local sys = require("luci.sys")
local util = require("luci.util")
local http = require("luci.http")
-local templ = require("luci.template")
local i18n = require("luci.i18n")
local json = require("luci.jsonc")
local uci = require("luci.model.uci").cursor()
-local fs = require("nixio.fs")
function index()
if not nixio.fs.access("/etc/config/adblock") then
rt_file = uci:get("adblock", "global", "adb_rtfile") or "/tmp/adb_runtime.json"
- if fs.access(rt_file) then
- content = json.parse(fs.readfile(rt_file))
- if content then
- http.prepare_content("application/json")
- http.write_json(content)
- end
+ if nixio.fs.access(rt_file) then
+ content = json.parse(nixio.fs.readfile(rt_file) or "")
+ http.prepare_content("application/json")
+ http.write_json(content)
end
end
local fs = require("nixio.fs")
local uci = require("luci.model.uci").cursor()
-local sys = require("luci.sys")
local util = require("luci.util")
local dump = util.ubus("network.interface", "dump", {})
.. "<a href=\"%s\" target=\"_blank\">"
.. "check the online documentation</a>", "https://github.com/openwrt/packages/blob/master/net/adblock/files/README.md"))
-function m.on_apply(self)
- luci.sys.call("/etc/init.d/adblock reload >/dev/null 2>&1")
-end
-
-- Main adblock options
s = m:section(NamedSection, "global", "adblock")
.cbi-section-table-row,
.tr[data-title]::before
{
- text-align:left;
- vertical-align:top;
- margin-left:0px;
- padding-left:2px;
+ text-align: left;
+ vertical-align: top;
+ margin-left: 0px;
+ padding-left: 2px;
}
.table.cbi-section-table .th
{
- white-space:nowrap;
+ white-space: nowrap;
}
.table.cbi-section-table input
{
- width:7em;
+ width: 7em;
}
.cbi-section-table-row > .cbi-value-field [data-dynlist] > input,
.table.cbi-section-table input
{
- width:7em;
+ width: 7em;
}
.cbi-input-text
{
- text-align:left;
- padding-left:2px;
- outline:none;
- box-shadow:none;
- background:transparent;
- width:7em;
+ text-align: left;
+ padding-left: 2px;
+ outline: none;
+ box-shadow: none;
+ background: transparent;
+ width: 7em;
}
</style>
<div class="cbi-section" id="cbi-<%=self.config%>-<%=self.sectiontype%>">
<% if self.title then -%>
- <legend><%=self.title%></legend>
+ <h3><%=self.title%></h3>
<%- end %>
<div class="cbi-section-descr"><%=self.description%></div>
<div class="cbi-section-node">
-%>
<%+header%>
+<style type="text/css">
+ select[readonly],
+ textarea[readonly]
+ {
+ width: 100%;
+ height: 450px;
+ border: 1px solid #cccccc;
+ padding: 5px;
+ font-size: 12px;
+ font-family: monospace;
+ resize: none;
+ pointer-events: auto;
+ cursor: auto;
+ }
+</style>
<script type="text/javascript">
//<![CDATA[
<div class="cbi-map">
<div class="cbi-section">
<div class="cbi-section-descr"><%:The syslog output, pre-filtered for adblock related messages only.%></div>
- <textarea id="view_id" style="width:100%;height:450px;border:1px solid #cccccc;padding:5px;font-size:12px;font-family:monospace;resize:none;" readonly="readonly" wrap="off" value=""></textarea>
+ <textarea id="view_id" readonly="readonly" wrap="off" value=""></textarea>
</div>
</div>
<%#
-Copyright 2017 Dirk Brenken (dev@brenken.org)
+Copyright 2017-2018 Dirk Brenken (dev@brenken.org)
This is free software, licensed under the Apache License, Version 2.0
-%>
function update_status(data)
{
var domain = data.value;
- var input = document.getElementById('query_input');
+ var input = document.getElementById('query_input');
var output = document.getElementById('query_output');
if (input && output)
<div class="cbi-section">
<div class="cbi-section-descr"><%:This form allows you to query active block lists for certain domains, e.g. for whitelisting.%></div>
<div style="width:33%; float:left;">
- <input style="margin: 5px 0" type="text" value="google.com" name="input" />
+ <input type="text" value="google.com" name="input" />
<input type="button" value="<%:Query%>" class="cbi-button cbi-button-apply" onclick="update_status(this.form.input)" />
</div>
<br style="clear:both" />
<%#
Copyright 2017-2018 Dirk Brenken (dev@brenken.org)
This is free software, licensed under the Apache License, Version 2.0
-local sys = require("luci.sys")
-
-%>
+
<style type="text/css">
.runtime
{
- color:#0069d6;
- font-weight:bold;
- display:inline-block;
- width:100%;
+ color: #37c;
+ font-weight: bold;
+ display: inline-block;
+ width: 100%;
padding-top: 0.5rem;
}
</style>
//<![CDATA[
function status_update(json)
{
- var view = document.getElementById("value_1");
- var btn1 = document.getElementById("btn1");
- var btn2 = document.getElementById("btn2");
- var input = json.data.adblock_status;
+ var view = document.getElementById("value_1");
+ var btn1 = document.getElementById("btn1");
+ var btn1_running = document.getElementById("btn1_running");
+ var btn2 = document.getElementById("btn2");
+ var btn2_running = document.getElementById("btn2_running");
+ var input = json.data.adblock_status;
view.innerHTML = input || "-";
if (input === "enabled")
btn2.value = "<%:Refresh%>";
btn2.name = "do_refresh";
btn1.disabled = true;
- btn2.disabled = false;
+ btn2.disabled = true;
return;
}
status_update(json_info)
PKG_RELEASE:=5
PKG_LICENSE:=Apache-2.0
-PKG_MAINTAINER:=Christian Schoenebeck <christian.schoenebeck@gmail.com>, \
- Ansuel Smith <ansuelsmth@gmail.com>
+PKG_MAINTAINER:=Ansuel Smith <ansuelsmth@gmail.com>
# LuCI specific settings
LUCI_TITLE:=LuCI Support for Dynamic DNS Client (ddns-scripts)
function env_info(type)
- if ( type == "has_ssl" ) or ( type == "has_proxy" ) or ( type == "has_forceip" )
- or ( type == "has_bindnet" ) or ( type == "has_fetch" )
- or ( type == "has_wgetssl" ) or ( type == "has_curl" )
- or ( type == "has_curlssl" ) or ( type == "has_curlpxy" )
- or ( type == "has_fetchssl" ) or ( type == "has_bbwget" ) then
-
- local function has_wgetssl()
+ if ( type == "has_ssl" ) or ( type == "has_proxy" ) or ( type == "has_forceip" )
+ or ( type == "has_bindnet" ) or ( type == "has_fetch" )
+ or ( type == "has_wgetssl" ) or ( type == "has_curl" )
+ or ( type == "has_curlssl" ) or ( type == "has_curlpxy" )
+ or ( type == "has_fetchssl" ) or ( type == "has_bbwget" ) then
+
+ local function has_wgetssl()
return (SYS.call( [[which wget-ssl >/dev/null 2>&1]] ) == 0) -- and true or nil
end
-
- local function has_curlssl()
+
+ local function has_curlssl()
return (SYS.call( [[$(which curl) -V 2>&1 | grep "Protocols:" | grep -qF "https"]] ) ~= 0)
end
-
+
local function has_fetch()
return (SYS.call( [[which uclient-fetch >/dev/null 2>&1]] ) == 0)
end
-
+
local function has_fetchssl()
return NXFS.access("/lib/libustream-ssl.so")
end
-
+
local function has_curl()
return (SYS.call( [[which curl >/dev/null 2>&1]] ) == 0)
end
-
+
local function has_curlpxy()
return (SYS.call( [[grep -i "all_proxy" /usr/lib/libcurl.so* >/dev/null 2>&1]] ) == 0)
end
-
+
local function has_bbwget()
return (SYS.call( [[$(which wget) -V 2>&1 | grep -iqF "busybox"]] ) == 0)
end
-
+
if type == "has_wgetssl" then
return has_wgetssl()
-
+
elseif type == "has_curl" then
return has_curl()
-
+
elseif type == "has_curlssl" then
return has_curlssl()
-
+
elseif type == "has_curlpxy" then
return has_curlpxy()
-
+
elseif type == "has_fetch" then
return has_fetch()
-
+
elseif type == "has_fetchssl" then
return has_fetchssl()
-
+
elseif type == "has_bbwget" then
return has_bbwget()
-
+
elseif type == "has_ssl" then
if has_wgetssl() then return true end
if has_curlssl() then return true end
if (has_fetch() and has_fetchssl()) then return true end
return false
-
+
elseif type == "has_proxy" then
if has_wgetssl() then return true end
if has_curlpxy() then return true end
if has_fetch() then return true end
if has_bbwget() then return true end
return false
-
+
elseif type == "has_forceip" then
if has_wgetssl() then return true end
if has_curl() then return true end
if has_fetch() then return true end -- only really needed for transfer
return false
-
+
elseif type == "has_bindnet" then
if has_curl() then return true end
if has_wgetssl() then return true end
return false
end
-
+
elseif ( type == "has_dnsserver" ) or ( type == "has_bindhost" ) or ( type == "has_hostip" ) or ( type == "has_nslookup" ) then
- local function has_bindhost()
- if (SYS.call( [[which host >/dev/null 2>&1]] ) == 0) then return true end
+ local function has_bindhost()
if (SYS.call( [[which host >/dev/null 2>&1]] ) == 0) then return true end
if (SYS.call( [[which khost >/dev/null 2>&1]] ) == 0) then return true end
if (SYS.call( [[which drill >/dev/null 2>&1]] ) == 0) then return true end
return false
end
-
+
local function has_hostip()
return (SYS.call( [[which hostip >/dev/null 2>&1]] ) == 0)
end
-
+
local function has_nslookup()
return (SYS.call( [[$(which nslookup) localhost 2>&1 | grep -qF "(null)"]] ) ~= 0)
end
-
+
if type == "has_bindhost" then
return has_bindhost()
elseif type == "has_hostip" then
return has_hostip()
elseif type == "has_nslookup" then
return has_nslookup()
- elseif tyep == "has_dnsserver" then
+ elseif type == "has_dnsserver" then
if has_bindhost() then return true end
if has_hostip() then return true end
if has_nslookup() then return true end
return false
end
-
+
elseif type == "has_ipv6" then
return (NXFS.access("/proc/net/ipv6_route") and NXFS.access("/usr/sbin/ip6tables"))
-
+
elseif type == "has_cacerts" then
- --old _check_certs() local function
+ --old _check_certs() local function
local _, v = NXFS.glob("/etc/ssl/certs/*.crt")
if ( v == 0 ) then _, v = NXFS.glob("/etc/ssl/certs/*.pem") end
return (v > 0)
<%
local fw = require "luci.model.firewall".init()
- local wz = fw:get_zone("wan")
- local lz = fw:get_zone("lan")
local zones = fw:get_zones()
%>
-<% if wz then %>
+<% if #zones > 0 then %>
<h4><%:Open ports on router%></h4>
<div class="table">
<div class="tr cbi-section-table-titles">
<input type="submit" class="cbi-button cbi-button-add" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" value="<%:Add%>" />
<% end %>
-<% if wz then %>
+<% if #zones > 0 then %>
<script type="text/javascript">//<![CDATA[
cbi_validate_field('_newopen.extport', true, 'list(neg(portrange))');
cbi_bind(document.getElementById('_newopen.extport'), 'blur',
# Release == build
# increase on changes of translation files
-PKG_RELEASE:=1
+PKG_RELEASE:=2
PKG_LICENSE:=Apache-2.0
-PKG_MAINTAINER:=Christian Schoenebeck <christian.schoenebeck@gmail.com>
+PKG_MAINTAINER:=
# LuCI specific settings
LUCI_TITLE:=LuCI Support for Radicale CardDAV/CalDAV
--- /dev/null
+# This is free software, licensed under the Apache License, Version 2.0 .
+
+include $(TOPDIR)/rules.mk
+
+LUCI_TITLE:=Network Shares - Samba 4 SMB/CIFS module
+LUCI_DEPENDS:=+samba4-server
+
+include ../../luci.mk
+
+# call BuildPackage - OpenWrt buildroot signature
--- /dev/null
+-- Licensed to the public under the Apache License 2.0.
+
+module("luci.controller.samba4", package.seeall)
+
+function index()
+ if not nixio.fs.access("/etc/config/samba4") then
+ return
+ end
+
+ local page
+
+ page = entry({"admin", "services", "samba4"}, cbi("samba4"), _("Network Shares"))
+ page.dependent = true
+end
--- /dev/null
+-- Licensed to the public under the Apache License 2.0.
+
+m = Map("samba4", translate("Network Shares"))
+
+s = m:section(TypedSection, "samba", "Samba")
+s.anonymous = true
+
+s:tab("general", translate("General Settings"))
+s:tab("template", translate("Edit Template"))
+
+s:taboption("general", Value, "name", translate("Hostname"))
+s:taboption("general", Value, "description", translate("Description"))
+s:taboption("general", Value, "workgroup", translate("Workgroup"))
+h = s:taboption("general", Flag, "homes", translate("Share home-directories"),
+ translate("Allow system users to reach their home directories via " ..
+ "network shares"))
+h.rmempty = false
+s:taboption("general", Flag, "disable_netbios", translate("Disable Netbios"))
+s:taboption("general", Flag, "disable_ad_dc", translate("Disable Active Directory Domain Controller"))
+s:taboption("general", Flag, "disable_winbind", translate("Disable Winbind"))
+
+tmpl = s:taboption("template", Value, "_tmpl",
+ translate("Edit the template that is used for generating the samba configuration."),
+ translate("This is the content of the file '/etc/samba/smb.conf.template' from which your samba configuration will be generated. " ..
+ "Values enclosed by pipe symbols ('|') should not be changed. They get their values from the 'General Settings' tab."))
+
+tmpl.template = "cbi/tvalue"
+tmpl.rows = 20
+
+function tmpl.cfgvalue(self, section)
+ return nixio.fs.readfile("/etc/samba/smb.conf.template")
+end
+
+function tmpl.write(self, section, value)
+ value = value:gsub("\r\n?", "\n")
+ nixio.fs.writefile("/etc/samba/smb.conf.template", value)
+end
+
+
+s = m:section(TypedSection, "sambashare", translate("Shared Directories")
+ , translate("Please add directories to share. Each directory refers to a folder on a mounted device."))
+s.anonymous = true
+s.addremove = true
+s.template = "cbi/tblsection"
+
+s:option(Value, "name", translate("Name"))
+pth = s:option(Value, "path", translate("Path"))
+if nixio.fs.access("/etc/config/fstab") then
+ pth.titleref = luci.dispatcher.build_url("admin", "system", "fstab")
+end
+
+s:option(Value, "users", translate("Allowed users")).rmempty = true
+
+ro = s:option(Flag, "read_only", translate("Read-only"))
+ro.rmempty = false
+ro.enabled = "yes"
+ro.disabled = "no"
+
+br = s:option(Flag, "browseable", translate("Browseable"))
+br.rmempty = false
+br.default = "yes"
+br.enabled = "yes"
+br.disabled = "no"
+
+go = s:option(Flag, "guest_ok", translate("Allow guests"))
+go.rmempty = false
+go.enabled = "yes"
+go.disabled = "no"
+
+gon = s:option(Flag, "guest_only", translate("Guests only"))
+gon.rmempty = false
+gon.enabled = "yes"
+gon.disabled = "no"
+
+io = s:option(Flag, "inherit_owner", translate("Inherit owner"))
+io.rmempty = false
+io.enabled = "yes"
+io.disabled = "no"
+
+cm = s:option(Value, "create_mask", translate("Create mask"))
+cm.rmempty = true
+cm.size = 4
+
+dm = s:option(Value, "dir_mask", translate("Directory mask"))
+dm.rmempty = true
+dm.size = 4
+
+s:option(Value, "vfs_objects", translate("Vfs objects")).rmempty = true
+
+return m
--- /dev/null
+# samba.pot
+# generated from ./applications/luci-samba/luasrc/i18n/samba.en.lua
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-06-10 03:40+0200\n"
+"PO-Revision-Date: 2014-07-01 05:47+0200\n"
+"Last-Translator: Alex <alexhenrie24@gmail.com>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: ca\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Pootle 2.0.6\n"
+
+msgid "Allow guests"
+msgstr "Permet convidats"
+
+msgid "Allow system users to reach their home directories via network shares"
+msgstr ""
+"Permet que els usuaris del sistema pugin arribar als seus directoris d'inici "
+"via comparticions de xarxa"
+
+msgid "Allowed users"
+msgstr "Usuaris permesos"
+
+msgid "Browseable"
+msgstr ""
+
+msgid "Create mask"
+msgstr "Crea màscara"
+
+msgid "Description"
+msgstr "Descripció"
+
+msgid "Directory mask"
+msgstr "Màscara de directori"
+
+msgid "Disable Active Directory Domain Controller"
+msgstr ""
+
+msgid "Disable Netbios"
+msgstr ""
+
+msgid "Disable Winbind"
+msgstr ""
+
+msgid "Edit Template"
+msgstr "Edita plantilla"
+
+msgid "Edit the template that is used for generating the samba configuration."
+msgstr "Edita la plantilla que s'usa per generar la configuració de samba."
+
+msgid "General Settings"
+msgstr "Ajusts generals"
+
+msgid "Guests only"
+msgstr ""
+
+msgid "Hostname"
+msgstr "Nom de màquina"
+
+msgid "Inherit owner"
+msgstr ""
+
+msgid "Name"
+msgstr "Nom"
+
+msgid "Network Shares"
+msgstr "Comparticions de xarxa"
+
+msgid "Path"
+msgstr "Ruta"
+
+msgid ""
+"Please add directories to share. Each directory refers to a folder on a "
+"mounted device."
+msgstr ""
+
+msgid "Read-only"
+msgstr "Només lectura"
+
+msgid "Share home-directories"
+msgstr "Comparteix directoris d'inici"
+
+msgid "Shared Directories"
+msgstr "Directoris compartits"
+
+msgid ""
+"This is the content of the file '/etc/samba/smb.conf.template' from which "
+"your samba configuration will be generated. Values enclosed by pipe symbols "
+"('|') should not be changed. They get their values from the 'General "
+"Settings' tab."
+msgstr ""
+"Això és el contingut del fitxer '/etc/samba/smb.conf.template' del qual la "
+"vostra configuració de samba es generarà. Valors encerclats per símbols de "
+"barra ('|') no es deuen canviar. Reben els seus valors de la pestanya "
+"'Ajusts generals'."
+
+msgid "Vfs objects"
+msgstr ""
+
+msgid "Workgroup"
+msgstr "Grup de treball"
+
+#~ msgid "Mask for new directories"
+#~ msgstr "Màscara per directoris nous"
+
+#~ msgid "Mask for new files"
+#~ msgstr "Màscara per fitxers nous"
+
+#~ msgid "Shared Directory"
+#~ msgstr "Directori compartit"
+
+#~ msgid "Physical Path"
+#~ msgstr "Ruta física"
+
+#~ msgid "optional"
+#~ msgstr "opcional"
--- /dev/null
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"PO-Revision-Date: 2014-05-31 13:56+0200\n"
+"Last-Translator: koli <lukas.koluch@gmail.com>\n"
+"Language-Team: none\n"
+"Language: cs\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
+"X-Generator: Pootle 2.0.6\n"
+
+msgid "Allow guests"
+msgstr "Povolení hosté"
+
+msgid "Allow system users to reach their home directories via network shares"
+msgstr ""
+"Povoluje systémovým uživatelům přístup do jejich domácích adresářů skrze "
+"sdílení přes síť."
+
+msgid "Allowed users"
+msgstr "Povolení uživatelé"
+
+msgid "Browseable"
+msgstr ""
+
+msgid "Create mask"
+msgstr "Vytvořit masku"
+
+msgid "Description"
+msgstr "Popis"
+
+msgid "Directory mask"
+msgstr "Maska adresáře"
+
+msgid "Disable Active Directory Domain Controller"
+msgstr ""
+
+msgid "Disable Netbios"
+msgstr ""
+
+msgid "Disable Winbind"
+msgstr ""
+
+msgid "Edit Template"
+msgstr "Editovat šablonu"
+
+msgid "Edit the template that is used for generating the samba configuration."
+msgstr ""
+"Editovat šablonu, která je použita pro generování konfiguračního souboru pro "
+"sambu."
+
+msgid "General Settings"
+msgstr "Obecné nastavení"
+
+msgid "Guests only"
+msgstr ""
+
+msgid "Hostname"
+msgstr "Název počítače."
+
+msgid "Inherit owner"
+msgstr ""
+
+msgid "Name"
+msgstr "Jméno"
+
+msgid "Network Shares"
+msgstr "Síťová sdílení"
+
+msgid "Path"
+msgstr "Cesta"
+
+msgid ""
+"Please add directories to share. Each directory refers to a folder on a "
+"mounted device."
+msgstr ""
+
+msgid "Read-only"
+msgstr "Pouze pro čtení"
+
+msgid "Share home-directories"
+msgstr "Sdílet domácí adresáře"
+
+msgid "Shared Directories"
+msgstr "Sdílené adresáře"
+
+msgid ""
+"This is the content of the file '/etc/samba/smb.conf.template' from which "
+"your samba configuration will be generated. Values enclosed by pipe symbols "
+"('|') should not be changed. They get their values from the 'General "
+"Settings' tab."
+msgstr ""
+"Toto je obsah souboru \"/etc/samba/smb.conf.template\", ze kterého je "
+"konfigurace samby generována. Hodnoty uzavřené rourou (\"|\"), by se neměly "
+"měnit. Tyto hodnoty jsou brány ze záložky \"Obecná nastavení\"."
+
+msgid "Vfs objects"
+msgstr ""
+
+msgid "Workgroup"
+msgstr "Skupina"
+
+#~ msgid "Mask for new directories"
+#~ msgstr "Maska pro nové adresáře"
+
+#~ msgid "Mask for new files"
+#~ msgstr "Maska pro nové soubory"
--- /dev/null
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-05-26 17:57+0200\n"
+"PO-Revision-Date: 2011-10-18 13:13+0200\n"
+"Last-Translator: Manuel <freifunk@somakoma.de>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: de\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Pootle 2.0.4\n"
+
+msgid "Allow guests"
+msgstr "Gastzugang"
+
+msgid "Allow system users to reach their home directories via network shares"
+msgstr ""
+"Systembenutzer dürfen ihre Heimatverzeichnis über Netzwerkfreigaben "
+"erreichen."
+
+msgid "Allowed users"
+msgstr "Legitimierte Benutzer"
+
+msgid "Browseable"
+msgstr "Suchbar"
+
+msgid "Create mask"
+msgstr "Berechtigungsmaske für neue Dateien"
+
+msgid "Description"
+msgstr "Beschreibung"
+
+msgid "Directory mask"
+msgstr "Verzeichnismaske"
+
+msgid "Disable Active Directory Domain Controller"
+msgstr "Deaktiviere Active Directory Domain Controller"
+
+msgid "Disable Netbios"
+msgstr "Deaktiviere Netbios"
+
+msgid "Disable Winbind"
+msgstr "Deaktiviere Winbind"
+
+msgid "Edit Template"
+msgstr "Template bearbeiten"
+
+msgid "Edit the template that is used for generating the samba configuration."
+msgstr ""
+"Hier kann das Template bearbeitet werden, das zur Erstellung der Samba-"
+"Konfigurationsdateien verwendet wird."
+
+msgid "General Settings"
+msgstr "Allgemeine Einstellungen"
+
+msgid "Guests only"
+msgstr "Nur Gaeste"
+
+msgid "Hostname"
+msgstr "Hostname"
+
+msgid "Inherit owner"
+msgstr "Besitzer Erben"
+
+msgid "Name"
+msgstr "Name"
+
+msgid "Network Shares"
+msgstr "Netzwerkfreigaben"
+
+msgid "Path"
+msgstr "Pfad"
+
+msgid ""
+"Please add directories to share. Each directory refers to a folder on a "
+"mounted device."
+msgstr ""
+
+msgid "Read-only"
+msgstr "Nur Lesen"
+
+msgid "Share home-directories"
+msgstr "Heimatverzeichnisse freigeben"
+
+msgid "Shared Directories"
+msgstr "Freigegebene Verzeichnisse"
+
+msgid ""
+"This is the content of the file '/etc/samba/smb.conf.template' from which "
+"your samba configuration will be generated. Values enclosed by pipe symbols "
+"('|') should not be changed. They get their values from the 'General "
+"Settings' tab."
+msgstr ""
+"Dieses Fenster zeigt den Inhalt der Datei '/etc/samba/smb.conf.template', "
+"die als Template zum Erstellen der Samba-Konfiguration verwendet wird. Werte "
+"die von Pipe Symbolen (|) eingeschlossen sind sollten nicht verändert "
+"werden, da diese beim Erstellen der Konfiguration mit den Werten aus dem Tab "
+"'Allgemeine Einstellungen' ersetzt werden."
+
+msgid "Vfs objects"
+msgstr "Virtuelle Filesystem Module"
+
+msgid "Workgroup"
+msgstr "Arbeitsgruppe"
+
+#~ msgid "Mask for new directories"
+#~ msgstr "Maske für neue Verzeichnisse"
+
+#~ msgid "Mask for new files"
+#~ msgstr "Maske für neue Dateien"
--- /dev/null
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-05-28 02:08+0200\n"
+"PO-Revision-Date: 2012-03-18 15:31+0200\n"
+"Last-Translator: Vasilis <acinonyx@openwrt.gr>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: el\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Pootle 2.0.4\n"
+
+msgid "Allow guests"
+msgstr ""
+
+msgid "Allow system users to reach their home directories via network shares"
+msgstr ""
+
+msgid "Allowed users"
+msgstr ""
+
+msgid "Browseable"
+msgstr ""
+
+msgid "Create mask"
+msgstr ""
+
+msgid "Description"
+msgstr ""
+
+msgid "Directory mask"
+msgstr ""
+
+msgid "Disable Active Directory Domain Controller"
+msgstr ""
+
+msgid "Disable Netbios"
+msgstr ""
+
+msgid "Disable Winbind"
+msgstr ""
+
+msgid "Edit Template"
+msgstr ""
+
+msgid "Edit the template that is used for generating the samba configuration."
+msgstr ""
+
+msgid "General Settings"
+msgstr ""
+
+msgid "Guests only"
+msgstr ""
+
+msgid "Hostname"
+msgstr ""
+
+msgid "Inherit owner"
+msgstr ""
+
+msgid "Name"
+msgstr "Όνομα"
+
+msgid "Network Shares"
+msgstr ""
+
+msgid "Path"
+msgstr ""
+
+msgid ""
+"Please add directories to share. Each directory refers to a folder on a "
+"mounted device."
+msgstr ""
+
+msgid "Read-only"
+msgstr ""
+
+msgid "Share home-directories"
+msgstr ""
+
+msgid "Shared Directories"
+msgstr ""
+
+msgid ""
+"This is the content of the file '/etc/samba/smb.conf.template' from which "
+"your samba configuration will be generated. Values enclosed by pipe symbols "
+"('|') should not be changed. They get their values from the 'General "
+"Settings' tab."
+msgstr ""
+
+msgid "Vfs objects"
+msgstr ""
+
+msgid "Workgroup"
+msgstr ""
--- /dev/null
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2010-03-22 15:23+0100\n"
+"PO-Revision-Date: 2011-10-25 21:26+0200\n"
+"Last-Translator: awm1 <awm1klimes8vladimir@gmail.com>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: en\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Pootle 2.0.4\n"
+
+msgid "Allow guests"
+msgstr "Allow guests"
+
+msgid "Allow system users to reach their home directories via network shares"
+msgstr "Allow system users to reach their home directories via network shares"
+
+msgid "Allowed users"
+msgstr "Allowed users"
+
+msgid "Browseable"
+msgstr ""
+
+msgid "Create mask"
+msgstr "Create mask"
+
+msgid "Description"
+msgstr "Description"
+
+msgid "Directory mask"
+msgstr "Directory mask"
+
+msgid "Disable Active Directory Domain Controller"
+msgstr ""
+
+msgid "Disable Netbios"
+msgstr ""
+
+msgid "Disable Winbind"
+msgstr ""
+
+msgid "Edit Template"
+msgstr "Edit template"
+
+msgid "Edit the template that is used for generating the samba configuration."
+msgstr "Edit the template that is used for generating the Samba configuration."
+
+msgid "General Settings"
+msgstr "General settings"
+
+msgid "Guests only"
+msgstr ""
+
+msgid "Hostname"
+msgstr "Hostname"
+
+msgid "Inherit owner"
+msgstr ""
+
+msgid "Name"
+msgstr "Name"
+
+msgid "Network Shares"
+msgstr "Network Shares"
+
+msgid "Path"
+msgstr "Path"
+
+msgid ""
+"Please add directories to share. Each directory refers to a folder on a "
+"mounted device."
+msgstr ""
+
+msgid "Read-only"
+msgstr "Read-only"
+
+msgid "Share home-directories"
+msgstr "Share home-directories"
+
+msgid "Shared Directories"
+msgstr "Shared Directories"
+
+msgid ""
+"This is the content of the file '/etc/samba/smb.conf.template' from which "
+"your samba configuration will be generated. Values enclosed by pipe symbols "
+"('|') should not be changed. They get their values from the 'General "
+"Settings' tab."
+msgstr ""
+"This is the content of the file '/etc/samba/smb.conf.template' from which "
+"your Samba configuration will be generated. Values enclosed by pipe symbols "
+"('|') should not be changed. They get their values from the 'General "
+"settings' tab."
+
+msgid "Vfs objects"
+msgstr ""
+
+msgid "Workgroup"
+msgstr "Workgroup"
+
+#~ msgid "Mask for new directories"
+#~ msgstr "Mask for new directories"
+
+#~ msgid "Mask for new files"
+#~ msgstr "Mask for new files"
--- /dev/null
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-06-10 03:41+0200\n"
+"PO-Revision-Date: 2012-08-22 17:45+0200\n"
+"Last-Translator: José Vicente <josevteg@gmail.com>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: es\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Pootle 2.0.6\n"
+
+msgid "Allow guests"
+msgstr "Permitir invitados"
+
+msgid "Allow system users to reach their home directories via network shares"
+msgstr ""
+"Permitir a los usuarios acceder a sus directorios de inicio vía "
+"comparticiones de red"
+
+msgid "Allowed users"
+msgstr "Usuarios permitidos"
+
+msgid "Browseable"
+msgstr ""
+
+msgid "Create mask"
+msgstr "Crear máscara"
+
+msgid "Description"
+msgstr "Descripción"
+
+msgid "Directory mask"
+msgstr "Máscara de directorio"
+
+msgid "Disable Active Directory Domain Controller"
+msgstr ""
+
+msgid "Disable Netbios"
+msgstr ""
+
+msgid "Disable Winbind"
+msgstr ""
+
+msgid "Edit Template"
+msgstr "Editar plantilla"
+
+msgid "Edit the template that is used for generating the samba configuration."
+msgstr "Editar la plantilla usada para generar la configuración de samba."
+
+msgid "General Settings"
+msgstr "Configuración general"
+
+msgid "Guests only"
+msgstr ""
+
+msgid "Hostname"
+msgstr "Nombre de máquina"
+
+msgid "Inherit owner"
+msgstr ""
+
+msgid "Name"
+msgstr "Nombre"
+
+msgid "Network Shares"
+msgstr "Comparticiones de red"
+
+msgid "Path"
+msgstr "Dirección"
+
+msgid ""
+"Please add directories to share. Each directory refers to a folder on a "
+"mounted device."
+msgstr ""
+
+msgid "Read-only"
+msgstr "Solo lectura"
+
+msgid "Share home-directories"
+msgstr "Compartir directorios personales"
+
+msgid "Shared Directories"
+msgstr "Directorios compartidos"
+
+msgid ""
+"This is the content of the file '/etc/samba/smb.conf.template' from which "
+"your samba configuration will be generated. Values enclosed by pipe symbols "
+"('|') should not be changed. They get their values from the 'General "
+"Settings' tab."
+msgstr ""
+"Contenido del fichero '/etc/samba/smb.conf.template' desde el que se "
+"generará la configuración de samba. Los valores entre tuberías ('|') no "
+"deben cambiarse. Su valor se toma desde la pestaña 'Configuración General'."
+
+msgid "Vfs objects"
+msgstr ""
+
+msgid "Workgroup"
+msgstr "Grupo de trabajo"
+
+#~ msgid "Mask for new directories"
+#~ msgstr "Máscara para directorios nuevos"
+
+#~ msgid "Mask for new files"
+#~ msgstr "Máscara para archivos nuevos"
+
+#~ msgid "Shared Directory"
+#~ msgstr "Directorio compatido"
+
+#~ msgid "Physical Path"
+#~ msgstr "Ruta Física"
+
+#~ msgid "optional"
+#~ msgstr "opcional"
--- /dev/null
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-05-19 19:36+0200\n"
+"PO-Revision-Date: 2011-11-23 22:36+0200\n"
+"Last-Translator: fredb <fblistes+luci@free.fr>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: fr\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+"X-Generator: Pootle 2.0.4\n"
+
+msgid "Allow guests"
+msgstr "Invités autorisés"
+
+msgid "Allow system users to reach their home directories via network shares"
+msgstr ""
+"Autoriser les utilisateurs système à atteindre leurs dossiers personnels via "
+"les partages réseau"
+
+msgid "Allowed users"
+msgstr "Utilisateurs autorisés"
+
+msgid "Browseable"
+msgstr ""
+
+msgid "Create mask"
+msgstr "Maque de création"
+
+msgid "Description"
+msgstr "Description"
+
+msgid "Directory mask"
+msgstr "Masque des dossiers"
+
+msgid "Disable Active Directory Domain Controller"
+msgstr ""
+
+msgid "Disable Netbios"
+msgstr ""
+
+msgid "Disable Winbind"
+msgstr ""
+
+msgid "Edit Template"
+msgstr "Éditer le modèle"
+
+msgid "Edit the template that is used for generating the samba configuration."
+msgstr "Éditer le modèle utilisé pour générer la configuration Samba."
+
+msgid "General Settings"
+msgstr "Paramètres généraux"
+
+msgid "Guests only"
+msgstr ""
+
+msgid "Hostname"
+msgstr "Nom d'hôte"
+
+msgid "Inherit owner"
+msgstr ""
+
+msgid "Name"
+msgstr "Nom"
+
+msgid "Network Shares"
+msgstr "Partages réseau"
+
+msgid "Path"
+msgstr "Chemin"
+
+msgid ""
+"Please add directories to share. Each directory refers to a folder on a "
+"mounted device."
+msgstr ""
+
+msgid "Read-only"
+msgstr "Lecture seule"
+
+msgid "Share home-directories"
+msgstr "Partager les dossiers personnels"
+
+msgid "Shared Directories"
+msgstr "Dossiers partagés"
+
+msgid ""
+"This is the content of the file '/etc/samba/smb.conf.template' from which "
+"your samba configuration will be generated. Values enclosed by pipe symbols "
+"('|') should not be changed. They get their values from the 'General "
+"Settings' tab."
+msgstr ""
+"Voici le contenu du fichier '/etc/samba/smb.conf.template' d'où sera généré "
+"votre configuration Samba. Les valeurs entre les symboles barre-verticale "
+" (« | ») ne doivent pas être modifiées, elles proviennent de l'onglet "
+"« Paramètres généraux »."
+
+msgid "Vfs objects"
+msgstr ""
+
+msgid "Workgroup"
+msgstr "Groupe de travail"
+
+#~ msgid "Mask for new directories"
+#~ msgstr "Masque pour les nouveaux dossiers"
+
+#~ msgid "Mask for new files"
+#~ msgstr "Masque pour les nouveaux fichiers"
--- /dev/null
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Last-Translator: Automatically generated\n"
+"Language-Team: none\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgid "Allow guests"
+msgstr ""
+
+msgid "Allow system users to reach their home directories via network shares"
+msgstr ""
+
+msgid "Allowed users"
+msgstr ""
+
+msgid "Browseable"
+msgstr ""
+
+msgid "Create mask"
+msgstr ""
+
+msgid "Description"
+msgstr ""
+
+msgid "Directory mask"
+msgstr ""
+
+msgid "Disable Active Directory Domain Controller"
+msgstr ""
+
+msgid "Disable Netbios"
+msgstr ""
+
+msgid "Disable Winbind"
+msgstr ""
+
+msgid "Edit Template"
+msgstr ""
+
+msgid "Edit the template that is used for generating the samba configuration."
+msgstr ""
+
+msgid "General Settings"
+msgstr ""
+
+msgid "Guests only"
+msgstr ""
+
+msgid "Hostname"
+msgstr ""
+
+msgid "Inherit owner"
+msgstr ""
+
+msgid "Name"
+msgstr ""
+
+msgid "Network Shares"
+msgstr ""
+
+msgid "Path"
+msgstr ""
+
+msgid ""
+"Please add directories to share. Each directory refers to a folder on a "
+"mounted device."
+msgstr ""
+
+msgid "Read-only"
+msgstr ""
+
+msgid "Share home-directories"
+msgstr ""
+
+msgid "Shared Directories"
+msgstr ""
+
+msgid ""
+"This is the content of the file '/etc/samba/smb.conf.template' from which "
+"your samba configuration will be generated. Values enclosed by pipe symbols "
+"('|') should not be changed. They get their values from the 'General "
+"Settings' tab."
+msgstr ""
+
+msgid "Vfs objects"
+msgstr ""
+
+msgid "Workgroup"
+msgstr ""
--- /dev/null
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"PO-Revision-Date: 2012-04-06 10:56+0200\n"
+"Last-Translator: juhosg <juhosg@openwrt.org>\n"
+"Language-Team: none\n"
+"Language: hu\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Pootle 2.0.4\n"
+
+msgid "Allow guests"
+msgstr "Vendég hozzáférés"
+
+msgid "Allow system users to reach their home directories via network shares"
+msgstr ""
+"A rendszerfelhasználók hálózati megosztáson keresztül hozzáférhetnek a home "
+"könyvtárukhoz."
+
+msgid "Allowed users"
+msgstr "Engedélyezett felhasználók"
+
+msgid "Browseable"
+msgstr ""
+
+msgid "Create mask"
+msgstr "Létrehozási maszk"
+
+msgid "Description"
+msgstr "Leírás"
+
+msgid "Directory mask"
+msgstr "Könyvtár maszk"
+
+msgid "Disable Active Directory Domain Controller"
+msgstr ""
+
+msgid "Disable Netbios"
+msgstr ""
+
+msgid "Disable Winbind"
+msgstr ""
+
+msgid "Edit Template"
+msgstr "Sablon szerkesztése"
+
+msgid "Edit the template that is used for generating the samba configuration."
+msgstr ""
+"Itt szerkesztheti a sablont, ami a végleges samba konfiguráció "
+"elkészítéséhez kerül felhasználásra."
+
+msgid "General Settings"
+msgstr "Általános beállítások"
+
+msgid "Guests only"
+msgstr ""
+
+msgid "Hostname"
+msgstr "Gépnév"
+
+msgid "Inherit owner"
+msgstr ""
+
+msgid "Name"
+msgstr "Név"
+
+msgid "Network Shares"
+msgstr "Hálózati megosztások"
+
+msgid "Path"
+msgstr "Elérési út"
+
+msgid ""
+"Please add directories to share. Each directory refers to a folder on a "
+"mounted device."
+msgstr ""
+
+msgid "Read-only"
+msgstr "Csak olvasható"
+
+msgid "Share home-directories"
+msgstr "Home könyvtárak megosztása"
+
+msgid "Shared Directories"
+msgstr "Megosztott könyvtárak"
+
+msgid ""
+"This is the content of the file '/etc/samba/smb.conf.template' from which "
+"your samba configuration will be generated. Values enclosed by pipe symbols "
+"('|') should not be changed. They get their values from the 'General "
+"Settings' tab."
+msgstr ""
+"Itt látható a /etc/samba/smb.conf.template file tartalma, ami a samba "
+"konfiguráció előállításához kerül felhasználásra. A pipe szimbólumok ('|') "
+"közé zárt értékek módosítása nem szükséges, az értéküket az általános "
+"beállítások fülről kapják."
+
+msgid "Vfs objects"
+msgstr ""
+
+msgid "Workgroup"
+msgstr "Munkacsoport"
+
+#~ msgid "Mask for new directories"
+#~ msgstr "Új könyvtárak maszkja"
+
+#~ msgid "Mask for new files"
+#~ msgstr "Új fájlok maszkja"
--- /dev/null
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-05-19 19:36+0200\n"
+"PO-Revision-Date: 2017-09-06 01:28+0200\n"
+"Last-Translator: bubu83 <bubu83@gmail.com>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: it\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Pootle 2.0.4\n"
+
+msgid "Allow guests"
+msgstr "Permetti ospiti"
+
+msgid "Allow system users to reach their home directories via network shares"
+msgstr ""
+"Autorizza gli utenti del sistema a raggiungere la loro cartella home "
+"attraverso le condivisioni di rete"
+
+msgid "Allowed users"
+msgstr "Utenti ammessi"
+
+msgid "Browseable"
+msgstr "Sfogliabile"
+
+msgid "Create mask"
+msgstr "Crea maschera"
+
+msgid "Description"
+msgstr "Descrizione"
+
+msgid "Directory mask"
+msgstr "Maschera della cartella"
+
+msgid "Disable Active Directory Domain Controller"
+msgstr ""
+
+msgid "Disable Netbios"
+msgstr ""
+
+msgid "Disable Winbind"
+msgstr ""
+
+msgid "Edit Template"
+msgstr "Modifica Template"
+
+msgid "Edit the template that is used for generating the samba configuration."
+msgstr ""
+"Modifica il template utilizzato per generare la configurazione di samba."
+
+msgid "General Settings"
+msgstr "Opzioni Generali"
+
+msgid "Guests only"
+msgstr ""
+
+msgid "Hostname"
+msgstr "Hostname"
+
+msgid "Inherit owner"
+msgstr ""
+
+msgid "Name"
+msgstr "Nome"
+
+msgid "Network Shares"
+msgstr "Condivisioni di rete"
+
+msgid "Path"
+msgstr "Percorso"
+
+msgid ""
+"Please add directories to share. Each directory refers to a folder on a "
+"mounted device."
+msgstr ""
+"Per favore aggiungi le directory da condividere. Ogni directory si riferisce "
+"a una cartella su un dispositivo montato."
+
+msgid "Read-only"
+msgstr "Solo lettura"
+
+msgid "Share home-directories"
+msgstr "Condividi cartelle home"
+
+msgid "Shared Directories"
+msgstr "Cartelle Condivise"
+
+msgid ""
+"This is the content of the file '/etc/samba/smb.conf.template' from which "
+"your samba configuration will be generated. Values enclosed by pipe symbols "
+"('|') should not be changed. They get their values from the 'General "
+"Settings' tab."
+msgstr ""
+"Questo è il contenuto del file '/etc/samba/smb.conf.template' dal quale sarà "
+"generata la tua configurazione di samba. I valori racchiusi tra il simbolo "
+"('|') non dovrebbero essere toccati. Essi vengono generati dalla schermata "
+"'Opzioni Generali'."
+
+msgid "Vfs objects"
+msgstr ""
+
+msgid "Workgroup"
+msgstr "Gruppo di lavoro"
+
+#~ msgid "Mask for new directories"
+#~ msgstr "Maschera per le nuove cartelle"
+
+#~ msgid "Mask for new files"
+#~ msgstr "Maschera per i nuovi files"
--- /dev/null
+msgid ""
+msgstr ""
+"Project-Id-Version: \n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-05-19 19:36+0200\n"
+"PO-Revision-Date: 2018-08-06 05:17+0900\n"
+"Last-Translator: INAGAKI Hiroshi <musashino.open@gmail.com>\n"
+"Language: ja\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Generator: Poedit 2.1.1\n"
+"Language-Team: \n"
+
+msgid "Allow guests"
+msgstr "ゲストアクセスを許可"
+
+msgid "Allow system users to reach their home directories via network shares"
+msgstr "sambaを介してユーザーのホームディレクトリへのアクセスを許可します"
+
+msgid "Allowed users"
+msgstr "許可されたユーザー"
+
+msgid "Browseable"
+msgstr ""
+
+msgid "Create mask"
+msgstr "マスクの作成"
+
+msgid "Description"
+msgstr "説明"
+
+msgid "Directory mask"
+msgstr "ディレクトリのマスク"
+
+msgid "Disable Active Directory Domain Controller"
+msgstr "Active Directory ドメインコントローラを無効化"
+
+msgid "Disable Netbios"
+msgstr "Netbios を無効化"
+
+msgid "Disable Winbind"
+msgstr "Winbind を無効化"
+
+msgid "Edit Template"
+msgstr "テンプレートの編集"
+
+msgid "Edit the template that is used for generating the samba configuration."
+msgstr "samba設定を生成するテンプレートを編集します。"
+
+msgid "General Settings"
+msgstr "一般設定"
+
+msgid "Guests only"
+msgstr "ゲストのみ"
+
+msgid "Hostname"
+msgstr "ホスト名"
+
+msgid "Inherit owner"
+msgstr "オーナーの継承"
+
+msgid "Name"
+msgstr "名前"
+
+msgid "Network Shares"
+msgstr "ネットワーク共有"
+
+msgid "Path"
+msgstr "パス"
+
+msgid ""
+"Please add directories to share. Each directory refers to a folder on a "
+"mounted device."
+msgstr ""
+"共有するディレクトリを追加してください。マウントされたデバイス等のディレクト"
+"リを設定し、公開することができます。"
+
+msgid "Read-only"
+msgstr "読み込みのみ"
+
+msgid "Share home-directories"
+msgstr "ホームディレクトリの共有"
+
+msgid "Shared Directories"
+msgstr "共有ディレクトリ"
+
+msgid ""
+"This is the content of the file '/etc/samba/smb.conf.template' from which "
+"your samba configuration will be generated. Values enclosed by pipe symbols "
+"('|') should not be changed. They get their values from the 'General "
+"Settings' tab."
+msgstr ""
+"これは、samba設定を生成するための'/etc/samba/smb.conf.template' ファイルの内"
+"容です。パイプ('|')で閉じられた値は変更しないでください。これらの値は'一般設"
+"定'タブ内の値によって置き換えられます。"
+
+msgid "Vfs objects"
+msgstr ""
+
+msgid "Workgroup"
+msgstr "ワークグループ"
+
+#~ msgid "Mask for new directories"
+#~ msgstr "新規ディレクトリのマスク"
+
+#~ msgid "Mask for new files"
+#~ msgstr "新規ファイルのマスク"
--- /dev/null
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Last-Translator: Automatically generated\n"
+"Language-Team: none\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+msgid "Allow guests"
+msgstr ""
+
+msgid "Allow system users to reach their home directories via network shares"
+msgstr ""
+
+msgid "Allowed users"
+msgstr ""
+
+msgid "Browseable"
+msgstr ""
+
+msgid "Create mask"
+msgstr ""
+
+msgid "Description"
+msgstr ""
+
+msgid "Directory mask"
+msgstr ""
+
+msgid "Disable Active Directory Domain Controller"
+msgstr ""
+
+msgid "Disable Netbios"
+msgstr ""
+
+msgid "Disable Winbind"
+msgstr ""
+
+msgid "Edit Template"
+msgstr ""
+
+msgid "Edit the template that is used for generating the samba configuration."
+msgstr ""
+
+msgid "General Settings"
+msgstr ""
+
+msgid "Guests only"
+msgstr ""
+
+msgid "Hostname"
+msgstr ""
+
+msgid "Inherit owner"
+msgstr ""
+
+msgid "Name"
+msgstr ""
+
+msgid "Network Shares"
+msgstr ""
+
+msgid "Path"
+msgstr ""
+
+msgid ""
+"Please add directories to share. Each directory refers to a folder on a "
+"mounted device."
+msgstr ""
+
+msgid "Read-only"
+msgstr ""
+
+msgid "Share home-directories"
+msgstr ""
+
+msgid "Shared Directories"
+msgstr ""
+
+msgid ""
+"This is the content of the file '/etc/samba/smb.conf.template' from which "
+"your samba configuration will be generated. Values enclosed by pipe symbols "
+"('|') should not be changed. They get their values from the 'General "
+"Settings' tab."
+msgstr ""
+
+msgid "Vfs objects"
+msgstr ""
+
+msgid "Workgroup"
+msgstr ""
--- /dev/null
+msgid ""
+msgstr ""
+"Last-Translator: Lars Hardy <lars.hardy@gmail.com>\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+msgid "Allow guests"
+msgstr "Tillat gjester"
+
+msgid "Allow system users to reach their home directories via network shares"
+msgstr "Tillat systembrukere å nå sine hjemmekataloger via nettverks mapper."
+
+msgid "Allowed users"
+msgstr "Tillatte brukere"
+
+msgid "Browseable"
+msgstr ""
+
+msgid "Create mask"
+msgstr "Opprett Maske"
+
+msgid "Description"
+msgstr "Beskrivelse"
+
+msgid "Directory mask"
+msgstr "Katalog maske"
+
+msgid "Disable Active Directory Domain Controller"
+msgstr ""
+
+msgid "Disable Netbios"
+msgstr ""
+
+msgid "Disable Winbind"
+msgstr ""
+
+msgid "Edit Template"
+msgstr "Rediger Mal"
+
+msgid "Edit the template that is used for generating the samba configuration."
+msgstr "Rediger malen som brukes til å generere samba konfigurasjonen."
+
+msgid "General Settings"
+msgstr "Generelle Innstillinger"
+
+msgid "Guests only"
+msgstr ""
+
+msgid "Hostname"
+msgstr "Vertsnavn"
+
+msgid "Inherit owner"
+msgstr ""
+
+msgid "Name"
+msgstr "Navn"
+
+msgid "Network Shares"
+msgstr "Nettverks Mapper"
+
+msgid "Path"
+msgstr "Fysisk bane"
+
+msgid ""
+"Please add directories to share. Each directory refers to a folder on a "
+"mounted device."
+msgstr ""
+
+msgid "Read-only"
+msgstr "Skrivebeskyttet"
+
+msgid "Share home-directories"
+msgstr "Del Hjemmekataloger"
+
+msgid "Shared Directories"
+msgstr "Delte Kataloger"
+
+msgid ""
+"This is the content of the file '/etc/samba/smb.conf.template' from which "
+"your samba configuration will be generated. Values enclosed by pipe symbols "
+"('|') should not be changed. They get their values from the 'General "
+"Settings' tab."
+msgstr ""
+"Dette er innholdet av filen '/etc/samba/smb.conf.template' som din samba "
+"konfigurasjon vil bli generert fra. Verdier omsluttet av ('|') bør ikke "
+"endres. De får sine verdier fra 'Generelle Innstillinger' fanen."
+
+msgid "Vfs objects"
+msgstr ""
+
+msgid "Workgroup"
+msgstr "Arbeidsgruppe"
+
+#~ msgid "Mask for new directories"
+#~ msgstr "Maske for nye kataloger"
+
+#~ msgid "Mask for new files"
+#~ msgstr "Maske for nye filer"
--- /dev/null
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"PO-Revision-Date: 2011-08-26 09:51+0200\n"
+"Last-Translator: Staszek <fistaszek@tlen.pl>\n"
+"Language-Team: none\n"
+"Language: pl\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
+"|| n%100>=20) ? 1 : 2);\n"
+"X-Generator: Pootle 2.0.4\n"
+
+msgid "Allow guests"
+msgstr "Zezwalaj Gościom"
+
+msgid "Allow system users to reach their home directories via network shares"
+msgstr ""
+"Użytkownicy systemu mogą dostać się do swoich katalogów domowych za "
+"pośrednictwem udziałów sieciowych."
+
+msgid "Allowed users"
+msgstr "Użytkownicy z prawem dostępu"
+
+msgid "Browseable"
+msgstr ""
+
+msgid "Create mask"
+msgstr "Utwórz maskę"
+
+msgid "Description"
+msgstr "Opis"
+
+msgid "Directory mask"
+msgstr "Maska katalogu"
+
+msgid "Disable Active Directory Domain Controller"
+msgstr ""
+
+msgid "Disable Netbios"
+msgstr ""
+
+msgid "Disable Winbind"
+msgstr ""
+
+msgid "Edit Template"
+msgstr "Edytuj szablon"
+
+msgid "Edit the template that is used for generating the samba configuration."
+msgstr "Edytuj szablon, który jest używany do generowania konfiguracji samby."
+
+msgid "General Settings"
+msgstr "Ustawienia ogólne"
+
+msgid "Guests only"
+msgstr ""
+
+msgid "Hostname"
+msgstr "Nazwa hosta"
+
+msgid "Inherit owner"
+msgstr ""
+
+msgid "Name"
+msgstr "Nazwa"
+
+msgid "Network Shares"
+msgstr "Udziały sieciowe"
+
+msgid "Path"
+msgstr "Ścieżka"
+
+msgid ""
+"Please add directories to share. Each directory refers to a folder on a "
+"mounted device."
+msgstr ""
+
+msgid "Read-only"
+msgstr "Tylko do odczytu"
+
+msgid "Share home-directories"
+msgstr "Udostępniaj katalogi domowe"
+
+msgid "Shared Directories"
+msgstr "Udostępniane katalogi"
+
+msgid ""
+"This is the content of the file '/etc/samba/smb.conf.template' from which "
+"your samba configuration will be generated. Values enclosed by pipe symbols "
+"('|') should not be changed. They get their values from the 'General "
+"Settings' tab."
+msgstr ""
+"To jest zawartość pliku '/etc/samba/smb.conf.template\", na podstawie "
+"którego zostanie wygenerowana konfiguracja samby. Wartości otoczone symbolem "
+"kreski pionowej ('|') nie powinny być zmieniane. Wartości ich zostaną "
+"pobrane z zakładki \"Ustawienia ogólne\"."
+
+msgid "Vfs objects"
+msgstr ""
+
+msgid "Workgroup"
+msgstr "Grupa robocza"
+
+#~ msgid "Mask for new directories"
+#~ msgstr "Maska dla nowych katalogów"
+
+#~ msgid "Mask for new files"
+#~ msgstr "Maska dla nowych plików"
--- /dev/null
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-06-10 03:41+0200\n"
+"PO-Revision-Date: 2013-04-06 22:54+0200\n"
+"Last-Translator: Luiz Angelo <luizluca@gmail.com>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: pt_BR\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+"X-Generator: Pootle 2.0.6\n"
+
+msgid "Allow guests"
+msgstr "Permitir convidados"
+
+msgid "Allow system users to reach their home directories via network shares"
+msgstr ""
+"Usuários do sistema poderão acessar seu diretório home através dos "
+"compartilhamentos de rede"
+
+msgid "Allowed users"
+msgstr "Usuários permitidos"
+
+msgid "Browseable"
+msgstr ""
+
+msgid "Create mask"
+msgstr "Máscara de criação"
+
+msgid "Description"
+msgstr "Descrição"
+
+msgid "Directory mask"
+msgstr "Máscara do diretório"
+
+msgid "Disable Active Directory Domain Controller"
+msgstr ""
+
+msgid "Disable Netbios"
+msgstr ""
+
+msgid "Disable Winbind"
+msgstr ""
+
+msgid "Edit Template"
+msgstr "Editar modelo"
+
+msgid "Edit the template that is used for generating the samba configuration."
+msgstr "Edita o modelo que é usado para gerar a configuração do samba."
+
+msgid "General Settings"
+msgstr "Configurações Gerais"
+
+msgid "Guests only"
+msgstr ""
+
+msgid "Hostname"
+msgstr "Nome do equipamento"
+
+msgid "Inherit owner"
+msgstr ""
+
+msgid "Name"
+msgstr "Nome"
+
+msgid "Network Shares"
+msgstr "Compartilhamentos de Rede"
+
+msgid "Path"
+msgstr "Caminho"
+
+msgid ""
+"Please add directories to share. Each directory refers to a folder on a "
+"mounted device."
+msgstr ""
+
+msgid "Read-only"
+msgstr "Somente leitura"
+
+msgid "Share home-directories"
+msgstr "Compartilhar diretórios home"
+
+msgid "Shared Directories"
+msgstr "Diretórios Compartilhados"
+
+msgid ""
+"This is the content of the file '/etc/samba/smb.conf.template' from which "
+"your samba configuration will be generated. Values enclosed by pipe symbols "
+"('|') should not be changed. They get their values from the 'General "
+"Settings' tab."
+msgstr ""
+"Este é o conteúdo do arquivo '/etc/samba/smb.conf.template' a partir do qual "
+"sua configuração do samba será gerada. Valores entre simbolos de pipe ('|') "
+"não devem ser alterados. Estes valores serão obtidos a partir da aba "
+"'Configurações Gerais'."
+
+msgid "Vfs objects"
+msgstr ""
+
+msgid "Workgroup"
+msgstr "Grupo de trabalho"
+
+#~ msgid "Mask for new directories"
+#~ msgstr "Máscara para novos diretórios"
+
+#~ msgid "Mask for new files"
+#~ msgstr "Máscara para novos arquivos"
+
+#~ msgid "Shared Directory"
+#~ msgstr "Diretório Compartilhado"
+
+#~ msgid "Physical Path"
+#~ msgstr "Caminho Físico"
+
+#~ msgid "optional"
+#~ msgstr "opcional"
--- /dev/null
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-05-26 19:03+0200\n"
+"PO-Revision-Date: 2013-05-01 01:13+0200\n"
+"Last-Translator: pedromrgoncalves <pedromrgoncalves@gmail.com>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: pt\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Pootle 2.0.6\n"
+
+msgid "Allow guests"
+msgstr "Permitir Convidados"
+
+msgid "Allow system users to reach their home directories via network shares"
+msgstr ""
+"Utilizadores do sistema poderão aceder ao seu directório home através das "
+"partilhas de rede."
+
+msgid "Allowed users"
+msgstr "Utilizadores Permitidos"
+
+msgid "Browseable"
+msgstr ""
+
+msgid "Create mask"
+msgstr "Criar Máscara"
+
+msgid "Description"
+msgstr "Descrição"
+
+msgid "Directory mask"
+msgstr "Máscara do Directório"
+
+msgid "Disable Active Directory Domain Controller"
+msgstr ""
+
+msgid "Disable Netbios"
+msgstr ""
+
+msgid "Disable Winbind"
+msgstr ""
+
+msgid "Edit Template"
+msgstr "Editar Template"
+
+msgid "Edit the template that is used for generating the samba configuration."
+msgstr "Editar a template que é utilizada para gerar a configuração samba"
+
+msgid "General Settings"
+msgstr "Definições Gerais"
+
+msgid "Guests only"
+msgstr ""
+
+msgid "Hostname"
+msgstr "Nome do host"
+
+msgid "Inherit owner"
+msgstr ""
+
+msgid "Name"
+msgstr "Nome"
+
+msgid "Network Shares"
+msgstr "Partilhas da Rede"
+
+msgid "Path"
+msgstr "Caminho"
+
+msgid ""
+"Please add directories to share. Each directory refers to a folder on a "
+"mounted device."
+msgstr ""
+
+msgid "Read-only"
+msgstr "Apenas Leitura"
+
+msgid "Share home-directories"
+msgstr "Partilha de directórios home"
+
+msgid "Shared Directories"
+msgstr "Directórios Partilhados"
+
+msgid ""
+"This is the content of the file '/etc/samba/smb.conf.template' from which "
+"your samba configuration will be generated. Values enclosed by pipe symbols "
+"('|') should not be changed. They get their values from the 'General "
+"Settings' tab."
+msgstr ""
+"Isto é o conteúdo do ficheiro 'etc/samba/smb.conf.template' a partir do qual "
+"será gerado o ficheiro de configuração do samba. Os valores entre o símbolo "
+"| não devem ser alterados. Eles recebem os valores do separador 'Definições "
+"Gerais'."
+
+msgid "Vfs objects"
+msgstr ""
+
+msgid "Workgroup"
+msgstr "Grupo de trabalho"
+
+#~ msgid "Mask for new directories"
+#~ msgstr "Máscara para novos directórios"
+
+#~ msgid "Mask for new files"
+#~ msgstr "Máscara para novos ficheiros"
+
+#~ msgid "Shared Directory"
+#~ msgstr "Diretório Compartilhado"
+
+#~ msgid "Physical Path"
+#~ msgstr "Caminho Físico"
+
+#~ msgid "optional"
+#~ msgstr "opcional"
--- /dev/null
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"PO-Revision-Date: 2011-10-07 17:16+0200\n"
+"Last-Translator: Daniel <daniel.petre@pitesti.rcs-rds.ro>\n"
+"Language-Team: none\n"
+"Language: ro\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < "
+"20)) ? 1 : 2);;\n"
+"X-Generator: Pootle 2.0.4\n"
+
+msgid "Allow guests"
+msgstr "Permite oaspeti"
+
+msgid "Allow system users to reach their home directories via network shares"
+msgstr ""
+"Permite utilizatorii de sistem sa acceseze directoarele lor peste "
+"partajarile de retea"
+
+msgid "Allowed users"
+msgstr "Utilizatori acceptati"
+
+msgid "Browseable"
+msgstr ""
+
+msgid "Create mask"
+msgstr "Creaza masca"
+
+msgid "Description"
+msgstr "Descriere"
+
+msgid "Directory mask"
+msgstr "Masca director"
+
+msgid "Disable Active Directory Domain Controller"
+msgstr ""
+
+msgid "Disable Netbios"
+msgstr ""
+
+msgid "Disable Winbind"
+msgstr ""
+
+msgid "Edit Template"
+msgstr "Editeaza sablon"
+
+msgid "Edit the template that is used for generating the samba configuration."
+msgstr "Editeaza sablonul care e folosit pentru generarea configuratiei samba."
+
+msgid "General Settings"
+msgstr "Setari generale"
+
+msgid "Guests only"
+msgstr ""
+
+msgid "Hostname"
+msgstr "Numele de host"
+
+msgid "Inherit owner"
+msgstr ""
+
+msgid "Name"
+msgstr "Nume"
+
+msgid "Network Shares"
+msgstr "Partajari pe retea"
+
+msgid "Path"
+msgstr "Cale"
+
+msgid ""
+"Please add directories to share. Each directory refers to a folder on a "
+"mounted device."
+msgstr ""
+
+msgid "Read-only"
+msgstr "Doar citire"
+
+msgid "Share home-directories"
+msgstr "Partajeaza directoarele proprii"
+
+msgid "Shared Directories"
+msgstr "Directoare partajate"
+
+msgid ""
+"This is the content of the file '/etc/samba/smb.conf.template' from which "
+"your samba configuration will be generated. Values enclosed by pipe symbols "
+"('|') should not be changed. They get their values from the 'General "
+"Settings' tab."
+msgstr ""
+"Acesta este continutul fisierului '/etc/samba/smb.conf.template' din care se "
+"genereaza configuratia samba. Valorile dintre liniuta verticala ('|') n-ar "
+"trebui schimbate, ele iau valorile direct din tab-ul de \"Setari generale\"."
+
+msgid "Vfs objects"
+msgstr ""
+
+msgid "Workgroup"
+msgstr "Workgroup"
+
+#~ msgid "Mask for new directories"
+#~ msgstr "Masca pentru directoarele noi"
+
+#~ msgid "Mask for new files"
+#~ msgstr "Masca pentru fisierele noi"
--- /dev/null
+msgid ""
+msgstr ""
+"Content-Type: text/plain; charset=UTF-8\n"
+"Project-Id-Version: LuCI: samba\n"
+"POT-Creation-Date: 2009-05-19 19:36+0200\n"
+"PO-Revision-Date: 2018-01-14 11:43+0300\n"
+"Language-Team: http://cyber-place.ru\n"
+"MIME-Version: 1.0\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 1.8.7.1\n"
+"Last-Translator: Vladimir aka sunny <picfun@ya.ru>\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
+"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+"Language: ru\n"
+"Project-Info: Это технический перевод, не дословный. Главное-удобный русский "
+"интерфейс, все проверялось в графическом режиме, совместим с другими apps\n"
+
+msgid "Allow guests"
+msgstr "Разрешить гостевой вход"
+
+msgid "Allow system users to reach their home directories via network shares"
+msgstr ""
+"Разрешить пользователям получать доступ к их домашним папкам, через "
+"локальную сеть."
+
+msgid "Allowed users"
+msgstr "Разрешенные пользователи"
+
+msgid "Browseable"
+msgstr "Виден в списке доступных ресурсов"
+
+msgid "Create mask"
+msgstr "Создать маску"
+
+msgid "Description"
+msgstr "Описание"
+
+msgid "Directory mask"
+msgstr "Маска папок"
+
+msgid "Disable Active Directory Domain Controller"
+msgstr ""
+
+msgid "Disable Netbios"
+msgstr ""
+
+msgid "Disable Winbind"
+msgstr ""
+
+msgid "Edit Template"
+msgstr "Настройка config файла"
+
+msgid "Edit the template that is used for generating the samba configuration."
+msgstr "Настройка config<br />файла samba."
+
+msgid "General Settings"
+msgstr "Основные настройки"
+
+msgid "Guests only"
+msgstr ""
+
+msgid "Hostname"
+msgstr "Имя хоста"
+
+msgid "Inherit owner"
+msgstr ""
+
+msgid "Name"
+msgstr "Имя"
+
+msgid "Network Shares"
+msgstr "Сетевые ресурсы"
+
+msgid "Path"
+msgstr "Путь"
+
+msgid ""
+"Please add directories to share. Each directory refers to a folder on a "
+"mounted device."
+msgstr ""
+"Добавьте папки для совместного доступа. Каждая папка - соответствует разделу "
+"на подключенном устройстве."
+
+msgid "Read-only"
+msgstr "Только для чтения"
+
+msgid "Share home-directories"
+msgstr "Совместно использовать домашние папки"
+
+msgid "Shared Directories"
+msgstr "Совместно используемые папки"
+
+msgid ""
+"This is the content of the file '/etc/samba/smb.conf.template' from which "
+"your samba configuration will be generated. Values enclosed by pipe symbols "
+"('|') should not be changed. They get their values from the 'General "
+"Settings' tab."
+msgstr ""
+"Это содержимое файла '/etc/samba/smb.conf.template', из которого "
+"генерируется config файл - samba.<br />Значения, заключенные в символы "
+"('|'), не должны быть изменены.<br />Они будут автоматически заменены на "
+"значения со страницы 'Основные настройки'."
+
+msgid "Vfs objects"
+msgstr ""
+
+msgid "Workgroup"
+msgstr "Рабочая группа"
+
+#~ msgid "Mask for new directories"
+#~ msgstr "Маска для новых папок"
+
+#~ msgid "Mask for new files"
+#~ msgstr "Маска для новых файлов"
--- /dev/null
+msgid ""
+msgstr ""
+"Content-Type: text/plain; charset=UTF-8\n"
+"Project-Id-Version: PACKAGE VERSION\n"
+"Last-Translator: Automatically generated\n"
+"Language-Team: none\n"
+"MIME-Version: 1.0\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
+
+msgid "Allow guests"
+msgstr ""
+
+msgid "Allow system users to reach their home directories via network shares"
+msgstr ""
+
+msgid "Allowed users"
+msgstr ""
+
+msgid "Browseable"
+msgstr ""
+
+msgid "Create mask"
+msgstr ""
+
+msgid "Description"
+msgstr ""
+
+msgid "Directory mask"
+msgstr ""
+
+msgid "Disable Active Directory Domain Controller"
+msgstr ""
+
+msgid "Disable Netbios"
+msgstr ""
+
+msgid "Disable Winbind"
+msgstr ""
+
+msgid "Edit Template"
+msgstr ""
+
+msgid "Edit the template that is used for generating the samba configuration."
+msgstr ""
+
+msgid "General Settings"
+msgstr ""
+
+msgid "Guests only"
+msgstr ""
+
+msgid "Hostname"
+msgstr ""
+
+msgid "Inherit owner"
+msgstr ""
+
+msgid "Name"
+msgstr ""
+
+msgid "Network Shares"
+msgstr ""
+
+msgid "Path"
+msgstr ""
+
+msgid ""
+"Please add directories to share. Each directory refers to a folder on a "
+"mounted device."
+msgstr ""
+
+msgid "Read-only"
+msgstr ""
+
+msgid "Share home-directories"
+msgstr ""
+
+msgid "Shared Directories"
+msgstr ""
+
+msgid ""
+"This is the content of the file '/etc/samba/smb.conf.template' from which "
+"your samba configuration will be generated. Values enclosed by pipe symbols "
+"('|') should not be changed. They get their values from the 'General "
+"Settings' tab."
+msgstr ""
+
+msgid "Vfs objects"
+msgstr ""
+
+msgid "Workgroup"
+msgstr ""
--- /dev/null
+msgid ""
+msgstr ""
+"Content-Type: text/plain; charset=UTF-8\n"
+"Project-Id-Version: PACKAGE VERSION\n"
+"Last-Translator: Automatically generated\n"
+"Language-Team: none\n"
+"Language: sv\n"
+"MIME-Version: 1.0\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgid "Allow guests"
+msgstr "Tillåt gäster"
+
+msgid "Allow system users to reach their home directories via network shares"
+msgstr "Tillåt systemanvändare att nå deras hem-mappar via nätverksdelningar"
+
+msgid "Allowed users"
+msgstr "Tillåtna användare"
+
+msgid "Browseable"
+msgstr ""
+
+msgid "Create mask"
+msgstr "Skapa mask"
+
+msgid "Description"
+msgstr "Beskrivning"
+
+msgid "Directory mask"
+msgstr "Mask för mapp"
+
+msgid "Disable Active Directory Domain Controller"
+msgstr ""
+
+msgid "Disable Netbios"
+msgstr ""
+
+msgid "Disable Winbind"
+msgstr ""
+
+msgid "Edit Template"
+msgstr "Redigera mall"
+
+msgid "Edit the template that is used for generating the samba configuration."
+msgstr ""
+"Redigera mallen som används för att generera konfigurationen för samba."
+
+msgid "General Settings"
+msgstr "Generella inställningar"
+
+msgid "Guests only"
+msgstr ""
+
+msgid "Hostname"
+msgstr "Värdnamn"
+
+msgid "Inherit owner"
+msgstr ""
+
+msgid "Name"
+msgstr "Namn"
+
+msgid "Network Shares"
+msgstr "Nätverksdelningar"
+
+msgid "Path"
+msgstr "Genväg"
+
+msgid ""
+"Please add directories to share. Each directory refers to a folder on a "
+"mounted device."
+msgstr ""
+
+msgid "Read-only"
+msgstr "Endast läsbar"
+
+msgid "Share home-directories"
+msgstr "Dela hem-mappar"
+
+msgid "Shared Directories"
+msgstr "Delade mappar"
+
+msgid ""
+"This is the content of the file '/etc/samba/smb.conf.template' from which "
+"your samba configuration will be generated. Values enclosed by pipe symbols "
+"('|') should not be changed. They get their values from the 'General "
+"Settings' tab."
+msgstr ""
+
+msgid "Vfs objects"
+msgstr ""
+
+msgid "Workgroup"
+msgstr "Arbetsgrupp"
+
+#~ msgid "Mask for new directories"
+#~ msgstr "Mask för nya mappar"
+
+#~ msgid "Mask for new files"
+#~ msgstr "Mask för nya filer"
--- /dev/null
+msgid ""
+msgstr "Content-Type: text/plain; charset=UTF-8"
+
+msgid "Allow guests"
+msgstr ""
+
+msgid "Allow system users to reach their home directories via network shares"
+msgstr ""
+
+msgid "Allowed users"
+msgstr ""
+
+msgid "Browseable"
+msgstr ""
+
+msgid "Create mask"
+msgstr ""
+
+msgid "Description"
+msgstr ""
+
+msgid "Directory mask"
+msgstr ""
+
+msgid "Disable Active Directory Domain Controller"
+msgstr ""
+
+msgid "Disable Netbios"
+msgstr ""
+
+msgid "Disable Winbind"
+msgstr ""
+
+msgid "Edit Template"
+msgstr ""
+
+msgid "Edit the template that is used for generating the samba configuration."
+msgstr ""
+
+msgid "General Settings"
+msgstr ""
+
+msgid "Guests only"
+msgstr ""
+
+msgid "Hostname"
+msgstr ""
+
+msgid "Inherit owner"
+msgstr ""
+
+msgid "Name"
+msgstr ""
+
+msgid "Network Shares"
+msgstr ""
+
+msgid "Path"
+msgstr ""
+
+msgid ""
+"Please add directories to share. Each directory refers to a folder on a "
+"mounted device."
+msgstr ""
+
+msgid "Read-only"
+msgstr ""
+
+msgid "Share home-directories"
+msgstr ""
+
+msgid "Shared Directories"
+msgstr ""
+
+msgid ""
+"This is the content of the file '/etc/samba/smb.conf.template' from which "
+"your samba configuration will be generated. Values enclosed by pipe symbols "
+"('|') should not be changed. They get their values from the 'General "
+"Settings' tab."
+msgstr ""
+
+msgid "Vfs objects"
+msgstr ""
+
+msgid "Workgroup"
+msgstr ""
--- /dev/null
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Last-Translator: Automatically generated\n"
+"Language-Team: none\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+msgid "Allow guests"
+msgstr ""
+
+msgid "Allow system users to reach their home directories via network shares"
+msgstr ""
+
+msgid "Allowed users"
+msgstr ""
+
+msgid "Browseable"
+msgstr ""
+
+msgid "Create mask"
+msgstr ""
+
+msgid "Description"
+msgstr ""
+
+msgid "Directory mask"
+msgstr ""
+
+msgid "Disable Active Directory Domain Controller"
+msgstr ""
+
+msgid "Disable Netbios"
+msgstr ""
+
+msgid "Disable Winbind"
+msgstr ""
+
+msgid "Edit Template"
+msgstr ""
+
+msgid "Edit the template that is used for generating the samba configuration."
+msgstr ""
+
+msgid "General Settings"
+msgstr ""
+
+msgid "Guests only"
+msgstr ""
+
+msgid "Hostname"
+msgstr ""
+
+msgid "Inherit owner"
+msgstr ""
+
+msgid "Name"
+msgstr ""
+
+msgid "Network Shares"
+msgstr ""
+
+msgid "Path"
+msgstr ""
+
+msgid ""
+"Please add directories to share. Each directory refers to a folder on a "
+"mounted device."
+msgstr ""
+
+msgid "Read-only"
+msgstr ""
+
+msgid "Share home-directories"
+msgstr ""
+
+msgid "Shared Directories"
+msgstr ""
+
+msgid ""
+"This is the content of the file '/etc/samba/smb.conf.template' from which "
+"your samba configuration will be generated. Values enclosed by pipe symbols "
+"('|') should not be changed. They get their values from the 'General "
+"Settings' tab."
+msgstr ""
+
+msgid "Vfs objects"
+msgstr ""
+
+msgid "Workgroup"
+msgstr ""
--- /dev/null
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"PO-Revision-Date: 2012-03-18 20:35+0200\n"
+"Last-Translator: YuriPet <yuripet@gmail.com>\n"
+"Language-Team: none\n"
+"Language: uk\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%"
+"10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+"X-Generator: Pootle 2.0.4\n"
+
+msgid "Allow guests"
+msgstr "Дозволити гостьовий вхід"
+
+msgid "Allow system users to reach their home directories via network shares"
+msgstr ""
+"Дозволити користувачам системи досягати своїх домашніх каталогів через "
+"загальні мережеві ресурси"
+
+msgid "Allowed users"
+msgstr "Дозволені користувачі"
+
+msgid "Browseable"
+msgstr ""
+
+msgid "Create mask"
+msgstr "Створити маску"
+
+msgid "Description"
+msgstr "Опис"
+
+msgid "Directory mask"
+msgstr "Маска каталогу"
+
+msgid "Disable Active Directory Domain Controller"
+msgstr ""
+
+msgid "Disable Netbios"
+msgstr ""
+
+msgid "Disable Winbind"
+msgstr ""
+
+msgid "Edit Template"
+msgstr "Редагувати шаблон"
+
+msgid "Edit the template that is used for generating the samba configuration."
+msgstr ""
+"Редагувати шаблон, який використовується для створення конфігурації samba."
+
+msgid "General Settings"
+msgstr "Загальні настройки"
+
+msgid "Guests only"
+msgstr ""
+
+msgid "Hostname"
+msgstr "Назва (ім'я) вузла"
+
+msgid "Inherit owner"
+msgstr ""
+
+msgid "Name"
+msgstr "Ім'я"
+
+msgid "Network Shares"
+msgstr "Загальні мережеві ресурси"
+
+msgid "Path"
+msgstr "Шлях"
+
+msgid ""
+"Please add directories to share. Each directory refers to a folder on a "
+"mounted device."
+msgstr ""
+
+msgid "Read-only"
+msgstr "Тільки читання"
+
+msgid "Share home-directories"
+msgstr "Спільно використовувати домашні каталоги"
+
+msgid "Shared Directories"
+msgstr "Загальні каталоги"
+
+msgid ""
+"This is the content of the file '/etc/samba/smb.conf.template' from which "
+"your samba configuration will be generated. Values enclosed by pipe symbols "
+"('|') should not be changed. They get their values from the 'General "
+"Settings' tab."
+msgstr ""
+"Це вміст файлу '/etc/samba/smb.conf.template', з якого буде генеруватися "
+"ваша конфігурація samba. Значення, укладені в символи \"вертикальна риска"
+"\" (\"|\") не повинні змінюватися. Вони отримують свої значення з вкладки "
+"\"Загальні налаштування\"."
+
+msgid "Vfs objects"
+msgstr ""
+
+msgid "Workgroup"
+msgstr "Робоча група"
+
+#~ msgid "Mask for new directories"
+#~ msgstr "Маска для нових каталогів"
+
+#~ msgid "Mask for new files"
+#~ msgstr "Маска для нових файлів"
--- /dev/null
+# samba.pot
+# generated from ./applications/luci-samba/luasrc/i18n/samba.en.lua
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-08-16 06:59+0200\n"
+"PO-Revision-Date: 2009-08-13 03:54+0200\n"
+"Last-Translator: Hong Phuc Dang <dhppat@gmail.com>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Pootle 1.1.0\n"
+
+#, fuzzy
+msgid "Allow guests"
+msgstr "Cho phép khách"
+
+#, fuzzy
+msgid "Allow system users to reach their home directories via network shares"
+msgstr ""
+"Những người sử dụng hệ thống có thể tiếp cận những thư mục tại nhà thông qua "
+"mạng lưới chia sẻ trực tuyến."
+
+#, fuzzy
+msgid "Allowed users"
+msgstr "Người sử dụng được cho phép"
+
+msgid "Browseable"
+msgstr ""
+
+#, fuzzy
+msgid "Create mask"
+msgstr "Tạo Mask"
+
+msgid "Description"
+msgstr "Mô tả"
+
+#, fuzzy
+msgid "Directory mask"
+msgstr "Thư mục Mask"
+
+msgid "Disable Active Directory Domain Controller"
+msgstr ""
+
+msgid "Disable Netbios"
+msgstr ""
+
+msgid "Disable Winbind"
+msgstr ""
+
+msgid "Edit Template"
+msgstr ""
+
+msgid "Edit the template that is used for generating the samba configuration."
+msgstr ""
+
+msgid "General Settings"
+msgstr ""
+
+msgid "Guests only"
+msgstr ""
+
+msgid "Hostname"
+msgstr "tên máy chủ"
+
+msgid "Inherit owner"
+msgstr ""
+
+msgid "Name"
+msgstr ""
+
+msgid "Network Shares"
+msgstr "Mạng chia sẻ"
+
+msgid "Path"
+msgstr ""
+
+msgid ""
+"Please add directories to share. Each directory refers to a folder on a "
+"mounted device."
+msgstr ""
+
+#, fuzzy
+msgid "Read-only"
+msgstr "Chỉ đọc "
+
+msgid "Share home-directories"
+msgstr "Chia sẻ danh bạ chính"
+
+msgid "Shared Directories"
+msgstr "Thư mục chia sẻ"
+
+msgid ""
+"This is the content of the file '/etc/samba/smb.conf.template' from which "
+"your samba configuration will be generated. Values enclosed by pipe symbols "
+"('|') should not be changed. They get their values from the 'General "
+"Settings' tab."
+msgstr ""
+
+msgid "Vfs objects"
+msgstr ""
+
+msgid "Workgroup"
+msgstr "Nhóm làm việc "
+
+#~ msgid "Mask for new directories"
+#~ msgstr "Mask cho thư mục mới"
+
+#~ msgid "Mask for new files"
+#~ msgstr "Mask cho tập tin mới"
+
+#~ msgid "Shared Directory"
+#~ msgstr "Đã chia sẻ thư mục"
+
+#~ msgid "Physical Path"
+#~ msgstr "Đường dẫn vật lý"
+
+#~ msgid "optional"
+#~ msgstr "Tùy thích"
--- /dev/null
+#
+# Yangfl <mmyangfl@gmail.com>, 2017.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-06-10 03:40+0200\n"
+"PO-Revision-Date: 2017-10-29 15:36+0800\n"
+"Last-Translator: Yangfl <mmyangfl@gmail.com>\n"
+"Language-Team: <debian-l10n-chinese@lists.debian.org>\n"
+"Language: zh_CN\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Generator: Gtranslator 2.91.7\n"
+
+msgid "Allow guests"
+msgstr "允许匿名用户"
+
+msgid "Allow system users to reach their home directories via network shares"
+msgstr "允许系统用户通过网络共享访问他们的家目录"
+
+msgid "Allowed users"
+msgstr "允许用户"
+
+msgid "Browseable"
+msgstr "可浏览"
+
+msgid "Create mask"
+msgstr "创建权限掩码"
+
+msgid "Description"
+msgstr "描述"
+
+msgid "Directory mask"
+msgstr "目录权限掩码"
+
+msgid "Disable Active Directory Domain Controller"
+msgstr ""
+
+msgid "Disable Netbios"
+msgstr ""
+
+msgid "Disable Winbind"
+msgstr ""
+
+msgid "Edit Template"
+msgstr "编辑模板"
+
+msgid "Edit the template that is used for generating the samba configuration."
+msgstr "编辑用来生成 samba 设置的模板"
+
+msgid "General Settings"
+msgstr "基本设置"
+
+msgid "Guests only"
+msgstr ""
+
+msgid "Hostname"
+msgstr "主机名"
+
+msgid "Inherit owner"
+msgstr ""
+
+msgid "Name"
+msgstr "共享名"
+
+msgid "Network Shares"
+msgstr "网络共享"
+
+msgid "Path"
+msgstr "目录"
+
+msgid ""
+"Please add directories to share. Each directory refers to a folder on a "
+"mounted device."
+msgstr "请添加要共享的目录。每个目录指到已挂载设备上的文件夹。"
+
+msgid "Read-only"
+msgstr "只读"
+
+msgid "Share home-directories"
+msgstr "共享家目录"
+
+msgid "Shared Directories"
+msgstr "共享目录"
+
+msgid ""
+"This is the content of the file '/etc/samba/smb.conf.template' from which "
+"your samba configuration will be generated. Values enclosed by pipe symbols "
+"('|') should not be changed. They get their values from the 'General "
+"Settings' tab."
+msgstr ""
+"这是将从其上生成 samba 配置的文件“/etc/samba/smb.conf.template”的内容。由管道"
+"符(“|”)包围的值不应更改。它们将从“常规设置”标签中获取其值。"
+
+msgid "Vfs objects"
+msgstr ""
+
+msgid "Workgroup"
+msgstr "工作组"
+
+#~ msgid "Mask for new directories"
+#~ msgstr "新目录权限掩码"
+
+#~ msgid "Mask for new files"
+#~ msgstr "新文件权限掩码"
+
+#~ msgid "Physical Path"
+#~ msgstr "物理路径"
--- /dev/null
+#
+# Yangfl <mmyangfl@gmail.com>, 2017.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-06-10 03:40+0200\n"
+"PO-Revision-Date: 2017-10-29 15:36+0800\n"
+"Last-Translator: Yangfl <mmyangfl@gmail.com>\n"
+"Language-Team: <debian-l10n-chinese@lists.debian.org>\n"
+"Language: zh_TW\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Generator: Gtranslator 2.91.7\n"
+
+msgid "Allow guests"
+msgstr "允許匿名使用者"
+
+msgid "Allow system users to reach their home directories via network shares"
+msgstr "允許系統使用者通過網路共享訪問他們的家目錄"
+
+msgid "Allowed users"
+msgstr "允許使用者"
+
+msgid "Browseable"
+msgstr "可瀏覽"
+
+msgid "Create mask"
+msgstr "建立權限掩碼"
+
+msgid "Description"
+msgstr "描述"
+
+msgid "Directory mask"
+msgstr "目錄權限掩碼"
+
+msgid "Disable Active Directory Domain Controller"
+msgstr ""
+
+msgid "Disable Netbios"
+msgstr ""
+
+msgid "Disable Winbind"
+msgstr ""
+
+msgid "Edit Template"
+msgstr "編輯模板"
+
+msgid "Edit the template that is used for generating the samba configuration."
+msgstr "編輯用來生成 samba 設定的模板"
+
+msgid "General Settings"
+msgstr "基本設定"
+
+msgid "Guests only"
+msgstr ""
+
+msgid "Hostname"
+msgstr "主機名"
+
+msgid "Inherit owner"
+msgstr ""
+
+msgid "Name"
+msgstr "共享名"
+
+msgid "Network Shares"
+msgstr "網路共享"
+
+msgid "Path"
+msgstr "目錄"
+
+msgid ""
+"Please add directories to share. Each directory refers to a folder on a "
+"mounted device."
+msgstr "請新增要共享的目錄。每個目錄指到已掛載裝置上的資料夾。"
+
+msgid "Read-only"
+msgstr "只讀"
+
+msgid "Share home-directories"
+msgstr "共享家目錄"
+
+msgid "Shared Directories"
+msgstr "共享目錄"
+
+msgid ""
+"This is the content of the file '/etc/samba/smb.conf.template' from which "
+"your samba configuration will be generated. Values enclosed by pipe symbols "
+"('|') should not be changed. They get their values from the 'General "
+"Settings' tab."
+msgstr ""
+"這是將從其上生成 samba 配置的檔案“/etc/samba/smb.conf.template”的內容。由管道"
+"符(“|”)包圍的值不應更改。它們將從“常規設定”標籤中獲取其值。"
+
+msgid "Vfs objects"
+msgstr ""
+
+msgid "Workgroup"
+msgstr "工作組"
+
+#~ msgid "Mask for new directories"
+#~ msgstr "新目錄權限掩碼"
+
+#~ msgid "Mask for new files"
+#~ msgstr "新檔案權限掩碼"
+
+#~ msgid "Physical Path"
+#~ msgstr "物理路徑"
local uci = require "luci.model.uci".cursor()
local trport = uci:get_first("transmission", "transmission", "rpc_port") or 9091
local running = (luci.sys.call("pidof transmission-daemon > /dev/null") == 0)
-local webinstalled = luci.model.ipkg.installed("transmission-web")
+local webinstalled = luci.model.ipkg.installed("transmission-web") or uci:get_first("transmission", "transmission", "web_home")
local button = ""
if running and webinstalled then
button = " <input type=\"button\" value=\" " .. translate("Open Web Interface") .. " \" onclick=\"window.open('http://'+window.location.hostname+':" .. trport .. "')\"/>"
user:value(p_user)
end
cache_size_mb=s:option(Value, "cache_size_mb", translate("Cache size in MB"))
+web_home=s:option(Value, "web_home", translate("Custom WEB UI directory"))
bandwidth=m:section(TypedSection, "transmission", translate("Bandwidth settings"))
bandwidth.anonymous=true
module("luci.controller.travelmate", package.seeall)
-local util = require("luci.util")
-local i18n = require("luci.i18n")
-local templ = require("luci.template")
+local sys = require("luci.sys")
+local util = require("luci.util")
+local http = require("luci.http")
+local i18n = require("luci.i18n")
+local json = require("luci.jsonc")
+local uci = require("luci.model.uci").cursor()
function index()
if not nixio.fs.access("/etc/config/travelmate") then
entry({"admin", "services", "travelmate"}, firstchild(), _("Travelmate"), 40).dependent = false
entry({"admin", "services", "travelmate", "tab_from_cbi"}, cbi("travelmate/overview_tab", {hideresetbtn=true, hidesavebtn=true}), _("Overview"), 10).leaf = true
entry({"admin", "services", "travelmate", "stations"}, template("travelmate/stations"), _("Wireless Stations"), 20).leaf = true
- entry({"admin", "services", "travelmate", "logfile"}, call("logread"), _("View Logfile"), 30).leaf = true
+ entry({"admin", "services", "travelmate", "log"}, template("travelmate/logread"), _("View Logfile"), 30).leaf = true
entry({"admin", "services", "travelmate", "advanced"}, firstchild(), _("Advanced"), 100)
entry({"admin", "services", "travelmate", "advanced", "configuration"}, form("travelmate/configuration_tab"), _("Edit Travelmate Configuration"), 110).leaf = true
entry({"admin", "services", "travelmate", "advanced", "cfg_wireless"}, form("travelmate/cfg_wireless_tab"), _("Edit Wireless Configuration"), 120).leaf = true
entry({"admin", "services", "travelmate", "advanced", "cfg_network"}, form("travelmate/cfg_network_tab"), _("Edit Network Configuration"), 130).leaf = true
entry({"admin", "services", "travelmate", "advanced", "cfg_firewall"}, form("travelmate/cfg_firewall_tab"), _("Edit Firewall Configuration"), 140).leaf = true
+ entry({"admin", "services", "travelmate", "logread"}, call("logread"), nil).leaf = true
+ entry({"admin", "services", "travelmate", "status"}, call("status_update"), nil).leaf = true
+ entry({"admin", "services", "travelmate", "action"}, call("trm_action"), nil).leaf = true
entry({"admin", "services", "travelmate", "apqr"}, template("travelmate/ap_qr")).leaf = true
entry({"admin", "services", "travelmate", "wifiscan"}, template("travelmate/wifi_scan")).leaf = true
entry({"admin", "services", "travelmate", "wifiadd"}, form("travelmate/wifi_add", {hideresetbtn=true, hidesavebtn=true})).leaf = true
entry({"admin", "services", "travelmate", "wifiorder"}, form("travelmate/wifi_order", {hideresetbtn=true, hidesavebtn=true})).leaf = true
end
+function trm_action(name)
+ if name == "do_restart" then
+ luci.sys.call("/etc/init.d/travelmate restart >/dev/null 2>&1")
+ end
+ luci.http.prepare_content("text/plain")
+ luci.http.write("0")
+end
+
+function status_update()
+ local rt_file
+ local content
+
+ rt_file = uci:get("travelmate", "global", "trm_rtfile") or "/tmp/trm_runtime.json"
+
+ if nixio.fs.access(rt_file) then
+ content = json.parse(nixio.fs.readfile(rt_file) or "")
+ http.prepare_content("application/json")
+ http.write_json(content)
+ end
+end
+
function logread()
- local logfile = ""
+ local content
if nixio.fs.access("/var/log/messages") then
- logfile = util.trim(util.exec("grep -F 'travelmate-' /var/log/messages"))
- elseif nixio.fs.access("/sbin/logread") then
- logfile = util.trim(util.exec("logread -e 'travelmate-'"))
+ content = util.trim(util.exec("grep -F 'travelmate-' /var/log/messages"))
+ else
+ content = util.trim(util.exec("logread -e 'travelmate-'"))
+ end
+
+ if content == "" then
+ content = "No travelmate related logs yet!"
end
- templ.render("travelmate/logread", {title = i18n.translate("Travelmate Logfile"), content = logfile})
+ http.write(content)
end
--- Copyright 2017 Dirk Brenken (dev@brenken.org)
+-- Copyright 2017-2018 Dirk Brenken (dev@brenken.org)
-- This is free software, licensed under the Apache License, Version 2.0
-local fs = require("nixio.fs")
-local util = require("luci.util")
-local trminput = "/etc/config/firewall"
+local fs = require("nixio.fs")
+local util = require("luci.util")
+local input = "/etc/config/firewall"
-if not nixio.fs.access(trminput) then
+if not fs.access(input) then
m = SimpleForm("error", nil, translate("Input file not found, please check your configuration."))
return m
end
f.rmempty = true
function f.cfgvalue()
- return nixio.fs.readfile(trminput) or ""
+ return fs.readfile(input) or ""
end
function f.write(self, section, data)
- return nixio.fs.writefile(trminput, "\n" .. util.trim(data:gsub("\r\n", "\n")) .. "\n")
+ return fs.writefile(input, "\n" .. util.trim(data:gsub("\r\n", "\n")) .. "\n")
+end
+
+function f.remove(self, section, value)
+ return fs.writefile(input, "")
end
function s.handle(self, state, data)
--- Copyright 2017 Dirk Brenken (dev@brenken.org)
+-- Copyright 2017-2018 Dirk Brenken (dev@brenken.org)
-- This is free software, licensed under the Apache License, Version 2.0
-local fs = require("nixio.fs")
-local util = require("luci.util")
-local trminput = "/etc/config/network"
+local fs = require("nixio.fs")
+local util = require("luci.util")
+local input = "/etc/config/network"
-if not nixio.fs.access(trminput) then
+if not fs.access(input) then
m = SimpleForm("error", nil, translate("Input file not found, please check your configuration."))
return m
end
f.rmempty = true
function f.cfgvalue()
- return nixio.fs.readfile(trminput) or ""
+ return fs.readfile(input) or ""
end
function f.write(self, section, data)
- return nixio.fs.writefile(trminput, "\n" .. util.trim(data:gsub("\r\n", "\n")) .. "\n")
+ return fs.writefile(input, "\n" .. util.trim(data:gsub("\r\n", "\n")) .. "\n")
+end
+
+function f.remove(self, section, value)
+ return fs.writefile(input, "")
end
function s.handle(self, state, data)
--- Copyright 2017 Dirk Brenken (dev@brenken.org)
+-- Copyright 2017-2018 Dirk Brenken (dev@brenken.org)
-- This is free software, licensed under the Apache License, Version 2.0
-local fs = require("nixio.fs")
-local util = require("luci.util")
-local trminput = "/etc/config/wireless"
+local fs = require("nixio.fs")
+local util = require("luci.util")
+local input = "/etc/config/wireless"
-if not nixio.fs.access(trminput) then
+if not fs.access(input) then
m = SimpleForm("error", nil, translate("Input file not found, please check your configuration."))
return m
end
f.rmempty = true
function f.cfgvalue()
- return nixio.fs.readfile(trminput) or ""
+ return fs.readfile(input) or ""
end
function f.write(self, section, data)
- return nixio.fs.writefile(trminput, "\n" .. util.trim(data:gsub("\r\n", "\n")) .. "\n")
+ return fs.writefile(input, "\n" .. util.trim(data:gsub("\r\n", "\n")) .. "\n")
+end
+
+function f.remove(self, section, value)
+ return fs.writefile(input, "")
end
function s.handle(self, state, data)
--- Copyright 2017 Dirk Brenken (dev@brenken.org)
+-- Copyright 2017-2018 Dirk Brenken (dev@brenken.org)
-- This is free software, licensed under the Apache License, Version 2.0
-local fs = require("nixio.fs")
-local util = require("luci.util")
-local trminput = "/etc/config/travelmate"
+local fs = require("nixio.fs")
+local util = require("luci.util")
+local input = "/etc/config/travelmate"
-if not nixio.fs.access(trminput) then
+if not fs.access(input) then
m = SimpleForm("error", nil, translate("Input file not found, please check your configuration."))
m.reset = false
m.submit = false
f.rmempty = true
function f.cfgvalue()
- return nixio.fs.readfile(trminput) or ""
+ return fs.readfile(input) or ""
end
function f.write(self, section, data)
- return nixio.fs.writefile(trminput, "\n" .. util.trim(data:gsub("\r\n", "\n")) .. "\n")
+ return fs.writefile(input, "\n" .. util.trim(data:gsub("\r\n", "\n")) .. "\n")
+end
+
+function f.remove(self, section, value)
+ return fs.writefile(input, "")
end
function s.handle(self, state, data)
local fs = require("nixio.fs")
local uci = require("luci.model.uci").cursor()
-local json = require("luci.jsonc")
local util = require("luci.util")
local nw = require("luci.model.network").init()
local fw = require("luci.model.firewall").init()
local dump = util.ubus("network.interface", "dump", {})
local trmiface = uci:get("travelmate", "global", "trm_iface") or "trm_wwan"
-local trminput = uci:get("travelmate", "global", "trm_rtfile") or "/tmp/trm_runtime.json"
local uplink = uci:get("network", trmiface) or ""
-local parse = json.parse(fs.readfile(trminput) or "")
m = Map("travelmate", translate("Travelmate"),
translate("Configuration of the travelmate package to to enable travel router functionality. ")
m.apply_on_parse = true
function m.on_apply(self)
- luci.sys.call("env -i /etc/init.d/travelmate restart >/dev/null 2>&1")
- luci.http.redirect(luci.dispatcher.build_url("admin", "services", "travelmate"))
+ luci.sys.call("/etc/init.d/travelmate restart >/dev/null 2>&1")
end
-- Interface Wizard
ds = m:section(NamedSection, "global", "travelmate", translate("Interface Wizard"))
o = ds:option(Value, "trm_iface", translate("Create Uplink interface"),
translate("Create a new wireless wan uplink interface, configure it to use dhcp and ")
- .. translate("add it to the wan zone of the firewall.<br />")
+ .. translate("add it to the wan zone of the firewall. ")
.. translate("This step has only to be done once."))
o.datatype = "and(uciname,rangelength(3,15))"
o.default = trmiface
-- Runtime information
-ds = m:section(NamedSection, "global", "travelmate", translate("Runtime Information"))
-
-dv1 = ds:option(DummyValue, "status", translate("Travelmate Status (Quality)"))
-dv1.template = "travelmate/runtime"
-if parse ~= nil then
- dv1.value = parse.data.travelmate_status or translate("n/a")
-else
- dv1.value = translate("n/a")
-end
-
-dv2 = ds:option(DummyValue, "travelmate_version", translate("Travelmate Version"))
-dv2.template = "travelmate/runtime"
-if parse ~= nil then
- dv2.value = parse.data.travelmate_version or translate("n/a")
-else
- dv2.value = translate("n/a")
-end
-
-dv3 = ds:option(DummyValue, "station_id", translate("Station ID (SSID/BSSID)"))
-dv3.template = "travelmate/runtime"
-if parse ~= nil then
- dv3.value = parse.data.station_id or translate("n/a")
-else
- dv3.value = translate("n/a")
-end
-
-dv4 = ds:option(DummyValue, "station_interface", translate("Station Interface"))
-dv4.template = "travelmate/runtime"
-if parse ~= nil then
- dv4.value = parse.data.station_interface or translate("n/a")
-else
- dv4.value = translate("n/a")
-end
-
-dv5 = ds:option(DummyValue, "station_radio", translate("Station Radio"))
-dv5.template = "travelmate/runtime"
-if parse ~= nil then
- dv5.value = parse.data.station_radio or translate("n/a")
-else
- dv5.value = translate("n/a")
-end
-
-dv6 = ds:option(DummyValue, "last_rundate", translate("Last rundate"))
-dv6.template = "travelmate/runtime"
-if parse ~= nil then
- dv6.value = parse.data.last_rundate or translate("n/a")
-else
- dv6.value = translate("n/a")
-end
+ds = s:option(DummyValue, "_dummy")
+ds.template = "travelmate/runtime"
-- Extra options
<%+header%>
<div class="cbi-map">
- <div class="cbi-map-descr">
- <%=translate("Here you'll find the QR codes from all of your configured Access Points. It allows you to connect your Android or iOS devices to your router's WiFi using the QR code shown below.")%>
- </div>
-<%-
- local write = io.write
- local uci = require("luci.model.uci").cursor()
+ <div class="cbi-map-descr">
+ <%=translate("Here you'll find the QR codes from all of your configured Access Points. It allows you to connect your Android or iOS devices to your router's WiFi using the QR code shown below.")%>
+ </div>
+ <%- local uci = require("luci.model.uci").cursor()
- uci:foreach("wireless", "wifi-iface", function(s)
- local device = s.device or ""
- local mode = s.mode or ""
- local ssid = s.ssid or ""
- local enc = s.encryption or ""
- local key = s.key or ""
- local hidden = s.hidden or "false"
- local disabled = s.disabled or ""
- local wep_slots = {s.key1 or "", s.key2 or "", s.key3 or "", s.key4 or ""}
+ uci:foreach("wireless", "wifi-iface", function(s)
+ local device = s.device or ""
+ local mode = s.mode or ""
+ local ssid = s.ssid or ""
+ local enc = s.encryption or ""
+ local key = s.key or ""
+ local hidden = s.hidden or "false"
+ local disabled = s.disabled or ""
+ local wep_slots = {s.key1 or "", s.key2 or "", s.key3 or "", s.key4 or ""}
- if device and mode == "ap" and disabled ~= "1" then
- if string.match(enc, '^psk') then
- enc = "WPA"
- elseif string.match(enc, '^wep') then
- enc = "WEP"
- if tonumber(key) then
- key = wep_slots[tonumber(key)]
- end
- elseif enc == "none" then
- enc = "nopass"
- key = "nokey"
- else
- enc = ""
- end
- if hidden == "1" then
- hidden = "true"
- end
- if ssid and enc and key then
- local e_ssid = string.gsub(ssid,"[\"\\';:, ]",[[\\\%1]])
- local e_key = string.gsub(key,"[\"\\';:, ]",[[\\\%1]])
- local qrcode = ""
- qrcode = luci.sys.exec("/usr/bin/qrencode --inline --8bit --type=SVG --output=- 'WIFI:S:\"'" .. e_ssid .. "'\";T:'" .. enc .. "';P:\"'" .. e_key .. "'\";H:'" .. hidden .. "';'")
--%>
- <fieldset class="cbi-section">
- <legend>AP on <%=device%> with SSID "<%=ssid%>"</legend>
- <h3 name="content"><%=qrcode%></h3>
- </fieldset>
-<%-
- end
- end
- end)
-%>
+ if device and mode == "ap" and disabled ~= "1" then
+ if string.match(enc, '^psk') then
+ enc = "WPA"
+ elseif string.match(enc, '^wep') then
+ enc = "WEP"
+ if tonumber(key) then
+ key = wep_slots[tonumber(key)]
+ end
+ elseif enc == "none" then
+ enc = "nopass"
+ key = "nokey"
+ else
+ enc = ""
+ end
+
+ if hidden == "1" then
+ hidden = "true"
+ end
+
+ if ssid and enc and key then
+ local e_ssid = string.gsub(ssid,"[\"\\';:, ]",[[\\\%1]])
+ local e_key = string.gsub(key,"[\"\\';:, ]",[[\\\%1]])
+ local qrcode = ""
+
+ qrcode = luci.sys.exec("/usr/bin/qrencode --inline --8bit --type=SVG --output=- 'WIFI:S:\"'" .. e_ssid .. "'\";T:'" .. enc .. "';P:\"'" .. e_key .. "'\";H:'" .. hidden .. "';'")
+ -%>
+ <div class="cbi-section">
+ <h3>AP on <%=device%> with SSID "<%=ssid%>"</h3>
+ <h3><%=qrcode%></h3>
+ </div>
+ <%-
+ end
+ end
+ end)
+ -%>
</div>
<div class="cbi-page-actions right">
- <form class="inline" action="<%=luci.dispatcher.build_url('admin/services/travelmate/tab_from_cbi')%>" method="post">
- <input class="cbi-button cbi-button-reset" type="submit" value="<%:Back to overview%>"/>
- </form>
+ <form class="inline" action="<%=luci.dispatcher.build_url('admin/services/travelmate/tab_from_cbi')%>" method="post">
+ <input class="cbi-button cbi-button-reset" type="submit" value="<%:Back to overview%>" />
+ </form>
</div>
<%+footer%>
<%+header%>
+<style type="text/css">
+ select[readonly],
+ textarea[readonly]
+ {
+ width: 100%;
+ height: 450px;
+ border: 1px solid #cccccc;
+ padding: 5px;
+ font-size: 12px;
+ font-family: monospace;
+ resize: none;
+ pointer-events: auto;
+ cursor: auto;
+ }
+</style>
+
+<script type="text/javascript">
+//<![CDATA[
+ function log_update()
+ {
+ XHR.poll(5, '<%=luci.dispatcher.build_url("admin", "services", "travelmate", "logread")%>', null,
+ function(x)
+ {
+ if (!x)
+ {
+ return;
+ }
+ var view = document.getElementById("view_id");
+ view.value = x.responseText;
+ view.scrollTop = view.scrollHeight;
+ });
+ }
+ window.onload = log_update();
+//]]>
+</script>
+
<div class="cbi-map">
<div class="cbi-section">
- <div class="cbi-section-descr"><%:This form shows the syslog output, pre-filtered for travelmate related messages only.%></div>
- <textarea id="logread_id" style="width: 100%; height: 450px; border: 1px solid #cccccc; padding: 5px; font-size: 12px; font-family: monospace; resize: none;" readonly="readonly" wrap="off" rows="<%=content:cmatch("\n")+2%>"><%=content:pcdata()%></textarea>
+ <div class="cbi-section-descr"><%:The syslog output, pre-filtered for travelmate related messages only.%></div>
+ <textarea id="view_id" readonly="readonly" wrap="off" value=""></textarea>
</div>
</div>
-<script type="text/javascript">
- var textarea = document.getElementById('logread_id');
- textarea.scrollTop = textarea.scrollHeight;
-</script>
-
<%+footer%>
This is free software, licensed under the Apache License, Version 2.0
-%>
-<%+cbi/valueheader%>
+<style type="text/css">
+ .runtime
+ {
+ color: #37c;
+ font-weight: bold;
+ display: inline-block;
+ width: 100%;
+ padding-top: 0.5rem;
+ }
+</style>
-<input name="runtime" id="runtime" type="text" class="cbi-input-text" style="outline:none;border:none;box-shadow:none;background:transparent;color:#0069d6;font-weight:bold;line-height:30px;height:30px;width:50em;" value="<%=self:cfgvalue(section)%>" disabled="disabled" />
+<script type="text/javascript">
+//<![CDATA[
+ function status_update(json)
+ {
+ var btn1 = document.getElementById("btn1");
+ var view = document.getElementById("value_1");
+ var input = json.data.travelmate_status;
-<%+cbi/valuefooter%>
+ btn1.value = "<%:Restart%>";
+ btn1.name = "do_restart";
+ view.innerHTML = input || "-";
+ view = document.getElementById("value_2");
+ input = json.data.travelmate_version;
+ view.innerHTML = input || "-";
+ view = document.getElementById("value_3");
+ input = json.data.station_id;
+ view.innerHTML = input || "-";
+ view = document.getElementById("value_4");
+ input = json.data.station_interface;
+ view.innerHTML = input || "-";
+ view = document.getElementById("value_5");
+ input = json.data.faulty_stations;
+ view.innerHTML = input || "-";
+ view = document.getElementById("value_6");
+ input = json.data.last_rundate;
+ view.innerHTML = input || "-";
+ }
+
+ function btn_action(action)
+ {
+ var btn1 = document.getElementById("btn1");
+ var btn1_running = document.getElementById("btn1_running");
+
+ btn1.disabled = true;
+ running(btn1_running, 1);
+
+ new XHR.get('<%=luci.dispatcher.build_url("admin", "services", "travelmate")%>/action/' + action.name, null,
+ function(x)
+ {
+ if (!x)
+ {
+ return;
+ }
+ btn1.disabled = false;
+ running(btn1_running, 0);
+ });
+ }
+
+ function running(element, state)
+ {
+ if (state === 1)
+ {
+ var running_html = '<img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" width="16" height="16" style="vertical-align:middle" />';
+ element.innerHTML = running_html;
+ }
+ else
+ {
+ element.innerHTML = '';
+ }
+ }
+
+ XHR.get('<%=luci.dispatcher.build_url("admin", "services", "travelmate", "status")%>', null,
+ function(x, json_info)
+ {
+ if (!x || !json_info)
+ {
+ return;
+ }
+ status_update(json_info)
+ });
+
+ XHR.poll(5, '<%=luci.dispatcher.build_url("admin", "services", "travelmate", "status")%>', null,
+ function(x, json_info)
+ {
+ if (!x || !json_info)
+ {
+ return;
+ }
+ status_update(json_info)
+ });
+//]]>
+</script>
+
+<h3><%:Runtime Information%></h3>
+<div class="cbi-value" id="status_1">
+ <label class="cbi-value-title" for="status_1"><%:Travelmate Status (Quality)%></label>
+ <div class="cbi-value-field">
+ <span class="runtime" id="value_1">-</span>
+ </div>
+</div>
+<div class="cbi-value" id="status_2">
+ <label class="cbi-value-title" for="status_2"><%:Travelmate Version%></label>
+ <div class="cbi-value-field">
+ <span class="runtime" id="value_2">-</span>
+ </div>
+</div>
+<div class="cbi-value" id="status_3">
+ <label class="cbi-value-title" for="status_3"><%:Station ID (RADIO/SSID/BSSID)%></label>
+ <div class="cbi-value-field">
+ <span class="runtime" id="value_3">-</span>
+ </div>
+</div>
+<div class="cbi-value" id="status_4">
+ <label class="cbi-value-title" for="status_4"><%:Station Interface%></label>
+ <div class="cbi-value-field">
+ <span class="runtime" id="value_4">-</span>
+ </div>
+</div>
+<div class="cbi-value" id="status_5">
+ <label class="cbi-value-title" for="status_5"><%:Faulty Stations%></label>
+ <div class="cbi-value-field">
+ <span class="runtime" id="value_5">-</span>
+ </div>
+</div>
+<div class="cbi-value" id="status_6">
+ <label class="cbi-value-title" for="status_6"><%:Last Run%></label>
+ <div class="cbi-value-field">
+ <span class="runtime" id="value_6">-</span>
+ </div>
+</div>
+<hr />
+<div class="cbi-value" id="button_1">
+ <label class="cbi-value-title" for="button_1"><%:Restart Travelmate%></label>
+ <div class="cbi-value-field">
+ <input class="cbi-button cbi-button-reset" id="btn1" type="button" name="do_restart" value="<%:Restart%>" onclick="btn_action(this)" />
+ <span id="btn1_running" style="display:inline-block; width:16px; height:16px; margin:0 5px"></span>
+ </div>
+</div>
-%>
<%-
- local write = io.write
- local uci = require("luci.model.uci").cursor()
- local trmiface = uci:get("travelmate", "global", "trm_iface") or "trm_wwan"
+ local uci = require("luci.model.uci").cursor()
+ local trmiface = uci:get("travelmate", "global", "trm_iface") or "trm_wwan"
-%>
<%+header%>
+<script type="text/javascript">
+//<![CDATA[
+ function status_update(json)
+ {
+ var i;
+ var j;
+ var search;
+ var view;
+ var list;
+ var status = json.data.travelmate_status;
+ var faulty = json.data.faulty_stations;
+
+ if (faulty)
+ {
+ var faulty_array = faulty.split(' ');
+ for (i = 0; i < faulty_array.length; i++)
+ {
+ for (j = 1; j <= 5; j++)
+ {
+ search = j + "_" + faulty_array[i];
+ view = document.getElementById(search);
+ if (view)
+ {
+ view.setAttribute("name", "station_nok");
+ view.setAttribute("style", "color: #a22; font-weight: bold");
+ }
+ }
+ }
+ }
+ else
+ {
+ list = document.getElementsByName("station_nok");
+ if (list.length > 0)
+ {
+ for (i = 0; i < list.length; i++)
+ {
+ list[i].removeAttribute("style");
+ }
+ }
+ }
+
+ if (status.startsWith("connected"))
+ {
+ for (i = 1; i <= 5; i++)
+ {
+ search = i + "_" + json.data.station_id;
+ view = document.getElementById(search);
+ if (view)
+ {
+ view.setAttribute("style", "color: #37c; font-weight: bold");
+ }
+ }
+ }
+ else
+ {
+ list = document.getElementsByName("station_ok");
+ if (list.length > 0)
+ {
+ for (i = 0; i < list.length; i++)
+ {
+ list[i].removeAttribute("style");
+ }
+ }
+ }
+ }
+
+ XHR.get('<%=luci.dispatcher.build_url("admin", "services", "travelmate", "status")%>', null,
+ function(x, json_info)
+ {
+ if (!x || !json_info)
+ {
+ return;
+ }
+ status_update(json_info)
+ });
+
+ XHR.poll(5, '<%=luci.dispatcher.build_url("admin", "services", "travelmate", "status")%>', null,
+ function(x, json_info)
+ {
+ if (!x || !json_info)
+ {
+ return;
+ }
+ status_update(json_info)
+ });
+//]]>
+</script>
<div class="cbi-map">
-<div class="cbi-map-descr">
- <%=translatef("Provides an overview of all configured uplinks for the travelmate interface (%s). You can edit, delete or re-order existing uplinks or scan for a new one. The currently used uplink is emphasized in blue.", trmiface)%>
-</div>
+ <div class="cbi-map-descr">
+ <%=translatef("Provides an overview of all configured uplinks for the travelmate interface (%s). You can edit, delete or re-order existing uplinks or scan for a new one. The currently used uplink is emphasized in blue, faulty stations in red.", trmiface)%>
+ </div>
-<div class="cbi-section">
- <div class="table cbi-section-table">
- <div class="tr cbi-section-table-titles">
- <div class="th left"><%:Device%></div>
- <div class="th left"><%:SSID%></div>
- <div class="th left"><%:BSSID%></div>
- <div class="th left"><%:Encryption%></div>
- <div class="th center"> </div>
- </div>
-<%
- uci:foreach("wireless", "wifi-iface", function(s)
- local iface = s.network or ""
- if iface == trmiface then
- local section = s['.name'] or ""
- local device = s.device or "-"
- local ssid = s.ssid or "-"
- local bssid = s.bssid or "-"
- local encryption = s.encryption or "-"
- local disabled = s.disabled or ""
- local style = "text-align:left;color:#000000"
- if disabled == "0" then
- style = "text-align:left;color:#0069d6;font-weight:bold"
- end
-%>
- <div class="tr cbi-section-table-row cbi-rowstyle-1" style="<%=style%>">
- <div class="td" style="<%=style%>"><%=device%></div>
- <div class="td" style="<%=style%>"><%=ssid%></div>
- <div class="td" style="<%=style%>"><%=bssid%></div>
- <div class="td" style="<%=style%>"><%=encryption%></div>
- <div class="td cbi-section-actions">
- <input class="cbi-button cbi-button-up" type="button" value="<%:Up%>" onclick="location.href='<%=luci.dispatcher.build_url('admin/services/travelmate/wifiorder')%>?cfg=<%=section%>&dir=up'" alt="<%:Move up%>" title="<%:Move up%>"/>
- <input class="cbi-button cbi-button-down" type="button" value="<%:Down%>" onclick="location.href='<%=luci.dispatcher.build_url('admin/services/travelmate/wifiorder')%>?cfg=<%=section%>&dir=down'" alt="<%:Move down%>" title="<%:Move down%>"/>
- <input type="button" class="cbi-button cbi-button-edit" onclick="location.href='<%=luci.dispatcher.build_url('admin/services/travelmate/wifiedit')%>?cfg=<%=section%>'" title="<%:Edit this Uplink%>" value="<%:Edit%>"/>
- <input type="button" class="cbi-button cbi-button-remove" onclick="location.href='<%=luci.dispatcher.build_url('admin/services/travelmate/wifidelete')%>?cfg=<%=section%>'" title="<%:Delete this Uplink%>" value="<%:Delete%>"/>
- </div>
- </div>
-<%
- end
- end)
-%>
- </div>
-</div>
-<div class="cbi-page-actions right">
-<%
- uci:foreach("wireless", "wifi-device", function(s)
- local device = s[".name"]
-%>
- <form class="inline" action="<%=luci.dispatcher.build_url('admin/services/travelmate/wifiscan')%>" method="post">
- <input type="hidden" name="device" value="<%=device%>"/>
- <input type="hidden" name="token" value="<%=token%>"/>
- <input type="submit" class="cbi-button cbi-button-action important" title="<%:Find and join network on%> <%=device%>" value="<%:Scan%> <%=device%>"/>
- </form>
-<%
- end)
-%>
-</div>
+ <div class="cbi-section">
+ <div class="table cbi-section-table">
+ <div class="tr cbi-section-table-titles">
+ <div class="th left"><%:Device%></div>
+ <div class="th left"><%:SSID%></div>
+ <div class="th left"><%:BSSID%></div>
+ <div class="th left"><%:Encryption%></div>
+ <div class="th center"><%:Action%></div>
+ </div>
+ <%- uci:foreach("wireless", "wifi-iface", function(s)
+ local iface = s.network or ""
+ if iface == trmiface then
+ local section = s['.name'] or ""
+ local device = s.device or "-"
+ local ssid = s.ssid or "-"
+ local bssid = s.bssid or "-"
+ local encr = s.encryption or "-"
+ -%>
+ <div class="tr cbi-section-table-row cbi-rowstyle-1" name="station_ok" id="1_<%=device%>/<%=ssid%>/<%=bssid%>">
+ <div class="td left" name="station_ok" id="2_<%=device%>/<%=ssid%>/<%=bssid%>"><%=device%></div>
+ <div class="td left" name="station_ok" id="3_<%=device%>/<%=ssid%>/<%=bssid%>"><%=ssid%></div>
+ <div class="td left" name="station_ok" id="4_<%=device%>/<%=ssid%>/<%=bssid%>"><%=bssid%></div>
+ <div class="td left" name="station_ok" id="5_<%=device%>/<%=ssid%>/<%=bssid%>"><%=encr%></div>
+ <div class="td middle cbi-section-actions">
+ <div>
+ <input class="cbi-button cbi-button-up" type="button" value="<%:Up%>" onclick="location.href='<%=luci.dispatcher.build_url('admin/services/travelmate/wifiorder')%>?cfg=<%=section%>&dir=up'" alt="<%:Move up%>" title="<%:Move up%>" />
+ <input class="cbi-button cbi-button-down" type="button" value="<%:Down%>" onclick="location.href='<%=luci.dispatcher.build_url('admin/services/travelmate/wifiorder')%>?cfg=<%=section%>&dir=down'" alt="<%:Move down%>" title="<%:Move down%>" />
+ <input class="cbi-button cbi-button-edit" type="button" value="<%:Edit%>" onclick="location.href='<%=luci.dispatcher.build_url('admin/services/travelmate/wifiedit')%>?cfg=<%=section%>'" title="<%:Edit this Uplink%>" />
+ <input class="cbi-button cbi-button-remove" type="button" value="<%:Delete%>" onclick="location.href='<%=luci.dispatcher.build_url('admin/services/travelmate/wifidelete')%>?cfg=<%=section%>'" title="<%:Delete this Uplink%>" />
+ </div>
+ </div>
+ </div>
+ <%- end; end) -%>
+ </div>
+ </div>
+ <div class="cbi-page-actions right">
+ <%- uci:foreach("wireless", "wifi-device", function(s)
+ local device = s[".name"]
+ local hwmode = s.hwmode or "-" -%>
+ <form class="inline" action="<%=luci.dispatcher.build_url('admin/services/travelmate/wifiscan')%>" method="post">
+ <input type="hidden" name="device" value="<%=device%>" />
+ <input type="hidden" name="token" value="<%=token%>" />
+ <input type="submit" class="cbi-button cbi-button-action important" title="<%:Find and join network on%> <%=device%>" value="<%:Scan%> <%=device%> (<%=hwmode%>)" />
+ </form>
+ <%- end) -%>
+ </div>
</div>
<%+footer%>
<%#
-Copyright 2017 Dirk Brenken (dev@brenken.org)
+Copyright 2017-2018 Dirk Brenken (dev@brenken.org)
This is free software, licensed under the Apache License, Version 2.0
-%>
<%-
- local sys = require("luci.sys")
- local utl = require("luci.util")
- local dev = luci.http.formvalue("device")
- local iw = luci.sys.wifi.getiwinfo(dev)
- local wpa_label = {translate("WPA"), translate("WPA2"), translate("WPA/WPA2")}
+ local sys = require("luci.sys")
+ local utl = require("luci.util")
+ local dev = luci.http.formvalue("device")
+ local iw = luci.sys.wifi.getiwinfo(dev)
+ local label = {translate("WPA"), translate("WPA2"), translate("WPA/WPA2")}
- if not iw then
- luci.http.redirect(luci.dispatcher.build_url("admin/services/travelmate/stations"))
- end
+ if not iw then
+ luci.http.redirect(luci.dispatcher.build_url("admin/services/travelmate/stations"))
+ end
- function format_wifi_encryption(info)
- if info.wep == true then
- return translate("WEP")
- elseif info.wpa > 0 then
- return "%s (%s/%s)" %{wpa_label[info.wpa], table.concat(info.auth_suites), table.concat(info.group_ciphers)}
- elseif info.enabled then
- return translate("Unknown")
- else
- return translate("Open")
- end
- end
+ function format_wifi_encryption(info)
+ if info.wep == true then
+ return translate("WEP")
+ elseif info.wpa > 0 then
+ return "%s (%s/%s)" %{label[info.wpa], table.concat(info.auth_suites), table.concat(info.group_ciphers)}
+ elseif info.enabled then
+ return translate("Unknown")
+ else
+ return translate("Open")
+ end
+ end
- function percent_wifi_signal(info)
- local qc = info.quality or 0
- local qm = info.quality_max or 0
- if info.bssid and qc > 0 and qm > 0 then
- return math.floor((100 / qm) * qc)
- else
- return 0
- end
- end
+ function percent_wifi_signal(info)
+ local qc = info.quality or 0
+ local qm = info.quality_max or 0
+ if info.bssid and qc > 0 and qm > 0 then
+ return math.floor((100 / qm) * qc)
+ else
+ return 0
+ end
+ end
-%>
<%+header%>
-
<div class="cbi-map">
-<h2 name="content"><%:Wireless Scan%></h2>
- <div class="cbi-section">
- <div class="table cbi-section-table">
- <div class="tr cbi-section-table-titles">
- <div class="th left"><%:Uplink SSID%></div>
- <div class="th left"><%:Uplink BSSID%></div>
- <div class="th left"><%:Encryption%></div>
- <div class="th left"><%:Signal strength%></div>
- </div>
- <% for i, net in ipairs(iw.scanlist or { }) do %>
- <div class="tr cbi-section-table-row cbi-rowstyle-1">
- <div class="td left">
- <%=net.ssid and utl.pcdata(net.ssid) or "<em>%s</em>" % translate("hidden")%>
- </div>
- <div class="td left">
- <%=net.bssid and utl.pcdata(net.bssid)%>
- </div>
- <div class="td left">
- <%=format_wifi_encryption(net.encryption)%>
- </div>
- <div class="td left">
- <%=percent_wifi_signal(net)%> %
- </div>
- <div class="td cbi-section-actions">
- <form class="inline" action="<%=luci.dispatcher.build_url('admin/services/travelmate/wifiadd')%>" method="post">
- <input type="hidden" name="token" value="<%=token%>"/>
- <input type="hidden" name="device" value="<%=utl.pcdata(dev)%>"/>
- <input type="hidden" name="ssid" value="<%=utl.pcdata(net.ssid)%>"/>
- <input type="hidden" name="bssid" value="<%=utl.pcdata(net.bssid)%>"/>
- <input type="hidden" name="wep" value="<%=net.encryption.wep and 1 or 0%>"/>
- <% if net.encryption.wpa then %>
- <input type="hidden" name="wpa_version" value="<%=net.encryption.wpa%>"/>
- <% for _, v in ipairs(net.encryption.auth_suites) do %><input type="hidden" name="wpa_suites" value="<%=v%>"/><% end %>
- <% end %>
- <input class="cbi-button cbi-button-apply" type="submit" value="<%:Add Uplink%>"/>
- </form>
- </div>
- </div>
- <% end %>
- </div>
- </div>
-<div class="cbi-page-actions right">
- <form class="inline" action="<%=luci.dispatcher.build_url('admin/services/travelmate/stations')%>" method="get">
- <input class="cbi-button cbi-button-reset" type="submit" value="<%:Back to overview%>"/>
- </form>
- <form class="inline" action="<%=luci.dispatcher.build_url('admin/services/travelmate/wifiscan')%>" method="post">
- <input type="hidden" name="token" value="<%=token%>"/>
- <input type="hidden" name="device" value="<%=utl.pcdata(dev)%>"/>
- <input class="cbi-button cbi-input-find" type="submit" value="<%:Repeat scan%>"/>
- </form>
-</div>
+ <h3><%:Wireless Scan%></h3>
+ <div class="cbi-section">
+ <div class="table cbi-section-table">
+ <div class="tr cbi-section-table-titles">
+ <div class="th left"><%:Uplink SSID%></div>
+ <div class="th left"><%:Uplink BSSID%></div>
+ <div class="th left"><%:Encryption%></div>
+ <div class="th left"><%:Signal strength%></div>
+ <div class="th center"><%:Action%></div>
+ </div>
+ <%- for i, net in ipairs(iw.scanlist or { }) do -%>
+ <div class="tr cbi-section-table-row cbi-rowstyle-1">
+ <div class="td left">
+ <%=net.ssid and utl.pcdata(net.ssid) or "<em>%s</em>" % translate("hidden")%>
+ </div>
+ <div class="td left">
+ <%=net.bssid and utl.pcdata(net.bssid)%>
+ </div>
+ <div class="td left">
+ <%=format_wifi_encryption(net.encryption)%>
+ </div>
+ <div class="td left">
+ <%=percent_wifi_signal(net)%> %
+ </div>
+ <div class="td cbi-section-actions">
+ <form class="inline" action="<%=luci.dispatcher.build_url('admin/services/travelmate/wifiadd')%>" method="post">
+ <input type="hidden" name="token" value="<%=token%>"/>
+ <input type="hidden" name="device" value="<%=utl.pcdata(dev)%>"/>
+ <input type="hidden" name="ssid" value="<%=utl.pcdata(net.ssid)%>"/>
+ <input type="hidden" name="bssid" value="<%=utl.pcdata(net.bssid)%>"/>
+ <input type="hidden" name="wep" value="<%=net.encryption.wep and 1 or 0%>"/>
+ <%- if net.encryption.wpa then -%>
+ <input type="hidden" name="wpa_version" value="<%=net.encryption.wpa%>"/>
+ <%- for _, v in ipairs(net.encryption.auth_suites) do -%>
+ <input type="hidden" name="wpa_suites" value="<%=v%>"/>
+ <%- end -%>
+ <%- end -%>
+ <input class="cbi-button cbi-button-apply" type="submit" value="<%:Add Uplink%>"/>
+ </form>
+ </div>
+ </div>
+ <%- end -%>
+ </div>
+ </div>
+ <div class="cbi-page-actions right">
+ <form class="inline" action="<%=luci.dispatcher.build_url('admin/services/travelmate/stations')%>" method="get">
+ <input class="cbi-button cbi-button-reset" type="submit" value="<%:Back to overview%>"/>
+ </form>
+ <form class="inline" action="<%=luci.dispatcher.build_url('admin/services/travelmate/wifiscan')%>" method="post">
+ <input type="hidden" name="token" value="<%=token%>"/>
+ <input type="hidden" name="device" value="<%=utl.pcdata(dev)%>"/>
+ <input class="cbi-button cbi-input-find" type="submit" value="<%:Repeat scan%>"/>
+ </form>
+ </div>
</div>
<%+footer%>
-- Copyright 2008 Steven Barth <steven@midlink.org>
-- Copyright 2008 Jo-Philipp Wich <jow@openwrt.org>
--- Copyright 2017 Eric Luehrsen <ericluehrsen@hotmail.com>
+-- Copyright 2017 Eric Luehrsen <ericluehrsen@gmail.com>
-- Licensed to the public under the Apache License 2.0.
module("luci.controller.unbound", package.seeall)
function index()
- local ucl = luci.model.uci.cursor()
- local valexp = ucl:get_first("unbound", "unbound", "extended_luci")
- local valman = ucl:get_first("unbound", "unbound", "manual_conf")
+ local fs = require "nixio.fs"
+ local ucl = luci.model.uci.cursor()
+ local valman = ucl:get_first("unbound", "unbound", "manual_conf")
- if not nixio.fs.access("/etc/config/unbound") then
- return
- end
+ if not fs.access("/etc/config/unbound") then
+ return
+ end
- if valexp == "1" then
-- Expanded View
- entry({"admin", "services", "unbound"}, firstchild(), _("Recursive DNS")).dependent = false
+ entry({"admin", "services", "unbound"},
+ firstchild(), _("Recursive DNS")).dependent = false
-- UCI Tab(s)
- entry({"admin", "services", "unbound", "configure"}, cbi("unbound/configure"), _("Settings"), 10)
+ entry({"admin", "services", "unbound", "configure"},
+ cbi("unbound/configure"), _("Unbound"), 10)
+
+
+ if (valman == "0") then
+ entry({"admin", "services", "unbound", "zones"},
+ arcombine(cbi("unbound/zones"), cbi("unbound/zone-details")),
+ _("Zones"), 15).leaf = true
+ end
+
-- Status Tab(s)
- entry({"admin", "services", "unbound", "status"}, firstchild(), _("Status"), 20)
- entry({"admin", "services", "unbound", "status", "syslog"}, call("QuerySysLog"), _("Log"), 50).leaf = true
+ entry({"admin", "services", "unbound", "status"},
+ firstchild(), _("Status"), 20)
+
+ entry({"admin", "services", "unbound", "status", "syslog"},
+ call("QuerySysLog"), _("Log"), 50).leaf = true
+
+
+ if fs.access("/usr/sbin/unbound-control") then
+ -- Require unbound-control to execute
+ entry({"admin", "services", "unbound", "status", "statistics"},
+ call("QueryStatistics"), _("Statistics"), 10).leaf = true
+ entry({"admin", "services", "unbound", "status", "localdata"},
+ call("QueryLocalData"), _("Local Data"), 20).leaf = true
- if nixio.fs.access("/usr/sbin/unbound-control") then
- -- Require unbound-control to execute
- entry({"admin", "services", "unbound", "status", "statistics"}, call("QueryStatistics"), _("Statistics"), 10).leaf = true
- entry({"admin", "services", "unbound", "status", "localdata"}, call("QueryLocalData"), _("Local Data"), 20).leaf = true
- entry({"admin", "services", "unbound", "status", "localzone"}, call("QueryLocalZone"), _("Local Zones"), 30).leaf = true
+ entry({"admin", "services", "unbound", "status", "localzone"},
+ call("QueryLocalZone"), _("Local Zones"), 30).leaf = true
else
- entry({"admin", "services", "unbound", "status", "statistics"}, call("ShowEmpty"), _("Statistics"), 10).leaf = true
+ entry({"admin", "services", "unbound", "status", "statistics"},
+ call("ShowEmpty"), _("Statistics"), 10).leaf = true
end
-- Raw File Tab(s)
- entry({"admin", "services", "unbound", "files"}, firstchild(), _("Files"), 30)
+ entry({"admin", "services", "unbound", "files"},
+ firstchild(), _("Files"), 30)
- if valman ~= "1" then
- entry({"admin", "services", "unbound", "files", "base"}, call("ShowUnboundConf"), _("UCI: Unbound"), 10).leaf = true
+ if (valman == "0") then
+ entry({"admin", "services", "unbound", "files", "uci"},
+ form("unbound/uciedit"), _("Edit: UCI"), 5).leaf = true
+
+ entry({"admin", "services", "unbound", "files", "base"},
+ call("ShowUnboundConf"), _("Show: Unbound"), 10).leaf = true
+
else
- entry({"admin", "services", "unbound", "files", "base"}, form("unbound/manual"), _("Edit: Unbound"), 10).leaf = true
+ entry({"admin", "services", "unbound", "files", "base"},
+ form("unbound/manual"), _("Edit: Unbound"), 10).leaf = true
end
- entry({"admin", "services", "unbound", "files", "server"}, form("unbound/server"), _("Edit: Server"), 20).leaf = true
- entry({"admin", "services", "unbound", "files", "extended"}, form("unbound/extended"), _("Edit: Extended"), 30).leaf = true
+ entry({"admin", "services", "unbound", "files", "server"},
+ form("unbound/server"), _("Edit: Server"), 20).leaf = true
+ entry({"admin", "services", "unbound", "files", "extended"},
+ form("unbound/extended"), _("Edit: Extended"), 30).leaf = true
- if nixio.fs.access("/var/lib/unbound/unbound_dhcp.conf") then
- entry({"admin", "services", "unbound", "files", "dhcp"}, call("ShowDHCPConf"), _("Include: DHCP"), 40).leaf = true
+
+ if fs.access("/var/lib/unbound/dhcp.conf") then
+ entry({"admin", "services", "unbound", "files", "dhcp"},
+ call("ShowDHCPConf"), _("Show: DHCP"), 40).leaf = true
end
- if nixio.fs.access("/var/lib/unbound/adb_list.overall") then
- entry({"admin", "services", "unbound", "files", "adblock"}, call("ShowAdblock"), _("Include: Adblock"), 50).leaf = true
+ if fs.access("/var/lib/unbound/adb_list.overall") then
+ entry({"admin", "services", "unbound", "files", "adblock"},
+ call("ShowAdblock"), _("Show: Adblock"), 50).leaf = true
end
-
- else
- -- Simple View to UCI only
- entry({"admin", "services", "unbound"}, cbi("unbound/configure"), _("Recursive DNS")).dependent = false
- end
end
function ShowEmpty()
- local lclhead = "Unbound Control"
- local lcldesc = luci.i18n.translate("This could display more statistics with the unbound-control package.")
- luci.template.render("unbound/show-empty", {heading = lclhead, description = lcldesc})
+ local lclhead = "Unbound Control"
+ local lcldesc = luci.i18n.translate(
+ "This could display more statistics with the unbound-control package.")
+
+ luci.template.render("unbound/show-empty",
+ {heading = lclhead, description = lcldesc})
end
function QuerySysLog()
- local lclhead = "System Log"
- local lcldata = luci.util.exec("logread | grep -i unbound")
- local lcldesc = luci.i18n.translate("This shows syslog filtered for events involving Unbound.")
- luci.template.render("unbound/show-textbox", {heading = lclhead, description = lcldesc, content = lcldata})
+ local lcldata = luci.util.exec("logread -e 'unbound'")
+ local lcldesc = luci.i18n.translate(
+ "This shows syslog filtered for events involving Unbound.")
+
+ luci.template.render("unbound/show-textbox",
+ {heading = "", description = lcldesc, content = lcldata})
end
function QueryStatistics()
- local lclhead = "Unbound Control Stats"
- local lcldata = luci.util.exec("unbound-control -c /var/lib/unbound/unbound.conf stats_noreset")
- local lcldesc = luci.i18n.translate("This shows some performance statistics tracked by Unbound.")
- luci.template.render("unbound/show-textbox", {heading = lclhead, description = lcldesc, content = lcldata})
+ local lcldata = luci.util.exec(
+ "unbound-control -c /var/lib/unbound/unbound.conf stats_noreset")
+
+ local lcldesc = luci.i18n.translate(
+ "This shows Unbound self reported performance statistics.")
+
+ luci.template.render("unbound/show-textbox",
+ {heading = "", description = lcldesc, content = lcldata})
end
function QueryLocalData()
- local lclhead = "Unbound Control Local Data"
- local lcldata = luci.util.exec("unbound-control -c /var/lib/unbound/unbound.conf list_local_data")
- local lcldesc = luci.i18n.translate("This shows local host records that shortcut recursion.")
- luci.template.render("unbound/show-textbox", {heading = lclhead, description = lcldesc, content = lcldata})
+ local lcldata = luci.util.exec(
+ "unbound-control -c /var/lib/unbound/unbound.conf list_local_data")
+
+ local lcldesc = luci.i18n.translate(
+ "This shows Unbound 'local-data:' entries from default, .conf, or control.")
+
+ luci.template.render("unbound/show-textbox",
+ {heading = "", description = lcldesc, content = lcldata})
end
function QueryLocalZone()
- local lclhead = "Unbound Control Local Zones"
- local lcldata = luci.util.exec("unbound-control -c /var/lib/unbound/unbound.conf list_local_zones")
- local lcldesc = luci.i18n.translate("This shows local zone definitions that affect recursion routing or processing. ")
- luci.template.render("unbound/show-textbox", {heading = lclhead, description = lcldesc, content = lcldata})
+ local lcldata = luci.util.exec(
+ "unbound-control -c /var/lib/unbound/unbound.conf list_local_zones")
+
+ local lcldesc = luci.i18n.translate(
+ "This shows Unbound 'local-zone:' entries from default, .conf, or control.")
+
+ luci.template.render("unbound/show-textbox",
+ {heading = "", description = lcldesc, content = lcldata})
end
function ShowUnboundConf()
- local unboundfile = "/var/lib/unbound/unbound.conf"
- local lclhead = "Unbound Conf"
- local lcldata = nixio.fs.readfile(unboundfile)
- local lcldesc = luci.i18n.translate("This shows configuration generated by UCI:")
- lcldesc = lcldesc .. " (" .. unboundfile .. ")"
- luci.template.render("unbound/show-textbox", {heading = lclhead, description = lcldesc, content = lcldata})
+ local unboundfile = "/var/lib/unbound/unbound.conf"
+ local lcldata = nixio.fs.readfile(unboundfile)
+ local lcldesc = luci.i18n.translate(
+ "This shows '" .. unboundfile .. "' generated from UCI configuration.")
+
+ luci.template.render("unbound/show-textbox",
+ {heading = "", description = lcldesc, content = lcldata})
end
function ShowDHCPConf()
- local dhcpfile = "/var/lib/unbound/unbound_dhcp.conf"
- local lclhead = "DHCP Conf"
- local lcldata = nixio.fs.readfile(dhcpfile)
- local lcldesc = luci.i18n.translate("This shows LAN hosts added by DHCP hook scripts:")
- lcldesc = lcldesc .. " (" .. dhcpfile .. ")"
- luci.template.render("unbound/show-textbox", {heading = lclhead, description = lcldesc, content = lcldata})
+ local dhcpfile = "/var/lib/unbound/dhcp.conf"
+ local lcldata = nixio.fs.readfile(dhcpfile)
+ local lcldesc = luci.i18n.translate(
+ "This shows '" .. dhcpfile .. "' list of hosts from DHCP hook scripts.")
+
+ luci.template.render("unbound/show-textbox",
+ {heading = "", description = lcldesc, content = lcldata})
end
function ShowAdblock()
- local adblockfile = "/var/lib/unbound/adb_list.overall"
- local lclhead = "Adblock Conf"
- local lcldata, lcldesc
-
-
- if nixio.fs.stat(adblockfile).size > 262144 then
- lcldesc = luci.i18n.translate("Adblock domain list is too large for LuCI:")
- lcldesc = lcldesc .. " (" .. adblockfile .. ")"
- luci.template.render("unbound/show-empty", {heading = lclhead, description = lcldesc})
-
- else
- lcldata = nixio.fs.readfile(adblockfile)
- lcldesc = luci.i18n.translate("This shows blocked domains provided by Adblock scripts:")
- lcldesc = lcldesc .. " (" .. adblockfile .. ")"
- luci.template.render("unbound/show-textbox", {heading = lclhead, description = lcldesc, content = lcldata})
- end
+ local fs = require "nixio.fs"
+ local tp = require "luci.template"
+ local tr = require "luci.i18n"
+ local adblockfile = "/var/lib/unbound/adb_list.overall"
+ local lcldata, lcldesc
+
+
+ if fs.stat(adblockfile).size > 262144 then
+ lcldesc = tr.translate(
+ "Adblock domain list '" .. adblockfile .. "' is too large for LuCI.")
+
+ tp.render("unbound/show-empty",
+ {heading = "", description = lcldesc})
+
+ else
+ lcldata = fs.readfile(adblockfile)
+ lcldesc = tr.translate(
+ "This shows '" .. adblockfile .. "' list of adblock domains." )
+
+ tp.render("unbound/show-textbox",
+ {heading = "", description = lcldesc, content = lcldata})
+ end
end
-- Copyright 2008 Steven Barth <steven@midlink.org>
--- Copyright 2016 Eric Luehrsen <ericluehrsen@hotmail.com>
+-- Copyright 2016 Eric Luehrsen <ericluehrsen@gmail.com>
-- Copyright 2016 Dan Luedtke <mail@danrl.com>
-- Licensed to the public under the Apache License 2.0.
local ctl, dlk, dom, dty, lfq, wfq, exa
local dp6, d64, pfx, qry, qrs
local pro, tgr, rsc, rsn, ag2, stt
-local rpn, din, dfw, ath
+local rpn, din, ath
+
+local ut = require "luci.util"
+local sy = require "luci.sys"
+local ht = require "luci.http"
+local ds = require "luci.dispatcher"
local ucl = luci.model.uci.cursor()
local valman = ucl:get_first("unbound", "unbound", "manual_conf")
m1 = Map("unbound")
+s1 = m1:section(TypedSection, "unbound", translate("Recursive DNS"),
+ translatef("Unbound <a href=\"%s\" target=\"_blank\">(NLnet Labs)</a>"
+ .. " is a validating, recursive, and caching DNS resolver"
+ .. " <a href=\"%s\" target=\"_blank\">(help)</a>.",
+ "https://www.unbound.net/",
+ "https://github.com/openwrt/packages/blob/master/net/unbound/files/README.md"))
-s1 = m1:section(TypedSection, "unbound")
s1.addremove = false
s1.anonymous = true
--LuCI, Unbound, or Not
-s1:tab("basic", translate("Basic"),
- translatef("<h3>Unbound Basic Settings</h3>\n"
- .. "<a href=\"%s\" target=\"_blank\">Unbound (link)</a>"
- .. " is a validating, recursive, and caching DNS resolver. "
- .. "UCI documentation can be found on "
- .. "<a href=\"%s\" target=\"_blank\">github (link)</a>.",
- "https://www.unbound.net/",
- "https://github.com/openwrt/packages/blob/master/net/unbound/files/README.md"))
-
-
-if valman ~= "1" then
- -- Not in manual configuration mode; show UCI
- s1:tab("advanced", translate("Advanced"),
- translatef("<h3>Unbound Advanced Settings</h3>\n"
- .. "Domain manipulation, lookup protection, and workarounds for "
- .. "<a href=\"%s\" target=\"_blank\">Unbound </a>"
- .. " DNS resolver.", "https://www.unbound.net/"))
-
- s1:tab("DHCP", translate("DHCP"),
- translatef("<h3>Unbound DHCP Settings</h3>\n"
- .. "Link your DHCP server to "
- .. "<a href=\"%s\" target=\"_blank\">Unbound </a>"
- .. " DNS resolver.", "https://www.unbound.net/ "))
-
- s1:tab("resource", translate("Resource"),
- translatef("<h3>Unbound Resource Settings</h3>\n"
- .. "Memory and protocol setttings for "
- .. "<a href=\"%s\" target=\"_blank\">Unbound </a>"
- .. " DNS resolver.", "https://www.unbound.net/"))
-end
+s1:tab("basic", translate("Basic"))
-s1:tab("trigger", translate("Trigger"),
- translatef("<h3>Unbound Event Trigger Settings</h3>\n"
- .. "Start, reload, and save RFC5011 DNSKEY records for "
- .. "<a href=\"%s\" target=\"_blank\">Unbound </a>"
- .. " DNS resolver.", "https://www.unbound.net/"))
+if (valman == "0") then
+ -- Not in manual configuration mode; show UCI
+ s1:tab("advanced", translate("Advanced"))
+ s1:tab("DHCP", translate("DHCP"))
+ s1:tab("resource", translate("Resource"))
+end
--Basic Tab, unconditional pieces
-ena = s1:taboption("basic", Flag, "enabled", translate("Enable Unbound:"),
- translate("Enable the initialization scripts for Unbound"))
+ena = s1:taboption("basic", Flag, "enabled", translate("Enable Unbound"),
+ translate("Enable the initialization scripts for Unbound"))
ena.rmempty = false
-mcf = s1:taboption("basic", Flag, "manual_conf", translate("Manual Conf:"),
- translate("Skip UCI and use /etc/unbound/unbound.conf"))
+mcf = s1:taboption("basic", Flag, "manual_conf", translate("Manual Conf"),
+ translate("Skip UCI and use /etc/unbound/unbound.conf"))
mcf.rmempty = false
-lci = s1:taboption("basic", Flag, "extended_luci", translate("Extended Tabs:"),
- translate("See detailed tabs for statistics, debug, and manual configuration"))
-lci.rmempty = false
-
-
-if valman ~= "1" then
- -- Not in manual configuration mode; show UCI
- --Basic Tab
- lsv = s1:taboption("basic", Flag, "localservice", translate("Local Service:"),
- translate("Accept queries only from local subnets"))
- lsv.rmempty = false
-
- vld = s1:taboption("basic", Flag, "validator", translate("Enable DNSSEC:"),
- translate("Enable the DNSSEC validator module"))
- vld.rmempty = false
-
- nvd = s1:taboption("basic", Flag, "validator_ntp", translate("DNSSEC NTP Fix:"),
- translate("Break the loop where DNSSEC needs NTP and NTP needs DNS"))
- nvd.rmempty = false
- nvd:depends({ validator = true })
-
- d64 = s1:taboption("basic", Flag, "dns64", translate("Enable DNS64:"),
- translate("Enable the DNS64 module"))
- d64.rmempty = false
-
- pfx = s1:taboption("basic", Value, "dns64_prefix", translate("DNS64 Prefix:"),
- translate("Prefix for generated DNS64 addresses"))
- pfx.datatype = "ip6addr"
- pfx.placeholder = "64:ff9b::/96"
- pfx.optional = true
- pfx:depends({ dns64 = true })
-
- prt = s1:taboption("basic", Value, "listen_port", translate("Listening Port:"),
- translate("Choose Unbounds listening port"))
- prt.datatype = "port"
- prt.rmempty = false
-
- --Avanced Tab
- din = s1:taboption("advanced", DynamicList, "domain_insecure",
- translate("Domain Insecure:"),
- translate("List domains to bypass checks of DNSSEC"))
- din:depends({ validator = true })
-
- dfw = s1:taboption("advanced", DynamicList, "domain_forward",
- translate("Domain Forward:"),
- translate("List domains to simply forward to stub resolvers in /tmp/resolve.auto"))
-
- rlh = s1:taboption("advanced", Flag, "rebind_localhost", translate("Filter Localhost Rebind:"),
- translate("Protect against upstream response of 127.0.0.0/8"))
- rlh.rmempty = false
-
- rpv = s1:taboption("advanced", ListValue, "rebind_protection", translate("Filter Private Rebind:"),
- translate("Protect against upstream responses within local subnets"))
- rpv:value("0", translate("No Filter"))
- rpv:value("1", translate("Filter RFC1918/4193"))
- rpv:value("2", translate("Filter Entire Subnet"))
- rpv.rmempty = false
-
- rpn = s1:taboption("advanced", Value, "rebind_interface", translate("Rebind Network Filter:"),
- translate("Network subnets to filter from upstream responses"))
- rpn.template = "cbi/network_netlist"
- rpn.widget = "checkbox"
- rpn.rmempty = true
- rpn.cast = "string"
- rpn.nocreate = true
- rpn:depends({ rebind_protection = 2 })
- rpn:depends({ rebind_protection = 3 })
-
- --DHCP Tab
- dlk = s1:taboption("DHCP", ListValue, "dhcp_link", translate("DHCP Link:"),
- translate("Link to supported programs to load DHCP into DNS"))
- dlk:value("none", translate("No Link"))
- dlk:value("dnsmasq", "dnsmasq")
- dlk:value("odhcpd", "odhcpd")
- dlk.rmempty = false
-
- dp6 = s1:taboption("DHCP", Flag, "dhcp4_slaac6", translate("DHCPv4 to SLAAC:"),
- translate("Use DHCPv4 MAC to discover IP6 hosts SLAAC (EUI64)"))
- dp6.rmempty = false
- dp6:depends({ dhcp_link = "odhcpd" })
-
- dom = s1:taboption("DHCP", Value, "domain", translate("Local Domain:"),
- translate("Domain suffix for this router and DHCP clients"))
- dom.placeholder = "lan"
- dom:depends({ dhcp_link = "none" })
- dom:depends({ dhcp_link = "odhcpd" })
-
- dty = s1:taboption("DHCP", ListValue, "domain_type", translate("Local Domain Type:"),
- translate("How to treat queries of this local domain"))
- dty:value("deny", translate("Ignored"))
- dty:value("refuse", translate("Refused"))
- dty:value("static", translate("Only Local"))
- dty:value("transparent", translate("Also Forwarded"))
- dty:depends({ dhcp_link = "none" })
- dty:depends({ dhcp_link = "odhcpd" })
-
- lfq = s1:taboption("DHCP", ListValue, "add_local_fqdn", translate("LAN DNS:"),
- translate("How to enter the LAN or local network router in DNS"))
- lfq:value("0", translate("No Entry"))
- lfq:value("1", translate("Hostname, Primary Address"))
- lfq:value("2", translate("Hostname, All Addresses"))
- lfq:value("3", translate("Host FQDN, All Addresses"))
- lfq:value("4", translate("Interface FQDN, All Addresses"))
- lfq:depends({ dhcp_link = "none" })
- lfq:depends({ dhcp_link = "odhcpd" })
-
- wfq = s1:taboption("DHCP", ListValue, "add_wan_fqdn", translate("WAN DNS:"),
- translate("Override the WAN side router entry in DNS"))
- wfq:value("0", translate("Use Upstream"))
- wfq:value("1", translate("Hostname, Primary Address"))
- wfq:value("2", translate("Hostname, All Addresses"))
- wfq:value("3", translate("Host FQDN, All Addresses"))
- wfq:value("4", translate("Interface FQDN, All Addresses"))
- wfq:depends({ dhcp_link = "none" })
- wfq:depends({ dhcp_link = "odhcpd" })
-
- exa = s1:taboption("DHCP", ListValue, "add_extra_dns", translate("Extra DNS:"),
- translate("Use extra DNS entries found in /etc/config/dhcp"))
- exa:value("0", translate("Ignore"))
- exa:value("1", translate("Include Network/Hostnames"))
- exa:value("2", translate("Advanced MX/SRV RR"))
- exa:value("3", translate("Advanced CNAME RR"))
- exa:depends({ dhcp_link = "none" })
- exa:depends({ dhcp_link = "odhcpd" })
-
- --TODO: dnsmasq needs to not reference resolve-file and get off port 53.
-
- --Resource Tuning Tab
- ctl = s1:taboption("resource", ListValue, "unbound_control", translate("Unbound Control App:"),
- translate("Enable access for unbound-control"))
- ctl.rmempty = false
- ctl:value("0", translate("No Remote Control"))
- ctl:value("1", translate("Local Host, No Encryption"))
- ctl:value("2", translate("Local Host, Encrypted"))
- ctl:value("3", translate("Local Subnet, Encrypted"))
- ctl:value("4", translate("Local Subnet, Static Encryption"))
-
- pro = s1:taboption("resource", ListValue, "protocol", translate("Recursion Protocol:"),
- translate("Chose the protocol recursion queries leave on"))
- pro:value("default", translate("Default"))
- pro:value("ip4_only", translate("IP4 Only"))
- pro:value("ip6_only", translate("IP6 Only"))
- pro:value("ip6_prefer", translate("IP6 Preferred"))
- pro:value("mixed", translate("IP4 and IP6"))
- pro.rmempty = false
-
- rsc = s1:taboption("resource", ListValue, "resource", translate("Memory Resource:"),
- translate("Use menu System/Processes to observe any memory growth"))
- rsc:value("default", translate("Default"))
- rsc:value("tiny", translate("Tiny"))
- rsc:value("small", translate("Small"))
- rsc:value("medium", translate("Medium"))
- rsc:value("large", translate("Large"))
- rsc.rmempty = false
-
- rsn = s1:taboption("resource", ListValue, "recursion", translate("Recursion Strength:"),
- translate("Recursion activity affects memory growth and CPU load"))
- rsn:value("default", translate("Default"))
- rsn:value("passive", translate("Passive"))
- rsn:value("aggressive", translate("Aggressive"))
- rsn.rmempty = false
-
- qry = s1:taboption("resource", Flag, "query_minimize", translate("Query Minimize:"),
- translate("Break down query components for limited added privacy"))
- qry.rmempty = false
- qry:depends({ recursion = "passive" })
- qry:depends({ recursion = "aggressive" })
-
- qrs = s1:taboption("resource", Flag, "query_min_strict", translate("Strict Minimize:"),
- translate("Strict version of 'query minimize' but it can break DNS"))
- qrs.rmempty = false
- qrs:depends({ query_minimize = true })
-
- ath = s1:taboption("resource", Flag, "prefetch_root", translate("Prefetch Root:"),
- translate("Obtain complete root zone files and install in auth-zone: clause"))
- ath.rmempty = false
-
- eds = s1:taboption("resource", Value, "edns_size", translate("EDNS Size:"),
- translate("Limit extended DNS packet size"))
- eds.datatype = "and(uinteger,min(512),max(4096))"
- eds.rmempty = false
-
- tlm = s1:taboption("resource", Value, "ttl_min", translate("TTL Minimum:"),
- translate("Prevent excessively short cache periods"))
- tlm.datatype = "and(uinteger,min(0),max(600))"
- tlm.rmempty = false
-
- stt = s1:taboption("resource", Flag, "extended_stats", translate("Extended Statistics:"),
- translate("Extended statistics are printed from unbound-control"))
- stt.rmempty = false
-end
-
-
---Trigger Tab, always unconditional
-ag2 = s1:taboption("trigger", Value, "root_age", translate("Root DSKEY Age:"),
- translate("Limit days between RFC5011 copies to reduce flash writes"))
-ag2.datatype = "and(uinteger,min(1),max(99))"
-ag2:value("3", "3")
-ag2:value("9", "9 ("..translate("default")..")")
-ag2:value("12", "12")
-ag2:value("24", "24")
-ag2:value("99", "99 ("..translate("never")..")")
-tgr = s1:taboption("trigger", Value, "trigger_interface", translate("Trigger Networks:"),
- translate("Networks that may trigger Unbound to reload (avoid wan6)"))
-tgr.template = "cbi/network_netlist"
-tgr.widget = "checkbox"
-tgr.rmempty = true
-tgr.cast = "string"
-tgr.nocreate = true
+if (valman == "0") then
+ -- Not in manual configuration mode; show UCI
+ --Basic Tab
+ lsv = s1:taboption("basic", Flag, "localservice",
+ translate("Local Service"),
+ translate("Accept queries only from local subnets"))
+ lsv.rmempty = false
+
+ vld = s1:taboption("basic", Flag, "validator",
+ translate("Enable DNSSEC"),
+ translate("Enable the DNSSEC validator module"))
+ vld.rmempty = false
+
+ nvd = s1:taboption("basic", Flag, "validator_ntp",
+ translate("DNSSEC NTP Fix"),
+ translate("Break the loop where DNSSEC needs NTP and NTP needs DNS"))
+ nvd.optional = true
+ nvd:depends("validator", true)
+
+ prt = s1:taboption("basic", Value, "listen_port",
+ translate("Listening Port"),
+ translate("Choose Unbounds listening port"))
+ prt.datatype = "port"
+ prt.placeholder = "53"
+
+ --Avanced Tab
+ rlh = s1:taboption("advanced", Flag, "rebind_localhost",
+ translate("Filter Localhost Rebind"),
+ translate("Protect against upstream response of 127.0.0.0/8"))
+ rlh.rmempty = false
+
+ rpv = s1:taboption("advanced", ListValue, "rebind_protection",
+ translate("Filter Private Rebind"),
+ translate("Protect against upstream responses within local subnets"))
+ rpv:value("0", translate("No Filter"))
+ rpv:value("1", translate("Filter Private Address"))
+ rpv:value("2", translate("Filter Entire Subnet"))
+ rpv.rmempty = false
+
+ d64 = s1:taboption("advanced", Flag, "dns64", translate("Enable DNS64"),
+ translate("Enable the DNS64 module"))
+ d64.rmempty = false
+
+ pfx = s1:taboption("advanced", Value, "dns64_prefix",
+ translate("DNS64 Prefix"),
+ translate("Prefix for generated DNS64 addresses"))
+ pfx.datatype = "ip6addr"
+ pfx.placeholder = "64:ff9b::/96"
+ pfx.optional = true
+ pfx:depends("dns64", true)
+
+ din = s1:taboption("advanced", DynamicList, "domain_insecure",
+ translate("Domain Insecure"),
+ translate("List domains to bypass checks of DNSSEC"))
+ din:depends("validator", true)
+
+ ag2 = s1:taboption("advanced", Value, "root_age",
+ translate("Root DSKEY Age"),
+ translate("Limit days between RFC5011 copies to reduce flash writes"))
+ ag2.datatype = "and(uinteger,min(1),max(99))"
+ ag2:value("3", "3")
+ ag2:value("9", "9 ("..translate("default")..")")
+ ag2:value("12", "12")
+ ag2:value("24", "24")
+ ag2:value("99", "99 ("..translate("never")..")")
+
+ tgr = s1:taboption("advanced", Value, "trigger_interface",
+ translate("Trigger Networks"),
+ translate("Networks that may trigger Unbound to reload (avoid wan6)"))
+ tgr.template = "cbi/network_netlist"
+ tgr.widget = "checkbox"
+ tgr.rmempty = true
+ tgr.cast = "string"
+ tgr.nocreate = true
+
+ --DHCP Tab
+ dlk = s1:taboption("DHCP", ListValue, "dhcp_link",
+ translate("DHCP Link"),
+ translate("Link to supported programs to load DHCP into DNS"))
+ dlk:value("none", translate("No Link"))
+ dlk:value("dnsmasq", "dnsmasq")
+ dlk:value("odhcpd", "odhcpd")
+ dlk.rmempty = false
+
+ dp6 = s1:taboption("DHCP", Flag, "dhcp4_slaac6",
+ translate("DHCPv4 to SLAAC"),
+ translate("Use DHCPv4 MAC to discover IP6 hosts SLAAC (EUI64)"))
+ dp6.optional = true
+ dp6:depends("dhcp_link", "odhcpd")
+
+ dom = s1:taboption("DHCP", Value, "domain",
+ translate("Local Domain"),
+ translate("Domain suffix for this router and DHCP clients"))
+ dom.placeholder = "lan"
+ dom.optional = true
+ dom:depends("dhcp_link", "none")
+ dom:depends("dhcp_link", "odhcpd")
+
+ dty = s1:taboption("DHCP", ListValue, "domain_type",
+ translate("Local Domain Type"),
+ translate("How to treat queries of this local domain"))
+ dty.optional = true
+ dty:value("deny", translate("Denied (nxdomain)"))
+ dty:value("refuse", translate("Refused"))
+ dty:value("static", translate("Static (local only)"))
+ dty:value("transparent", translate("Transparent (local/global)"))
+ dty:depends("dhcp_link", "none")
+ dty:depends("dhcp_link", "odhcpd")
+
+ lfq = s1:taboption("DHCP", ListValue, "add_local_fqdn",
+ translate("LAN DNS"),
+ translate("How to enter the LAN or local network router in DNS"))
+ lfq.optional = true
+ lfq:value("0", translate("No Entry"))
+ lfq:value("1", translate("Hostname, Primary Address"))
+ lfq:value("2", translate("Hostname, All Addresses"))
+ lfq:value("3", translate("Host FQDN, All Addresses"))
+ lfq:value("4", translate("Interface FQDN, All Addresses"))
+ lfq:depends("dhcp_link", "none")
+ lfq:depends("dhcp_link", "odhcpd")
+
+ wfq = s1:taboption("DHCP", ListValue, "add_wan_fqdn",
+ translate("WAN DNS"),
+ translate("Override the WAN side router entry in DNS"))
+ wfq.optional = true
+ wfq:value("0", translate("Use Upstream"))
+ wfq:value("1", translate("Hostname, Primary Address"))
+ wfq:value("2", translate("Hostname, All Addresses"))
+ wfq:value("3", translate("Host FQDN, All Addresses"))
+ wfq:value("4", translate("Interface FQDN, All Addresses"))
+ wfq:depends("dhcp_link", "none")
+ wfq:depends("dhcp_link", "odhcpd")
+
+ exa = s1:taboption("DHCP", ListValue, "add_extra_dns",
+ translate("Extra DNS"),
+ translate("Use extra DNS entries found in /etc/config/dhcp"))
+ exa.optional = true
+ exa:value("0", translate("Ignore"))
+ exa:value("1", translate("Host Records"))
+ exa:value("2", translate("Host/MX/SRV RR"))
+ exa:value("3", translate("Host/MX/SRV/CNAME RR"))
+ exa:depends("dhcp_link", "none")
+ exa:depends("dhcp_link", "odhcpd")
+
+ --TODO: dnsmasq needs to not reference resolve-file and get off port 53.
+
+ --Resource Tuning Tab
+ ctl = s1:taboption("resource", ListValue, "unbound_control",
+ translate("Unbound Control App"),
+ translate("Enable access for unbound-control"))
+ ctl.rmempty = false
+ ctl:value("0", translate("No Remote Control"))
+ ctl:value("1", translate("Local Host, No Encryption"))
+ ctl:value("2", translate("Local Host, Encrypted"))
+ ctl:value("3", translate("Local Subnet, Encrypted"))
+ ctl:value("4", translate("Local Subnet, Static Encryption"))
+
+ pro = s1:taboption("resource", ListValue, "protocol",
+ translate("Recursion Protocol"),
+ translate("Chose the protocol recursion queries leave on"))
+ pro:value("default", translate("Default"))
+ pro:value("ip4_only", translate("IP4 Only"))
+ pro:value("ip6_only", translate("IP6 Only"))
+ pro:value("ip6_prefer", translate("IP6 Preferred"))
+ pro:value("mixed", translate("IP4 and IP6"))
+ pro.rmempty = false
+
+ rsc = s1:taboption("resource", ListValue, "resource",
+ translate("Memory Resource"),
+ translate("Use menu System/Processes to observe any memory growth"))
+ rsc:value("default", translate("Default"))
+ rsc:value("tiny", translate("Tiny"))
+ rsc:value("small", translate("Small"))
+ rsc:value("medium", translate("Medium"))
+ rsc:value("large", translate("Large"))
+ rsc.rmempty = false
+
+ rsn = s1:taboption("resource", ListValue, "recursion",
+ translate("Recursion Strength"),
+ translate("Recursion activity affects memory growth and CPU load"))
+ rsn:value("default", translate("Default"))
+ rsn:value("passive", translate("Passive"))
+ rsn:value("aggressive", translate("Aggressive"))
+ rsn.rmempty = false
+
+ qry = s1:taboption("resource", Flag, "query_minimize",
+ translate("Query Minimize"),
+ translate("Break down query components for limited added privacy"))
+ qry.optional = true
+ qry:depends("recursion", "passive")
+ qry:depends("recursion", "aggressive")
+
+ qrs = s1:taboption("resource", Flag, "query_min_strict",
+ translate("Strict Minimize"),
+ translate("Strict version of 'query minimize' but it can break DNS"))
+ qrs.optional = true
+ qrs:depends("query_minimize", true)
+
+ eds = s1:taboption("resource", Value, "edns_size",
+ translate("EDNS Size:"),
+ translate("Limit extended DNS packet size"))
+ eds.datatype = "and(uinteger,min(512),max(4096))"
+ eds.placeholder = "1280"
+
+ tlm = s1:taboption("resource", Value, "ttl_min",
+ translate("TTL Minimum"),
+ translate("Prevent excessively short cache periods"))
+ tlm.datatype = "and(uinteger,min(0),max(1200))"
+ tlm.placeholder = "120"
+
+ stt = s1:taboption("resource", Flag, "extended_stats",
+ translate("Extended Statistics"),
+ translate("Extended statistics are printed from unbound-control"))
+ stt.rmempty = false
+
+else
+ ag2 = s1:taboption("basic", Value, "root_age",
+ translate("Root DSKEY Age"),
+ translate("Limit days between RFC5011 copies to reduce flash writes"))
+ ag2.datatype = "and(uinteger,min(1),max(99))"
+ ag2:value("3", "3")
+ ag2:value("9", "9 ("..translate("default")..")")
+ ag2:value("12", "12")
+ ag2:value("24", "24")
+ ag2:value("99", "99 ("..translate("never")..")")
+
+ tgr = s1:taboption("basic", Value, "trigger_interface",
+ translate("Trigger Networks"),
+ translate("Networks that may trigger Unbound to reload (avoid wan6)"))
+ tgr.template = "cbi/network_netlist"
+ tgr.widget = "checkbox"
+ tgr.rmempty = true
+ tgr.cast = "string"
+ tgr.nocreate = true
+end
function ena.cfgvalue(self, section)
- return luci.sys.init.enabled("unbound") and self.enabled or self.disabled
+ return sy.init.enabled("unbound") and self.enabled or self.disabled
end
function ena.write(self, section, value)
- if value == "1" then
- luci.sys.init.enable("unbound")
- luci.sys.call("/etc/init.d/unbound start >/dev/null")
- else
- luci.sys.call("/etc/init.d/unbound stop >/dev/null")
- luci.sys.init.disable("unbound")
- end
-
- return Flag.write(self, section, value)
+ if (value == "1") then
+ sy.init.enable("unbound")
+ sy.call("/etc/init.d/unbound start >/dev/null 2>&1")
+
+ else
+ sy.call("/etc/init.d/unbound stop >/dev/null 2>&1")
+ sy.init.disable("unbound")
+ end
+
+
+ return Flag.write(self, section, value)
end
-function m1.on_apply(self)
- function ena.validate(self, value)
- if value ~= "0" then
- luci.sys.call("/etc/init.d/unbound restart >/dev/null 2>&1")
+function m1.on_commit(self)
+ if sy.init.enabled("unbound") then
+ -- Restart Unbound with configuration
+ sy.call("/etc/init.d/unbound restart >/dev/null 2>&1")
+
else
- luci.sys.call("/etc/init.d/unbound stop >/dev/null 2>&1")
+ sy.call("/etc/init.d/unbound stop >/dev/null 2>&1")
end
- end
+end
- -- Restart Unbound with configuration and reload the page (some options hide)
- luci.http.redirect(luci.dispatcher.build_url("admin", "services", "unbound"))
+function m1.on_apply(self)
+ -- reload the page because some options hide
+ ht.redirect(ds.build_url("admin", "services", "unbound", "configure"))
end
--- Copyright 2016 Eric Luehrsen <ericluehrsen@hotmail.com>
+-- Copyright 2016 Eric Luehrsen <ericluehrsen@gmail.com>
-- Licensed to the public under the Apache License 2.0.
local m4, s4, frm
local filename = "/etc/unbound/unbound_ext.conf"
-local description = translatef("Here you may edit 'forward:' and 'remote-control:' in an extended 'include:'")
-description = description .. " (" .. filename .. ")"
+local fs = require "nixio.fs"
+local ut = require "luci.util"
m4 = SimpleForm("editing", nil)
m4:append(Template("unbound/css-editing"))
m4.submit = translate("Save")
m4.reset = false
-s4 = m4:section(SimpleSection, "Unbound Extended Conf", description)
+s4 = m4:section(SimpleSection, "",
+ translatef(
+ "Edit clauses such as 'forward-zone:' for 'include: " .. filename .. "'"))
+
frm = s4:option(TextValue, "data")
frm.datatype = "string"
frm.rows = 20
function frm.cfgvalue()
- return nixio.fs.readfile(filename) or ""
+ return fs.readfile(filename) or ""
end
function frm.write(self, section, data)
- return nixio.fs.writefile(filename, luci.util.trim(data:gsub("\r\n", "\n")))
+ return fs.writefile(filename, ut.trim(data:gsub("\r\n", "\n")))
end
--- Copyright 2016 Eric Luehrsen <ericluehrsen@hotmail.com>
+-- Copyright 2016 Eric Luehrsen <ericluehrsen@gmail.com>
-- Licensed to the public under the Apache License 2.0.
local m2, s2, frm
local filename = "/etc/unbound/unbound.conf"
-local description = translatef("Here you may edit raw 'unbound.conf' when you don't use UCI:")
-description = description .. " (" .. filename .. ")"
+local fs = require "nixio.fs"
+local ut = require "luci.util"
m2 = SimpleForm("editing", nil)
m2:append(Template("unbound/css-editing"))
m2.submit = translate("Save")
m2.reset = false
-s2 = m2:section(SimpleSection, "Unbound Conf", description)
+s2 = m2:section(SimpleSection, "",
+ translatef(
+ "Edit '" .. filename .. "' when you do not use UCI."))
+
frm = s2:option(TextValue, "data")
frm.datatype = "string"
frm.rows = 20
function frm.cfgvalue()
- return nixio.fs.readfile(filename) or ""
+ return fs.readfile(filename) or ""
end
function frm.write(self, section, data)
- return nixio.fs.writefile(filename, luci.util.trim(data:gsub("\r\n", "\n")))
+ return fs.writefile(filename, ut.trim(data:gsub("\r\n", "\n")))
end
--- Copyright 2016 Eric Luehrsen <ericluehrsen@hotmail.com>
+-- Copyright 2016 Eric Luehrsen <ericluehrsen@gmail.com>
-- Licensed to the public under the Apache License 2.0.
local m3, s3, frm
local filename = "/etc/unbound/unbound_srv.conf"
-local description = translatef("Here you may edit the 'server:' clause in an internal 'include:'")
-description = description .. " (" .. filename .. ")"
+local fs = require "nixio.fs"
+local ut = require "luci.util"
m3 = SimpleForm("editing", nil)
m3:append(Template("unbound/css-editing"))
m3.submit = translate("Save")
m3.reset = false
-s3 = m3:section(SimpleSection, "Unbound Server Conf", description)
+s3 = m3:section(SimpleSection, "",
+ translatef(
+ "Edit 'server:' clause options for 'include: " .. filename .. "'"))
+
frm = s3:option(TextValue, "data")
frm.datatype = "string"
frm.rows = 20
function frm.cfgvalue()
- return nixio.fs.readfile(filename) or ""
+ return fs.readfile(filename) or ""
end
function frm.write(self, section, data)
- return nixio.fs.writefile(filename, luci.util.trim(data:gsub("\r\n", "\n")))
+ return fs.writefile(filename, ut.trim(data:gsub("\r\n", "\n")))
end
--- /dev/null
+-- Copyright 2016 Eric Luehrsen <ericluehrsen@gmail.com>
+-- Licensed to the public under the Apache License 2.0.
+
+local m6, s6, frm
+local filename = "/etc/config/unbound"
+local fs = require "nixio.fs"
+local ut = require "luci.util"
+
+m6 = SimpleForm("editing", nil)
+m6:append(Template("unbound/css-editing"))
+m6.submit = translate("Save")
+m6.reset = false
+s6 = m6:section(SimpleSection, "",
+ translatef("Edit '" .. filename .. "' "
+ .. "and recipes can be found in OpenWrt "
+ .. "<a href=\"%s\" target=\"_blank\">Guides</a> "
+ .. "and <a href=\"%s\" target=\"_blank\">Github</a>.",
+ "https://openwrt.org/docs/guide-user/services/dns/unbound",
+ "https://github.com/openwrt/packages/blob/master/net/unbound/files/README.md"))
+
+frm = s6:option(TextValue, "data")
+frm.datatype = "string"
+frm.rows = 20
+
+
+function frm.cfgvalue()
+ return fs.readfile(filename) or ""
+end
+
+
+function frm.write(self, section, data)
+ return fs.writefile(filename, ut.trim(data:gsub("\r\n", "\n")))
+end
+
+
+return m6
+
--- /dev/null
+-- Copyright 2018 Eric Luehrsen <ericluehrsen@gmail.com>
+-- Licensed to the public under the Apache License 2.0.
+
+local sy = require "luci.sys"
+local ds = require "luci.dispatcher"
+local hp = require "luci.http"
+local m7, s7
+local ena, flb, zty, znm, srv, rlv, tlu
+local prt, tlp, tli, url
+
+arg[1] = arg[1] or ""
+m7 = Map("unbound")
+m7.redirect = ds.build_url("admin/services/unbound/zones")
+
+
+if (arg[1] == "") then
+ hp.redirect(m7.redirect)
+ return
+
+else
+ s7 = m7:section(NamedSection, arg[1], "zone",
+ translatef("Directed Zone"),
+ translatef("Edit a forward, stub, or zone-file-cache zone "
+ .. "for Unbound to use instead of recursion."))
+
+ s7.anonymous = true
+ s7.addremove = false
+
+ ena = s7:option(Flag, "enabled", translate("Enabled"),
+ translate("Enable this directed zone"))
+ ena.rmempty = false
+
+ flb = s7:option(Flag, "fallback", translate("Fall Back"),
+ translate("Allow open recursion when record not in zone"))
+ flb.rmempty = false
+
+ zty = s7:option(ListValue, "zone_type", translate("Zone Type"))
+ zty:value("auth_zone", translate("Authoritative (zone file)"))
+ zty:value("stub_zone", translate("Stub (forced recursion)"))
+ zty:value("forward_zone", translate("Forward (simple handoff)"))
+ zty.rmempty = false
+
+ znm = s7:option(DynamicList, "zone_name", translate("Zone Names"),
+ translate("Zone (Domain) names included in this zone combination"))
+ znm.placeholder="new.example.net."
+
+ srv = s7:option(DynamicList, "server", translate("Servers"),
+ translate("Servers for this zone; see README.md for optional form"))
+ srv.placeholder="192.0.2.53"
+
+ rlv = s7:option(Flag, "resolv_conf", translate("Use 'resolv.conf.auto'"),
+ translate("Forward to upstream nameservers (ISP)"))
+ rlv:depends("zone_type", "forward_zone")
+
+ tlu = s7:option(Flag, "tls_upstream", translate("DNS over TLS"),
+ translate("Connect to servers using TLS"))
+ tlu:depends("zone_type", "forward_zone")
+
+ prt = s7:option(Value, "port", translate("Server Port"),
+ translate("Port servers will receive queries on"))
+ prt:depends("tls_upstream", false)
+ prt.datatype = "port"
+ prt.placeholder="53"
+
+ tlp = s7:option(Value, "tls_port", translate("Server TLS Port"),
+ translate("Port servers will receive queries on"))
+ tlp:depends("tls_upstream", true)
+ tlp.datatype = "port"
+ tlp.placeholder="853"
+
+ tli = s7:option(Value, "tls_index", translate("TLS Name Index"),
+ translate("Domain name to verify TLS certificate"))
+ tli:depends("tls_upstream", true)
+ tli.placeholder="dns.example.net"
+
+ url = s7:option(Value, "url_dir", translate("Zone Download URL"),
+ translate("Directory only part of URL"))
+ url:depends("zone_type", "auth_zone")
+ url.placeholder="https://www.example.net/dl/zones/"
+end
+
+
+function m7.on_commit(self)
+ if sy.init.enabled("unbound") then
+ -- Restart Unbound with configuration
+ sy.call("/etc/init.d/unbound restart >/dev/null 2>&1")
+
+ else
+ sy.call("/etc/init.d/unbound stop >/dev/null 2>&1")
+ end
+end
+
+
+return m7
+
--- /dev/null
+-- Copyright 2018 Eric Luehrsen <ericluehrsen@gmail.com>
+-- Licensed to the public under the Apache License 2.0.
+
+local m5, s5
+local ztype, zones, servers, fallback, enabled
+
+local fs = require "nixio.fs"
+local ut = require "luci.util"
+local sy = require "luci.sys"
+local ds = require "luci.dispatcher"
+local resolvfile = "/tmp/resolv.conf.auto"
+local logerr = ut.exec("logread -e 'unbound.*error.*ssl library'")
+
+m5 = Map("unbound")
+s5 = m5:section(TypedSection, "zone", "Zones",
+ translatef("Organize directed forward, stub, and authoritative zones"
+ .. " <a href=\"%s\" target=\"_blank\">(help)</a>.",
+ "https://www.unbound.net/",
+ "https://github.com/openwrt/packages/blob/master/net/unbound/files/README.md"))
+
+s5.addremove = true
+s5.anonymous = true
+s5.sortable = true
+s5.template = "cbi/tblsection"
+s5.extedit = ds.build_url("admin/services/unbound/zones/%s")
+
+ztype = s5:option(DummyValue, "DummyType", translate("Type"))
+ztype.rawhtml = true
+
+zones = s5:option(DummyValue, "DummyZones", translate("Zones"))
+zones.rawhtml = true
+
+servers = s5:option(DummyValue, "DummyServers", translate("Servers"))
+servers.rawhtml = true
+
+fallback = s5:option(Flag, "fallback", translate("Fallback"))
+fallback.rmempty = false
+
+enabled = s5:option(Flag, "enabled", translate("Enable"))
+enabled.rmempty = false
+
+
+if logerr and (#logerr > 0) then
+ logerr = logerr:sub((1 + #logerr - math.min(#logerr, 250)), #logerr)
+ m5.message = translatef( "Note: SSL/TLS library is missing an API. "
+ .. "Please review syslog. >> logread ... " .. logerr )
+end
+
+
+function s5.create(self, section)
+ created = TypedSection.create(self, section)
+end
+
+
+function s5.parse(self, ...)
+ TypedSection.parse(self, ...)
+end
+
+
+function ztype.cfgvalue(self, s)
+ -- Format a meaninful tile for the Zone Type column
+ local itxt = self.map:get(s, "zone_type")
+ local itls = self.map:get(s, "tls_upstream")
+
+
+ if itxt and itxt:match("forward") then
+ if itls and (itls == "1") then
+ return translate("Forward TLS")
+
+ else
+ return translate("Forward")
+ end
+
+ elseif itxt and itxt:match("stub") then
+ return translate("Recurse")
+
+ elseif itxt and itxt:match("auth") then
+ return translate("AXFR")
+
+ else
+ return translate("Undefined")
+ end
+end
+
+
+function zones.cfgvalue(self, s)
+ -- Format a meaninful sentence for the Zones viewed column
+ local xtxt, otxt
+ local itxt = self.map:get(s, "zone_name")
+ local itype = self.map:get(s, "zone_type")
+
+
+ for xtxt in ut.imatch(itxt) do
+ if (xtxt == ".") then
+ -- zone_name lists
+ xtxt = translate("(root)")
+ end
+
+
+ if otxt and (#otxt > 0) then
+ otxt = otxt .. ", <var>%s</var>" % xtxt
+
+ else
+ otxt = "<var>%s</var>" % xtxt
+ end
+ end
+
+
+ if otxt and (#otxt > 0) then
+ if itype and itype:match("forward") then
+ -- from zone_type create a readable hint for the action
+ otxt = translate("accept upstream results for ") .. otxt
+
+ elseif itype and itype:match("stub") then
+ otxt = translate("select recursion for ") .. otxt
+
+ elseif itype and itype:match("auth") then
+ otxt = translate("prefetch zone files for ") .. otxt
+
+ else
+ otxt = translate("unknown action for ") .. otxt
+ end
+
+
+ return otxt
+
+ else
+ return "(empty)"
+ end
+end
+
+
+function servers.cfgvalue(self, s)
+ -- Format a meaninful sentence for the Servers (and URL) column
+ local xtxt, otxt, rtxt, found
+ local itxt = self.map:get(s, "server")
+ local iurl = self.map:get(s, "url_dir")
+ local itype = self.map:get(s, "zone_type")
+ local itls = self.map:get(s, "tls_upstream")
+ local iidx = self.map:get(s, "tls_index")
+ local irslv = self.map:get(s, "resolv_conf")
+
+
+ for xtxt in ut.imatch(itxt) do
+ if otxt and (#otxt > 0) then
+ -- bundle and make pretty the server list
+ otxt = otxt .. ", <var>%s</var>" % xtxt
+
+ else
+ otxt = "<var>%s</var>" % xtxt
+ end
+ end
+
+
+ if otxt and (#otxt > 0) then
+ otxt = translate("use nameservers ") .. otxt
+ end
+
+
+ if otxt and (#otxt > 0)
+ and itls and (itls == "1")
+ and iidx and (#iidx > 0) then
+ -- show TLS certificate name index if provided
+ otxt = otxt .. translatef(
+ " with default certificate for <var>%s</var>", iidx)
+ end
+
+
+ if iurl and (#iurl > 0) and itype and itype:match("auth") then
+ if otxt and (#otxt > 0) then
+ -- include optional URL filed for auth-zone: type
+ otxt = otxt .. translatef(", and try <var>%s</var>", iurl)
+
+ else
+ otxt = translatef("download from <var>%s</var>", iurl)
+ end
+ end
+
+
+ if irslv and (irslv == "1") and itype and itype:match("forward") then
+ for xtxt in ut.imatch(fs.readfile(resolvfile)) do
+ if xtxt:match("nameserver") then
+ found = true
+
+ elseif (found == true) then
+ if rtxt and (#rtxt > 0) then
+ -- fetch name servers from resolv.conf
+ rtxt = rtxt .. ", <var>%s</var>" % xtxt
+
+ else
+ rtxt = "<var>%s</var>" % xtxt
+ end
+
+
+ found = false
+ end
+ end
+
+
+ if otxt and (#otxt > 0) and rtxt and (#rtxt > 0) then
+ otxt = otxt .. translatef(
+ ", and <var>%s</var> entries ", resolvfile) .. rtxt
+
+ elseif rtxt and (#rtxt > 0) then
+ otxt = translatef(
+ "use <var>%s</var> nameservers ", resolvfile) .. rtxt
+ end
+ end
+
+
+ if otxt and (#otxt > 0) then
+ return otxt
+
+ else
+ return "(empty)"
+ end
+end
+
+
+function m5.on_commit(self)
+ if sy.init.enabled("unbound") then
+ -- Restart Unbound with configuration
+ sy.call("/etc/init.d/unbound restart >/dev/null 2>&1")
+
+ else
+ sy.call("/etc/init.d/unbound stop >/dev/null 2>&1")
+ end
+end
+
+
+return m5
+
if not wdgtime or ( systime - wdgtime ) > ( intv * 2 ) then
os.execute("logger -t 'OLSR watchdog' 'Process died - restarting!'")
+ local tnls = io.popen("ip tunnel show | cut -d : -f 1")
+ while true do
+ tnl = tnls:read("*line")
+ if tnl == nil then break end
+ if string.find(tnl, "tnl_") == 1 then
+ os.execute(string.format("logger -t 'OLSR watchdog' 'Deleting stale tunnel %s'", tnl))
+ os.execute(string.format("ip link del %s", tnl))
+ end
+ end
os.execute("/etc/init.d/olsrd restart")
end
end
define SrcDiet
$(FIND) $(1) -type f -name '*.lua' | while read src; do \
- if luasrcdiet --noopt-binequiv -o "$$$$src.o" "$$$$src"; \
+ if LUA_PATH="$(STAGING_DIR_HOSTPKG)/lib/lua/5.1/?.lua" luasrcdiet --noopt-binequiv -o "$$$$src.o" "$$$$src"; \
then mv "$$$$src.o" "$$$$src"; fi; \
done
endef
define Host/Compile
$(MAKE) -C src/ clean po2lmo
- $(MAKE) -C $(HOST_BUILD_DIR) bin/luasrcdiet
endef
define Host/Install
$(INSTALL_DIR) $(1)/bin
+ $(INSTALL_DIR) $(1)/lib/lua/5.1
$(INSTALL_BIN) src/po2lmo $(1)/bin/po2lmo
$(INSTALL_BIN) $(HOST_BUILD_DIR)/bin/luasrcdiet $(1)/bin/luasrcdiet
+ $(CP) $(HOST_BUILD_DIR)/luasrcdiet $(1)/lib/lua/5.1/
endef
$(eval $(call HostBuild))
if (xhr.readyState == 4) {
var json = null;
if (xhr.getResponseHeader("Content-Type") == "application/json") {
- try {
- json = JSON.parse(xhr.responseText);
- }
- catch(e) {
- json = null;
- }
+ try { json = JSON.parse(xhr.responseText); }
+ catch(e) { json = null; }
}
callback(xhr, json, Date.now() - ts);
xhr.onreadystatechange = function()
{
- if (xhr.readyState == 4)
- callback(xhr, null, Date.now() - ts);
+ if (xhr.readyState == 4) {
+ var json = null;
+ if (xhr.getResponseHeader("Content-Type") == "application/json") {
+ try { json = JSON.parse(xhr.responseText); }
+ catch(e) { json = null; }
+ }
+
+ callback(xhr, json, Date.now() - ts);
+ }
}
xhr.open('POST', url, true);
local pageaction = true
local parsechain = { }
- local is_rollback, time_remaining = uci:rollback_pending()
-
for i, res in ipairs(maps) do
if res.apply_needed and res.parsechain then
local c
for i, res in ipairs(maps) do
res:render({
firstmap = (i == 1),
- applymap = applymap,
- confirmmap = (is_rollback and time_remaining or nil),
redirect = redirect,
messages = messages,
pageaction = pageaction,
if not config.nofooter then
tpl.render("cbi/footer", {
- flow = config,
- pageaction = pageaction,
- redirect = redirect,
- state = state,
- autoapply = config.autoapply
+ flow = config,
+ pageaction = pageaction,
+ redirect = redirect,
+ state = state,
+ autoapply = config.autoapply,
+ trigger_apply = applymap
})
end
end
function changes(self, config)
- local rv = call("changes", { config = config })
- local res = {}
+ local rv, err = call("changes", { config = config })
if type(rv) == "table" and type(rv.changes) == "table" then
- local package, changes
- for package, changes in pairs(rv.changes) do
- res[package] = {}
-
- local _, change
- for _, change in ipairs(changes) do
- local operation, section, option, value = unpack(change)
- if option and operation ~= "add" then
- res[package][section] = res[package][section] or { }
-
- if operation == "list-add" then
- local v = res[package][section][option]
- if type(v) == "table" then
- v[#v+1] = value or ""
- elseif v ~= nil then
- res[package][section][option] = { v, value }
- else
- res[package][section][option] = { value }
- end
- else
- res[package][section][option] = value or ""
- end
- else
- res[package][section] = res[package][section] or {}
- res[package][section][".type"] = option or ""
- end
- end
- end
+ return rv.changes
+ elseif err then
+ return nil, ERRSTR[err]
+ else
+ return { }
end
-
- return res
end
local _, err
if rollback then
+ local sys = require "luci.sys"
local conf = require "luci.config"
- local timeout = tonumber(conf and conf.apply and conf.apply.rollback or "") or 0
+ local timeout = tonumber(conf and conf.apply and conf.apply.rollback or 30) or 0
_, err = call("apply", {
- timeout = (timeout > 30) and timeout or 30,
+ timeout = (timeout > 30) and timeout or 30,
rollback = true
})
if not err then
+ local now = os.time()
+ local token = sys.uniqueid(16)
+
util.ubus("session", "set", {
- ubus_rpc_session = session_id,
- values = { rollback = os.time() + timeout }
+ ubus_rpc_session = "00000000000000000000000000000000",
+ values = {
+ rollback = {
+ token = token,
+ session = session_id,
+ timeout = now + timeout
+ }
+ }
})
+
+ return token
end
else
_, err = call("changes", {})
return (err == nil), ERRSTR[err]
end
-function confirm(self)
- local _, err = call("confirm", {})
- if not err then
- util.ubus("session", "set", {
- ubus_rpc_session = session_id,
- values = { rollback = 0 }
+function confirm(self, token)
+ local is_pending, time_remaining, rollback_sid, rollback_token = self:rollback_pending()
+
+ if is_pending then
+ if token ~= rollback_token then
+ return false, "Permission denied"
+ end
+
+ local _, err = util.ubus("uci", "confirm", {
+ ubus_rpc_session = rollback_sid
})
+
+ if not err then
+ util.ubus("session", "set", {
+ ubus_rpc_session = "00000000000000000000000000000000",
+ values = { rollback = {} }
+ })
+ end
+
+ return (err == nil), ERRSTR[err]
end
- return (err == nil), ERRSTR[err]
+
+ return false, "No data"
end
function rollback(self)
- local _, err = call("rollback", {})
- if not err then
- util.ubus("session", "set", {
- ubus_rpc_session = session_id,
- values = { rollback = 0 }
+ local is_pending, time_remaining, rollback_sid = self:rollback_pending()
+
+ if is_pending then
+ local _, err = util.ubus("uci", "rollback", {
+ ubus_rpc_session = rollback_sid
})
+
+ if not err then
+ util.ubus("session", "set", {
+ ubus_rpc_session = "00000000000000000000000000000000",
+ values = { rollback = {} }
+ })
+ end
+
+ return (err == nil), ERRSTR[err]
end
- return (err == nil), ERRSTR[err]
+
+ return false, "No data"
end
function rollback_pending(self)
- local deadline, err = util.ubus("session", "get", {
- ubus_rpc_session = session_id,
+ local rv, err = util.ubus("session", "get", {
+ ubus_rpc_session = "00000000000000000000000000000000",
keys = { "rollback" }
})
- if type(deadline) == "table" and
- type(deadline.values) == "table" and
- type(deadline.values.rollback) == "number" and
- deadline.values.rollback > os.time()
+ local now = os.time()
+
+ if type(rv) == "table" and
+ type(rv.values) == "table" and
+ type(rv.values.rollback) == "table" and
+ type(rv.values.rollback.token) == "string" and
+ type(rv.values.rollback.session) == "string" and
+ type(rv.values.rollback.timeout) == "number" and
+ rv.values.rollback.timeout > now
then
- return true, deadline.values.rollback - os.time()
+ return true,
+ rv.values.rollback.timeout - now,
+ rv.values.rollback.session,
+ rv.values.rollback.token
end
return false, ERRSTR[err]
local _ubus_connection = nil
local getmetatable, setmetatable = getmetatable, setmetatable
-local rawget, rawset, unpack = rawget, rawset, unpack
+local rawget, rawset, unpack, select = rawget, rawset, unpack, select
local tostring, type, assert, error = tostring, type, assert, error
local ipairs, pairs, next, loadstring = ipairs, pairs, next, loadstring
local require, pcall, xpcall = require, pcall, xpcall
"CONNECTION_FAILED"
}
+local function ubus_return(...)
+ if select('#', ...) == 2 then
+ local rv, err = select(1, ...), select(2, ...)
+ if rv == nil and type(err) == "number" then
+ return nil, err, ubus_codes[err]
+ end
+ end
+
+ return ...
+end
+
function ubus(object, method, data)
if not _ubus_connection then
_ubus_connection = _ubus.connect()
if type(data) ~= "table" then
data = { }
end
- local rv, err = _ubus_connection:call(object, method, data)
- return rv, err, ubus_codes[err]
+ return ubus_return(_ubus_connection:call(object, method, data))
elseif object then
return _ubus_connection:signatures(object)
else
-<% export("cbi_apply_widget", function(redirect_ok) -%>
+<% export("cbi_apply_widget", function(redirect_ok, rollback_token) -%>
<style type="text/css">
#cbi_apply_overlay {
position: absolute;
uci_apply_holdoff = <%=math.max(luci.config and luci.config.apply and luci.config.apply.holdoff or 4, 1)%>,
uci_apply_timeout = <%=math.max(luci.config and luci.config.apply and luci.config.apply.timeout or 5, 1)%>,
uci_apply_display = <%=math.max(luci.config and luci.config.apply and luci.config.apply.display or 1.5, 1)%>,
+ uci_confirm_auth = <% if rollback_token then %>{ token: '<%=rollback_token%>' }<% else %>null<% end %>,
was_xhr_poll_running = false;
function uci_status_message(type, content) {
var delay = isNaN(duration) ? 0 : Math.max(1000 - duration, 0);
window.setTimeout(function() {
- xhr.post('<%=url("admin/uci/confirm")%>', uci_apply_auth, call, uci_apply_timeout * 1000);
+ xhr.post('<%=url("admin/uci/confirm")%>', uci_confirm_auth, call, uci_apply_timeout * 1000);
}, delay);
};
uci_status_message('notice',
'<img src="<%=resource%>/icons/loading.gif" alt="" style="vertical-align:middle" /> ' +
- '<%:Waiting for configuration to get applied… %ds%>'.format(Math.max(Math.floor((deadline - Date.now()) / 1000), 0)));
+ '<%:Waiting for configuration to be applied… %ds%>'.format(Math.max(Math.floor((deadline - Date.now()) / 1000), 0)));
if (now >= deadline)
return;
'<img src="<%=resource%>/icons/loading.gif" alt="" style="vertical-align:middle" /> ' +
'<%:Starting configuration apply…%>');
- xhr.post('<%=url("admin/uci")%>/' + (checked ? 'apply_rollback' : 'apply_unchecked'), uci_apply_auth, function(r) {
+ xhr.post('<%=url("admin/uci")%>/' + (checked ? 'apply_rollback' : 'apply_unchecked'), uci_apply_auth, function(r, tok) {
if (r.status === (checked ? 200 : 204)) {
+ if (checked && tok !== null && typeof(tok) === 'object' && typeof(tok.token) === 'string')
+ uci_confirm_auth = tok;
+
uci_confirm(checked, Date.now() + uci_apply_rollback * 1000);
}
else if (checked && r.status === 204) {
<div class="cbi-map" id="cbi-<%=self.config%>">
<% if self.title and #self.title > 0 then %><h2 name="content"><%=self.title%></h2><% end %>
<% if self.description and #self.description > 0 then %><div class="cbi-map-descr"><%=self.description%></div><% end %>
- <%- if firstmap and (applymap or confirmmap) then -%>
- <%+cbi/apply_widget%>
- <% cbi_apply_widget(redirect) %>
- <div class="alert-message" id="cbi_apply_status" style="display:none"></div>
- <script type="text/javascript">
- document.addEventListener("DOMContentLoaded", function() {
- <% if confirmmap then -%>
- uci_confirm(true, Date.now() + <%=confirmmap%> * 1000);
- <%- else -%>
- uci_apply(true);
- <%- end %>
- });
- </script>
- <%- end -%>
-
<% if self.tabbed then %>
<ul class="cbi-tabmenu map">
<%- self.selected_tab = luci.http.formvalue("tab.m-" .. self.config) %>
Licensed to the public under the Apache License 2.0.
-%>
-<% include("themes/" .. theme .. "/footer") %>
\ No newline at end of file
+<%
+ local is_rollback_pending, rollback_time_remaining, rollback_session, rollback_token = luci.model.uci:rollback_pending()
+
+ if is_rollback_pending or trigger_apply or trigger_revert then
+ include("cbi/apply_widget")
+ cbi_apply_widget(redirect, rollback_token)
+%>
+ <div class="alert-message" id="cbi_apply_status" style="display:none"></div>
+ <script type="text/javascript">
+ document.addEventListener("DOMContentLoaded", function() {
+ <% if trigger_apply then -%>
+ uci_apply(true);
+ <%- elseif trigger_revert then -%>
+ uci_revert();
+ <%- else -%>
+ uci_confirm(true, Date.now() + <%=rollback_time_remaining%> * 1000);
+ <%- end %>
+ });
+ </script>
+<%
+ end
+
+ include("themes/" .. theme .. "/footer")
+%>
msgid "Waiting for command to complete..."
msgstr "Esperant que s'acabi l'ordre..."
-msgid "Waiting for configuration to get applied… %ds"
+msgid "Waiting for configuration to be applied… %ds"
msgstr ""
msgid "Waiting for device..."
msgid "Waiting for command to complete..."
msgstr "Čekání na dokončení příkazu..."
-msgid "Waiting for configuration to get applied… %ds"
+msgid "Waiting for configuration to be applied… %ds"
msgstr ""
msgid "Waiting for device..."
msgid "Waiting for command to complete..."
msgstr "Der Befehl wird ausgeführt..."
-msgid "Waiting for configuration to get applied… %ds"
+msgid "Waiting for configuration to be applied… %ds"
msgstr "Warte auf das Anwenden der Konfigurationsänderungen... %d Sekunden"
msgid "Waiting for device..."
msgid "Waiting for command to complete..."
msgstr ""
-msgid "Waiting for configuration to get applied… %ds"
+msgid "Waiting for configuration to be applied… %ds"
msgstr ""
msgid "Waiting for device..."
msgid "Waiting for command to complete..."
msgstr ""
-msgid "Waiting for configuration to get applied… %ds"
+msgid "Waiting for configuration to be applied… %ds"
msgstr ""
msgid "Waiting for device..."
msgid "Waiting for command to complete..."
msgstr "Esperando a que termine el comando..."
-msgid "Waiting for configuration to get applied… %ds"
+msgid "Waiting for configuration to be applied… %ds"
msgstr ""
msgid "Waiting for device..."
msgid "Waiting for command to complete..."
msgstr "En attente de la fin de la commande..."
-msgid "Waiting for configuration to get applied… %ds"
+msgid "Waiting for configuration to be applied… %ds"
msgstr ""
msgid "Waiting for device..."
msgid "Waiting for command to complete..."
msgstr ""
-msgid "Waiting for configuration to get applied… %ds"
+msgid "Waiting for configuration to be applied… %ds"
msgstr ""
msgid "Waiting for device..."
msgid "Waiting for command to complete..."
msgstr "Várakozás a parancs befejezésére..."
-msgid "Waiting for configuration to get applied… %ds"
+msgid "Waiting for configuration to be applied… %ds"
msgstr ""
msgid "Waiting for device..."
msgid "Waiting for command to complete..."
msgstr "In attesa del comando da completare..."
-msgid "Waiting for configuration to get applied… %ds"
+msgid "Waiting for configuration to be applied… %ds"
msgstr ""
msgid "Waiting for device..."
msgid "Waiting for command to complete..."
msgstr "コマンド実行中です..."
-msgid "Waiting for configuration to get applied… %ds"
+msgid "Waiting for configuration to be applied… %ds"
msgstr "設定を適用中です... %d 秒"
msgid "Waiting for device..."
msgid "Waiting for command to complete..."
msgstr "실행한 명령이 끝나기를 기다리는 중입니다..."
-msgid "Waiting for configuration to get applied… %ds"
+msgid "Waiting for configuration to be applied… %ds"
msgstr ""
msgid "Waiting for device..."
msgid "Waiting for command to complete..."
msgstr ""
-msgid "Waiting for configuration to get applied… %ds"
+msgid "Waiting for configuration to be applied… %ds"
msgstr ""
msgid "Waiting for device..."
msgid "Waiting for command to complete..."
msgstr "Venter på at kommando fullføres..."
-msgid "Waiting for configuration to get applied… %ds"
+msgid "Waiting for configuration to be applied… %ds"
msgstr ""
msgid "Waiting for device..."
"Project-Id-Version: LuCI\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2010-04-20 09:40+0200\n"
-"PO-Revision-Date: 2018-07-21 18:35+0200\n"
+"PO-Revision-Date: 2018-08-05 13:45+0200\n"
"Last-Translator: Rixerx <krystian.kozak20@gmail.com>\n"
"Language-Team: Polish\n"
"Language: pl\n"
msgstr "Numer urządzenia ATM"
msgid "ATU-C System Vendor ID"
-msgstr ""
+msgstr "ID dostawcy systemu ATU-C"
# co to takiego?
msgid "Access Concentrator"
-msgstr "Koncentrator dostępowy ATM"
+msgstr "Koncentrator dostępowy (ATM)"
msgid "Access Point"
msgstr "Punkt dostępowy"
msgstr "Ustawienia zaawansowane"
msgid "Aggregate Transmit Power(ACTATP)"
-msgstr ""
+msgstr "Agregacja siły transmisji (ACTATP)"
msgid "Alert"
msgstr "Alarm"
"Build/distribution specific feed definitions. This file will NOT be "
"preserved in any sysupgrade."
msgstr ""
+"Kompiluj/rozpowszechniaj określone definicje źródeł. Ten plik NIE "
+"zostanie zachowany w procesie sysupgrade"
msgid "CA certificate; if empty it will be saved after the first connection."
msgstr ""
"Close inactive connection after the given amount of seconds, use 0 to "
"persist connection"
msgstr ""
-"Zamykaj nieaktywne połączenia po określonym czasie podanym w sekundach, "
+"Zamknij nieaktywne połączenia po określonym czasie podanym w sekundach, "
"wpisz 0 aby uzyskać stałe połączenie."
msgid "Close list..."
msgstr "Interfejs niestandardowy"
msgid "Custom delegated IPv6-prefix"
-msgstr ""
+msgstr "Delegowany niestandardowy prefiks IPv6"
msgid ""
"Custom feed definitions, e.g. private feeds. This file can be preserved in a "
"sysupgrade."
msgstr ""
+"Niestandardowe definicje plików danych, np. prywatne źródła. Ten plik może być "
+"zachowany podczas sysupgrade. "
msgid "Custom feeds"
-msgstr ""
+msgstr "Niestandardowe źródła"
msgid ""
"Custom files (certificates, scripts) may remain on the system. To prevent "
msgstr "DUID"
msgid "Data Rate"
-msgstr ""
+msgstr "Szybkość przesyłania danych"
msgid "Debug"
msgstr "Debug"
msgstr "Odległość do najdalej oddalonego członka sieci w metrach."
msgid "Distribution feeds"
-msgstr ""
+msgstr "Dystrybucja źródeł"
# Jak poprzednio trzymam się konwencji
msgid "Diversity"
msgstr "Błąd"
msgid "Errored seconds (ES)"
-msgstr ""
+msgstr "Ilość błędów (ES)"
msgid "Ethernet Adapter"
msgstr "Karta Ethernet"
msgstr "Stan firewalla"
msgid "Firmware File"
-msgstr ""
+msgstr "Plik firmware"
msgid "Firmware Version"
msgstr "Wersja firmware"
msgstr "Przekazuj ruch DHCP"
msgid "Forward Error Correction Seconds (FECS)"
-msgstr ""
+msgstr "Próby korekcji błędów (FECS)"
msgid "Forward broadcast traffic"
msgstr "Przekazuj broadcast`y"
msgstr "Ustawienia podstawowe"
msgid "General options for opkg"
-msgstr ""
+msgstr "Ogólne opcje dla opkg"
msgid "Generate Config"
msgstr "Wygeneruj konfigurację"
msgstr "Rozłącz"
msgid "Header Error Code Errors (HEC)"
-msgstr ""
+msgstr "Błędy kodu nagłówka (HEC)"
msgid ""
"Here you can configure the basic aspects of your device like its hostname or "
msgstr "Próg błędu echa LCP"
msgid "LCP echo interval"
-msgstr "Częstotliwość echa LCP"
+msgstr "Interwał echa LCP"
msgid "LLC"
msgstr "LLC"
msgstr "Pozostały czas dzierżawy"
msgid "Leave empty to autodetect"
-msgstr "Pozostaw niewypełnione dla autodetekcji"
+msgstr "Pozostaw puste, aby automatycznie wykryć"
msgid "Leave empty to use the current WAN address"
-msgstr "Pozostaw niewypełnione aby użyć bieżącego adresu WAN"
+msgstr "Pozostaw puste, aby użyć bieżącego adresu WAN"
msgid "Legend:"
msgstr "Legenda:"
msgstr "Ogranicz nasłuchiwanie do tych interfesjów, oraz loopbacku."
msgid "Line Attenuation (LATN)"
-msgstr ""
+msgstr "Tłumienie linii (LATN)"
msgid "Line Mode"
-msgstr ""
+msgstr "Tryb linii"
msgid "Line State"
-msgstr ""
+msgstr "Stan linii"
msgid "Line Uptime"
-msgstr ""
+msgstr "Czas działania linii"
msgid "Link On"
msgstr "Połączenie aktywne"
msgstr "Wyloguj"
msgid "Loss of Signal Seconds (LOSS)"
-msgstr ""
+msgstr "Utrata sygnału (LOSS)"
msgid "Lowest leased address as offset from the network address."
msgstr "Najniższy wydzierżawiony adres jako offset dla adresu sieci."
msgstr ""
msgid "Max. Attainable Data Rate (ATTNDR)"
-msgstr ""
+msgstr "Max. Osiągalna przepustowość danych (ATTNDR)"
msgid "Maximum allowed number of active DHCP leases"
msgstr "Maksymalna dozwolona liczba aktywnych dzierżaw DHCP"
msgstr "Nie podano nazwy sieci"
msgid "No package lists available"
-msgstr "Brak dostępu do listy pakietów"
+msgstr "Lista pakietów nie jest dostępna"
msgid "No password set!"
msgstr "Nie ustawiono hasła!"
msgstr "Szum:"
msgid "Non Pre-emtive CRC errors (CRC_P)"
-msgstr ""
+msgstr "Nieprzewidziane błedy CRC (CRC_P)"
msgid "Non-wildcard"
msgstr "Bez symboli wieloznacznych"
msgstr ""
msgid "Obtain IPv6-Address"
-msgstr ""
+msgstr "Uzyskaj adres IPv6"
msgid "Off-State Delay"
msgstr "Zwłoka wyłączenia"
msgstr "Tryb zarządzania energią"
msgid "Pre-emtive CRC errors (CRCP_P)"
-msgstr ""
+msgstr "Przewidziane błedy CRC (CRCP_P)"
msgid "Prefer LTE"
msgstr ""
"Presume peer to be dead after given amount of LCP echo failures, use 0 to "
"ignore failures"
msgstr ""
-"Zakładaj że klient jest martwy po danej ilości błedów odpowiedzi echa LCP, "
-"wpisz 0 aby zignorować błędy"
+"Przypuszczaj że klient może być martwy po zadanej ilości błedów echa LCP, "
+"wpisz 0 aby zignorować te błędy"
msgid "Prevent listening on these interfaces."
msgstr "Zapobiegaj nasłuchiwaniu na tych interfejsach."
msgstr "Zażądaj adresu IPv6"
msgid "Request IPv6-prefix of length"
-msgstr ""
+msgstr "Zażądaj długość prefiksu IPv6"
msgid "Required"
msgstr "Wymagany"
"Send LCP echo requests at the given interval in seconds, only effective in "
"conjunction with failure threshold"
msgstr ""
-"Co podany czas (w sekundach) wyślij zapytania LCP echo, to ustawienie działa "
-"tylko gdy ustawiony jest próg błędu LCP echo"
+"Wysyłaj żądania echa LCP w określonym przedziale czasowym, "
+"efektywne tylko wtedy gdy jest ustawiony próg błedu LCP"
msgid "Separate Clients"
msgstr "Rozdziel klientów"
msgstr "Ustawienia serwera DHCP"
msgid "Severely Errored Seconds (SES)"
-msgstr ""
+msgstr "Ilość poważnych błedów (SES)"
msgid "Short GI"
msgstr ""
msgstr "Sygnał"
msgid "Signal Attenuation (SATN)"
-msgstr ""
+msgstr "Tłumienie sygnału (SATN)"
msgid "Signal:"
msgstr "Sygnał:"
msgstr "Priorytet uruchomienia"
msgid "Starting configuration apply…"
-msgstr ""
+msgstr "Zatwierdzanie konfiguracji…"
msgid "Starting wireless scan..."
msgstr "Rozpoczynanie skanowania..."
"odpowiednim dzierżawami."
msgid "Status"
-msgstr "Stan"
+msgstr "Status"
msgid "Stop"
msgstr "Stop"
"compare them with the original file to ensure data integrity.<br /> Click "
"\"Proceed\" below to start the flash procedure."
msgstr ""
-"Obraz flash`a został przesłany. Poniżej znajduje się suma kontrolna i "
-"rozmiar obrazu, porównaj je z sumą kontrolną i rozmiarem oryginału, aby "
-"upewnić się, że został przesłany poprawnie.<br /> Wciśnij \"Wykonaj\" aby "
-"kontynuować aktualizację."
+"Obraz flash został przesłany. Poniżej znajduje się suma kontrolna i "
+"rozmiar pliku, porównaj je z orginałem aby zapewnić integralność "
+"danych.<br /> Wciśnij \"Wykonaj\" aby kontynuować aktualizację."
msgid "The following changes have been reverted"
msgstr "Następujące zmiany zostały odrzucone"
msgstr "Brak aktywnych dzierżaw."
msgid "There are no changes to apply."
-msgstr "Nie ma żadnych zmian do zastosowania."
+msgstr "Brak zmian do zastosowania."
msgid "There are no pending changes to revert!"
msgstr "Brak oczekujących zmian do przywrócenia!"
"\"Wykonaj reset\" (możliwe tylko w przypadku obrazu squashfs)."
msgid "Tone"
-msgstr ""
+msgstr "Ton"
msgid "Total Available"
msgstr "Całkowicie dostępna"
msgstr "Nie można rozpoznać nazwy peera"
msgid "Unavailable Seconds (UAS)"
-msgstr ""
+msgstr "Czas niedostępnośći (UAS)"
msgid "Unknown"
msgstr "Nieznany"
msgid "Waiting for command to complete..."
msgstr "Trwa wykonanie polecenia..."
-msgid "Waiting for configuration to get applied… %ds"
+msgid "Waiting for configuration to be applied… %ds"
msgstr "Oczekiwanie na zastosowanie konfiguracji… %ds"
msgid "Waiting for device..."
msgid "Waiting for command to complete..."
msgstr "Esperando o término do comando..."
-msgid "Waiting for configuration to get applied… %ds"
+msgid "Waiting for configuration to be applied… %ds"
msgstr ""
msgid "Waiting for device..."
msgid "Waiting for command to complete..."
msgstr "A aguardar que o comando termine..."
-msgid "Waiting for configuration to get applied… %ds"
+msgid "Waiting for configuration to be applied… %ds"
msgstr ""
msgid "Waiting for device..."
msgid "Waiting for command to complete..."
msgstr ""
-msgid "Waiting for configuration to get applied… %ds"
+msgid "Waiting for configuration to be applied… %ds"
msgstr ""
msgid "Waiting for device..."
msgid "Waiting for command to complete..."
msgstr "Ожидание завершения выполнения команды..."
-msgid "Waiting for configuration to get applied… %ds"
+msgid "Waiting for configuration to be applied… %ds"
msgstr "Ожидание применения конфигурации... %d сек."
msgid "Waiting for device..."
msgid "Waiting for command to complete..."
msgstr ""
-msgid "Waiting for configuration to get applied… %ds"
+msgid "Waiting for configuration to be applied… %ds"
msgstr ""
msgid "Waiting for device..."
msgid "Waiting for command to complete..."
msgstr "Väntar på att kommandot ska avsluta..."
-msgid "Waiting for configuration to get applied… %ds"
+msgid "Waiting for configuration to be applied… %ds"
msgstr ""
msgid "Waiting for device..."
msgid "Waiting for command to complete..."
msgstr ""
-msgid "Waiting for configuration to get applied… %ds"
+msgid "Waiting for configuration to be applied… %ds"
msgstr ""
msgid "Waiting for device..."
msgid "Waiting for command to complete..."
msgstr ""
-msgid "Waiting for configuration to get applied… %ds"
+msgid "Waiting for configuration to be applied… %ds"
msgstr ""
msgid "Waiting for device..."
msgid ""
msgstr ""
"Project-Id-Version: \n"
-"PO-Revision-Date: 2018-07-20 11:30+0300\n"
+"PO-Revision-Date: 2018-08-10 17:30+0300\n"
"Last-Translator: Yurii <yuripet@gmail.com>\n"
"Language-Team: none\n"
"Language: uk\n"
msgstr "Стартовий пріоритет"
msgid "Starting configuration apply…"
-msgstr "Ð\97аÑ\81Ñ\82оÑ\81овÑ\83Ñ\94Ñ\82Ñ\8cÑ\81Ñ\8f Ñ\81Ñ\82аÑ\80Ñ\82ова конÑ\84Ñ\96гÑ\83Ñ\80аÑ\86Ñ\96Ñ\8f…"
+msgstr "РозпоÑ\87аÑ\82о заÑ\81Ñ\82оÑ\81Ñ\83ваннÑ\8f конÑ\84Ñ\96гÑ\83Ñ\80аÑ\86Ñ\96Ñ\97…"
msgid "Starting wireless scan..."
msgstr "Розпочато сканування бездротових мереж..."
"\"Proceed\" below to start the flash procedure."
msgstr ""
"Образ завантажено. Нижче наведено контрольну суму та розмір файлу. "
-"Ð\9fоÑ\80Ñ\96внÑ\8fйÑ\82е Ñ\97Ñ\85 з виÑ\85Ñ\96дним Ñ\84айлом, Ñ\88об переконатися в цілісності даних.<br /> "
+"Ð\9fоÑ\80Ñ\96внÑ\8fйÑ\82е Ñ\97Ñ\85 з виÑ\85Ñ\96дним Ñ\84айлом, Ñ\89об переконатися в цілісності даних.<br /> "
"Натисніть \"Продовжити\", щоб розпочати процедуру прошивання."
msgid "The following changes have been reverted"
"There is no password set on this router. Please configure a root password to "
"protect the web interface and enable SSH."
msgstr ""
-"Цей маÑ\80Ñ\88Ñ\80Ñ\83Ñ\82изаÑ\82оÑ\80 не маÑ\94 паÑ\80олÑ\8f. Ð\92Ñ\81Ñ\82ановÑ\96Ñ\82Ñ\8c паÑ\80олÑ\8c, Ñ\88об захистити веб-"
+"Цей маÑ\80Ñ\88Ñ\80Ñ\83Ñ\82изаÑ\82оÑ\80 не маÑ\94 паÑ\80олÑ\8f. Ð\92Ñ\81Ñ\82ановÑ\96Ñ\82Ñ\8c паÑ\80олÑ\8c, Ñ\89об захистити веб-"
"інтерфейс і увімкнути SSH."
msgid "This IPv4 address of the relay"
msgid "Waiting for command to complete..."
msgstr "Очікуємо завершення виконання команди..."
-msgid "Waiting for configuration to get applied… %ds"
+msgid "Waiting for configuration to be applied… %ds"
msgstr "Чекаємо на застосування конфігурації… %d c"
msgid "Waiting for device..."
msgid "Waiting for command to complete..."
msgstr ""
-msgid "Waiting for configuration to get applied… %ds"
+msgid "Waiting for configuration to be applied… %ds"
msgstr ""
msgid "Waiting for device..."
+#
+# Yangfl <mmyangfl@gmail.com>, 2018.
+#
msgid ""
msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
-"Last-Translator: Hsing-Wang Liao <kuoruan@gmail.com>\n"
+"Last-Translator: Yangfl <mmyangfl@gmail.com>\n"
+"Language-Team: <debian-l10n-chinese@lists.debian.org>\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"PO-Revision-Date: 2018-08-07 14:59+0800\n"
+"X-Generator: Gtranslator 2.91.7\n"
msgid "%.1f dB"
-msgstr ""
+msgstr "%.1f dB"
msgid "%s is untagged in multiple VLANs!"
msgstr "%s 在多个 VLAN 中均未标记!"
msgstr "-- 根据 UUID 匹配 --"
msgid "-- please select --"
-msgstr ""
+msgstr "-- 请选择 --"
msgid "1 Minute Load:"
msgstr "1 分钟负载:"
msgstr "<abbr title=\"Media Access Control\">MAC</abbr> 地址"
msgid "<abbr title=\"The DHCP Unique Identifier\">DUID</abbr>"
-msgstr ""
+msgstr "<abbr title=\"The DHCP Unique Identifier\">DUID</abbr>"
msgid ""
"<abbr title=\"maximal\">Max.</abbr> <abbr title=\"Dynamic Host Configuration "
msgstr "警戒"
msgid "Alias Interface"
-msgstr ""
+msgstr "接口别名"
msgid "Alias of \"%s\""
-msgstr ""
+msgstr "\"%s\" 的别名"
msgid "All Servers"
-msgstr ""
+msgstr "所有服务器"
msgid ""
"Allocate IP addresses sequentially, starting from the lowest available "
msgstr "允许 <abbr title=\"Secure Shell\">SSH</abbr> 密码验证"
msgid "Allow AP mode to disconnect STAs based on low ACK condition"
-msgstr ""
+msgstr "允许 AP 模式时在 low ACK 的情况下断开无线终端"
msgid "Allow all except listed"
msgstr "仅允许列表外"
"Always use 40MHz channels even if the secondary channel overlaps. Using this "
"option does not comply with IEEE 802.11n-2009!"
msgstr ""
+"即使辅助信道重叠,也始终使用 40MHz 信道。使用此选项不符合 IEEE 802.11n-2009!"
msgid "Annex"
msgstr "Annex"
msgstr "应用请求失败,状态 <code>%h</code>"
msgid "Apply unchecked"
-msgstr "åº\94ç\94¨æ\9cªé\80\89ä¸"
+msgstr "强å\88¶åº\94ç\94¨"
msgid "Architecture"
msgstr "架构"
msgstr "频宽"
msgid "Beacon Interval"
-msgstr ""
+msgstr "Beacon 间隔"
msgid ""
"Below is the determined list of files to backup. It consists of changed "
msgstr "CPU 使用率(%)"
msgid "Call failed"
-msgstr ""
+msgstr "调用失败"
msgid "Cancel"
msgstr "取消"
msgstr "链"
msgid "Changes"
-msgstr "修改数"
+msgstr "更改数"
msgid "Changes applied."
msgstr "更改已应用。"
msgid "Changes have been reverted."
-msgstr "更改已取消。"
+msgstr "更改已恢复。"
msgid "Changes the administrator password for accessing the device"
-msgstr "修改访问设备的管理员密码"
+msgstr "更改访问设备的管理员密码"
msgid "Channel"
msgstr "信道"
msgstr "在给定时间(秒)后关闭非活动链接,0 为保持连接"
msgid "Close list..."
-msgstr "关闭列表..."
+msgstr "关闭列表…"
msgid "Collecting data..."
-msgstr "正在收集数据..."
+msgstr "正在收集数据…"
msgid "Command"
msgstr "命令"
msgstr "配置"
msgid "Configuration failed"
-msgstr ""
+msgstr "配置失败"
msgid "Configuration files will be kept."
msgstr "配置文件将被保留。"
msgstr "连接数限制"
msgid "Connection attempt failed"
-msgstr ""
+msgstr "尝试连接失败"
msgid "Connections"
msgstr "连接"
"changes. You might need to reconnect if you modified network related "
"settings such as the IP address or wireless security credentials."
msgstr ""
-"应用配置更改后,无法重新获得对设备的访问权限。如果您修改了网络相关设置如 IP "
+"应用配置更改后,无法重新获得对设备的访问权限。如果您更改了网络相关设置如 IP "
"地址或无线安全证书,则可能需要重新连接。"
msgid "Country"
msgstr "DSL 线路模式"
msgid "DTIM Interval"
-msgstr ""
+msgstr "DTIM 间隔"
msgid "DUID"
msgstr "DUID"
msgstr "删除此网络"
msgid "Delivery Traffic Indication Message Interval"
-msgstr ""
+msgstr "发送流量指示消息间隔"
msgid "Description"
msgstr "描述"
msgstr "设备配置"
msgid "Device is rebooting..."
-msgstr "设备正在重启..."
+msgstr "设备正在重启…"
msgid "Device unreachable!"
msgstr "无法连接到设备"
msgid "Device unreachable! Still waiting for device..."
-msgstr ""
+msgstr "无法连接到设备!仍旧等待设备…"
msgid "Diagnostics"
msgstr "网络诊断"
msgstr "已禁用"
msgid "Disabled (default)"
-msgstr "禁用(默认)"
+msgstr "已禁用(默认)"
msgid "Disassociate On Low Acknowledgement"
-msgstr ""
+msgstr "在低 Ack 应答时断开连接"
msgid "Discard upstream RFC1918 responses"
msgstr "丢弃 RFC1918 上行响应数据"
msgid "Disconnection attempt failed"
-msgstr ""
+msgstr "尝试断开连接失败"
msgid "Dismiss"
msgstr "解除"
"不转发没有 <abbr title=\"Domain Name System\">DNS</abbr> 名称的解析请求"
msgid "Down"
-msgstr ""
+msgstr "向下"
msgid "Download and install package"
msgstr "下载并安装软件包"
msgstr "EAP 类型"
msgid "Edit"
-msgstr "修改"
+msgstr "编辑"
msgid ""
"Edit the raw configuration data above to fix any error and hit \"Save\" to "
msgstr "编辑上方的原始配置数据来修复错误,点击“保存”按钮以重新载入此页面。"
msgid "Edit this interface"
-msgstr "修改此接口"
+msgstr "编辑此接口"
msgid "Edit this network"
-msgstr "修改此网络"
+msgstr "编辑此网络"
msgid "Emergency"
msgstr "紧急"
"Enable <abbr title=\"Internet Group Management Protocol\">IGMP</abbr> "
"snooping"
msgstr ""
-"启用 <abbr title=\"Internet Group Management Protocol\">IGMP</abbr> 窥探"
+"启用 <abbr title=\"Internet Group Management Protocol\">IGMP</abbr> 嗅探"
msgid "Enable <abbr title=\"Spanning Tree Protocol\">STP</abbr>"
msgstr "开启 <abbr title=\"Spanning Tree Protocol\">STP</abbr>"
msgstr "启用此挂载点"
msgid "Enable this network"
-msgstr ""
+msgstr "启用此网络"
msgid "Enable this swap"
msgstr "启用此 swap 分区"
msgstr "端点端口"
msgid "Enter custom value"
-msgstr ""
+msgstr "输入自定义值"
msgid "Enter custom values"
-msgstr ""
+msgstr "输入自定义值"
msgid "Erasing..."
-msgstr "擦除中..."
+msgstr "擦除中…"
msgid "Error"
msgstr "错误"
msgstr "额外的 SSH 命令选项"
msgid "FT over DS"
-msgstr ""
+msgstr "FT over DS"
msgid "FT over the Air"
-msgstr ""
+msgstr "FT over the Air"
msgid "FT protocol"
msgstr "FT 协议"
msgid "Failed to confirm apply within %ds, waiting for rollback…"
-msgstr "在 %d 秒内确认应用失败,等待回滚..."
+msgstr "在 %d 秒内确认应用失败,等待回滚…"
msgid "File"
msgstr "文件"
msgstr "过滤无用包"
msgid "Finalizing failed"
-msgstr ""
+msgstr "最终确认失败"
msgid ""
"Find all currently attached filesystems and swap and replace configuration "
msgstr "刷新固件"
msgid "Flash image..."
-msgstr "刷写固件..."
+msgstr "刷写固件…"
msgid "Flash new firmware image"
msgstr "刷写新的固件"
msgstr "刷新操作"
msgid "Flashing..."
-msgstr "刷写中..."
+msgstr "正在刷写…"
msgid "Force"
msgstr "强制"
msgid "Force 40MHz mode"
-msgstr ""
+msgstr "强制 40MHz 模式"
msgid "Force CCMP (AES)"
msgstr "强制 CCMP(AES)"
msgstr "网关"
msgid "Gateway address is invalid"
-msgstr ""
+msgstr "网关地址无效"
msgid "Gateway ports"
msgstr "网关端口"
msgstr "全局网络选项"
msgid "Go to password configuration..."
-msgstr "跳转到密码配置页..."
+msgstr "跳转到密码配置页…"
msgid "Go to relevant configuration page"
msgstr "跳转到相关的配置页面"
msgstr "主机 <abbr title=\"Internet Protocol Address\">IP</abbr> 或网络"
msgid "Host-Uniq tag content"
-msgstr ""
+msgstr "Host-Uniq 标签内容"
msgid "Hostname"
msgstr "主机名"
msgstr "IP 地址"
msgid "IP address in invalid"
-msgstr ""
+msgstr "IP 地址无效"
msgid "IP address is missing"
-msgstr ""
+msgstr "IP 地址缺失"
msgid "IPv4"
msgstr "IPv4"
msgstr "信息"
msgid "Initialization failure"
-msgstr ""
+msgstr "初始化失败"
msgid "Initscript"
msgstr "启动脚本"
msgstr "安装软件包 %q"
msgid "Install protocol extensions..."
-msgstr "安装扩展协议..."
+msgstr "安装扩展协议…"
msgid "Installed packages"
msgstr "已安装软件包"
msgstr "接口总览"
msgid "Interface is reconnecting..."
-msgstr "正在重新连接接口..."
+msgstr "正在重新连接接口…"
msgid "Interface name"
msgstr "接口名称"
msgstr "加载中"
msgid "Local IP address is invalid"
-msgstr ""
+msgstr "本地 IP 地址无效"
msgid "Local IP address to assign"
msgstr "要分配的本地 IP 地址"
msgstr "网络地址的起始分配基址。"
msgid "MAC"
-msgstr ""
+msgstr "MAC"
msgid "MAC-Address"
msgstr "MAC 地址"
msgstr "MAP / LW4over6"
msgid "MAP rule is invalid"
-msgstr ""
+msgstr "MAP 规则无效"
msgid "MB/s"
msgstr "MB/s"
msgstr "调制解调器节点"
msgid "Modem information query failed"
-msgstr ""
+msgstr "调制解调器信息查询失败"
msgid "Modem init timeout"
msgstr "调制解调器初始化超时"
msgstr "网络启动镜像"
msgid "Network device is not present"
-msgstr ""
+msgstr "网络设备不存在"
msgid "Network without interfaces."
msgstr "无接口的网络。"
msgid "Next »"
-msgstr "下一步 »"
+msgstr "前进 »"
msgid "No DHCP Server configured for this interface"
msgstr "本接口未配置 DHCP 服务器"
msgstr "无可用信息"
msgid "No matching prefix delegation"
-msgstr ""
+msgstr "无匹配的前缀委托"
msgid "No negative cache"
msgstr "禁用无效信息缓存"
msgstr "本链没有规则"
msgid "No scan results available yet..."
-msgstr ""
+msgstr "还没有可用的扫描结果…"
msgid "No zone assigned"
msgstr "未指定区域"
msgstr "一个或多个必选项值为空!"
msgid "Open list..."
-msgstr "打开列表..."
+msgstr "打开列表……"
msgid "OpenConnect (CISCO AnyConnect)"
msgstr "OpenConnect (CISCO AnyConnect)"
msgstr "工作频率"
msgid "Option changed"
-msgstr "ä¿®æ\94¹ç\9a\84é\80\89项"
+msgstr "é\80\89项已æ\9b´æ\94¹"
msgid "Option removed"
-msgstr "移除的选项"
+msgstr "选项已移除"
msgid "Optional"
msgstr "可选"
msgstr "可选,为此 Peer 创建允许 IP 的路由。"
msgid "Optional. Description of peer."
-msgstr ""
+msgstr "可选,Peer 的描述。"
msgid ""
"Optional. Host of peer. Names are resolved prior to bringing up the "
msgstr "PIN"
msgid "PIN code rejected"
-msgstr ""
+msgstr "PIN 码被拒绝"
msgid "PMK R1 Push"
msgstr "R1 推送 PMK"
msgstr "内部私钥的密码"
msgid "Password successfully changed!"
-msgstr "密码修改成功!"
+msgstr "密码更改成功!"
msgid "Password2"
msgstr "密码 2"
msgstr "要分配的 Peer IP 地址"
msgid "Peer address is missing"
-msgstr ""
+msgstr "Peer 地址缺失"
msgid "Peers"
msgstr "Peers"
"Query all available upstream <abbr title=\"Domain Name System\">DNS</abbr> "
"servers"
msgstr ""
+"查询所有可用的上游 <abbr title=\"Domain Name System\">DNS</abbr> 服务器"
msgid "R0 Key Lifetime"
msgstr "R0 密钥生存期"
msgstr "Radius 认证服务器"
msgid "Raw hex-encoded bytes. Leave empty unless your ISP require this"
-msgstr ""
+msgstr "原始 16 进制编码的字节。除非您的 ISP 要求,否则请留空"
msgid ""
"Read <code>/etc/ethers</code> to configure the <abbr title=\"Dynamic Host "
"Really delete this interface? The deletion cannot be undone! You might lose "
"access to this device if you are connected via this interface"
msgstr ""
+"确定要删除此接口?删除操作无法撤消!若您删除此接口,可能导致无法再访问此设备"
msgid ""
"Really delete this wireless network? The deletion cannot be undone! You "
"might lose access to this device if you are connected via this network."
msgstr ""
-"确定要删除此无线网络?删除操作无法撤销!\\n删除此无线网络,可能导致无法再访问"
-"路由器!"
+"确定要删除此无线网络?删除操作无法撤销!若您删除此无线网络,可能导致无法再访"
+"问此设备。"
msgid "Really reset all changes?"
msgstr "确定要放弃所有更改?"
msgstr "重启"
msgid "Rebooting..."
-msgstr "重启中..."
+msgstr "正在重启…"
msgid "Reboots the operating system of your device"
msgstr "重启您设备上的系统"
msgstr "重启防火墙"
msgid "Restart radio interface"
-msgstr ""
+msgstr "重启无线接口"
msgid "Restore"
msgstr "恢复"
msgstr "恢复请求失败,状态 <code>%h</code>"
msgid "Reverting configuration…"
-msgstr "正在恢复配置..."
+msgstr "正在恢复配置…"
msgid "Root"
msgstr "Root"
msgstr "扫描"
msgid "Scan request failed"
-msgstr ""
+msgstr "扫描请求失败"
msgid "Scheduled Tasks"
msgstr "计划任务"
msgstr "设置时间同步"
msgid "Setting PLMN failed"
-msgstr ""
+msgstr "设置 PLMN 失败"
msgid "Setting operation mode failed"
-msgstr ""
+msgstr "设置操作模式失败"
msgid "Setup DHCP Server"
msgstr "配置 DHCP 服务器"
msgstr "Short GI"
msgid "Short Preamble"
-msgstr ""
+msgstr "Short Preamble"
msgid "Show current backup file list"
msgstr "显示当前备份文件列表"
msgstr "启动优先级"
msgid "Starting configuration apply…"
-msgstr "开始应用配置..."
+msgstr "开始应用配置…"
msgid "Starting wireless scan..."
-msgstr ""
+msgstr "正在启动无线扫描…"
msgid "Startup"
msgstr "启动项"
msgstr "同步浏览器时间"
msgid "Synchronizing..."
-msgstr "同步中..."
+msgstr "正在同步…"
msgid "System"
msgstr "系统"
"code>"
msgid "The backup archive does not appear to be a valid gzip file."
-msgstr ""
+msgstr "备份存档似乎不是有效的 gzip 文件。"
msgid "The configuration file could not be loaded due to the following error:"
msgstr "由于以下错误,配置文件无法被加载:"
"or revert all pending changes to keep the currently working configuration "
"state."
msgstr ""
-"在应用挂起的更改后 %d 秒内无法到达该设备,出于安全原因导致配置回滚。如果您认"
-"为配置更改仍然正确,请执行未选中的配置应用。或者您可以在尝试再次应用之前解除"
-"此警告并编辑更改,或者还原所有未完成的更改以保持当前正在工作的配置状态。"
+"在应用挂起的更改后 %d 秒内无法连接到此设备,出于安全原因导致配置回滚。如果您"
+"认为配置的更改是正确的,请执行强制应用。或者您可以在再次尝试应用之前解除此警"
+"告并编辑配置,或者恢复所有挂起的更改以保持当前正在工作的配置状态。"
msgid ""
"The device file of the memory or partition (<abbr title=\"for example\">e.g."
"过程中切勿断电!"
msgid "The following changes have been reverted"
-msgstr "以ä¸\8bæ\9b´æ\94¹å·²æ\94¾å¼\83"
+msgstr "以ä¸\8bæ\9b´æ\94¹å·²æ\81¢å¤\8d"
msgid "The following rules are currently active on this system."
msgstr "以下规则当前在系统中处于活动状态。"
msgid ""
"The length of the IPv4 prefix in bits, the remainder is used in the IPv6 "
"addresses."
-msgstr "IPv4 前缀长度(bit),其余的用在 IPv6 地址。"
+msgstr "IPv4 前缀长度(位),其余的用在 IPv6 地址。"
msgid "The length of the IPv6 prefix in bits"
-msgstr "IPv6 前缀长度(bit)"
+msgstr "IPv6 前缀长度(位)"
msgid "The local IPv4 address over which the tunnel is created (optional)."
msgstr "所创建隧道的本地 IPv4 地址(可选)。"
"address of your computer to reach the device again, depending on your "
"settings."
msgstr ""
-"正在刷新系统...<br />切勿关闭电源! DO NOT POWER OFF THE DEVICE!<br />等待数分"
+"正在刷写系统…<br />切勿关闭电源! DO NOT POWER OFF THE DEVICE!<br />等待数分"
"钟后即可尝试重新连接到路由。您可能需要更改计算机的 IP 地址以重新连接。"
msgid ""
msgstr "没有已分配的租约。"
msgid "There are no changes to apply."
-msgstr "没有待生效的更改。"
+msgstr "没有待应用的更改。"
msgid "There are no pending changes to revert!"
-msgstr "没有可放弃的更改!"
+msgstr "没有挂起的更改可恢复!"
msgid "There are no pending changes!"
-msgstr "没有待生效的更改!"
+msgstr "没有挂起的更改!"
msgid ""
"There is no device assigned yet, please attach a network device in the "
"include during sysupgrade. Modified files in /etc/config/ and certain other "
"configurations are automatically preserved."
msgstr ""
-"系统升级时要保存的配置文件和目录的清单。目录 /etc/config/ 内修改过的文件以及"
+"系统升级时要保存的配置文件和目录的清单。目录 /etc/config/ 内更改过的文件以及"
"部分其他配置会被自动保存。"
msgid ""
msgstr "UUID"
msgid "Unable to determine device name"
-msgstr ""
+msgstr "无法确认设备名称"
msgid "Unable to determine external IP address"
-msgstr ""
+msgstr "无法确认外部 IP 地址"
msgid "Unable to determine upstream interface"
-msgstr ""
+msgstr "无法确认上游接口"
msgid "Unable to dispatch"
msgstr "无法调度"
msgid "Unable to obtain client ID"
-msgstr ""
+msgstr "无法获取客户端 ID"
msgid "Unable to resolve AFTR host name"
-msgstr ""
+msgstr "无法解析 AFTR 主机名"
msgid "Unable to resolve peer host name"
-msgstr ""
+msgstr "无法解析 Pear 主机名"
msgid "Unavailable Seconds (UAS)"
msgstr "不可用秒数(UAS)"
msgstr "未知错误,密码未更改!"
msgid "Unknown error (%s)"
-msgstr ""
+msgstr "未知错误(%s)"
msgid "Unmanaged"
msgstr "不配置协议"
msgstr "未保存的配置"
msgid "Unsupported MAP type"
-msgstr ""
+msgstr "不支持的 MAP 类型"
msgid "Unsupported modem"
-msgstr ""
+msgstr "不支持的调制解调器"
msgid "Unsupported protocol type."
msgstr "不支持的协议类型"
msgid "Up"
-msgstr ""
+msgstr "向上"
msgid "Update lists"
msgstr "刷新列表"
msgstr "版本"
msgid "Virtual dynamic interface"
-msgstr ""
+msgstr "虚拟动态接口"
msgid "WDS"
msgstr "WDS"
"点 Ad-Hoc 模式)。"
msgid "Waiting for changes to be applied..."
-msgstr "正在应用更改..."
+msgstr "正在应用更改…"
msgid "Waiting for command to complete..."
-msgstr "等待命令执行完成..."
+msgstr "等待命令执行完成…"
-msgid "Waiting for configuration to get applied… %ds"
-msgstr "等待应用配置... %d 秒"
+msgid "Waiting for configuration to be applied… %ds"
+msgstr "等待应用配置… %d 秒"
msgid "Waiting for device..."
-msgstr "等待设备..."
+msgstr "等待设备…"
msgid "Warning"
msgstr "警告"
msgstr "无线未开启"
msgid "Wireless is not associated"
-msgstr "无线未未关联"
+msgstr "无线未关联"
msgid "Wireless is restarting..."
-msgstr "无线重启中..."
+msgstr "无线重启中…"
msgid "Wireless network is disabled"
msgstr "无线网络已禁用"
"or Safari."
msgstr ""
"您的 IE 浏览器太老了,无法正常显示这个页面!请更新到 IE7 及以上或使用其他浏览"
-"器,例如:Chrome、Firefox、Opera、Safari。"
+"器,如 Firefox、Opera、Safari。"
msgid "any"
msgstr "任意"
msgstr "桥接的"
msgid "create"
-msgstr ""
+msgstr "创建"
msgid "create:"
msgstr "创建:"
msgstr "kbit/s"
msgid "local <abbr title=\"Domain Name System\">DNS</abbr> file"
-msgstr "本地 <abbr title=\"Domain Name Syste\">DNS</abbr> 解析文件"
+msgstr "本地 <abbr title=\"Domain Name System\">DNS</abbr> 解析文件"
msgid "minutes"
msgstr "分钟"
msgid "mixed WPA/WPA2"
-msgstr ""
+msgstr "混合 WPA/WPA2"
msgid "no"
msgstr "否"
msgstr "开放式"
msgid "output"
-msgstr ""
+msgstr "输出"
msgid "overlay"
msgstr "覆盖"
msgstr "服务器模式"
msgid "stateful-only"
-msgstr "有状态的"
+msgstr "有状态"
msgid "stateless"
-msgstr "无状态的"
+msgstr "无状态"
msgid "stateless + stateful"
-msgstr "无状态的 + 有状态的"
+msgstr "无状态 + 有状态"
msgid "tagged"
msgstr "已标记"
msgid "Waiting for command to complete..."
msgstr "等待完整性指令..."
-msgid "Waiting for configuration to get applied… %ds"
+msgid "Waiting for configuration to be applied… %ds"
msgstr ""
msgid "Waiting for device..."
or table.concat(luci.dispatcher.context.request, "/")
entry({"admin", "uci"}, nil, _("Configuration"))
- entry({"admin", "uci", "changes"}, call("action_changes"), _("Changes"), 40).query = {redir=redir}
+ entry({"admin", "uci", "changes"}, post_on({ trigger_apply = true }, "action_changes"), _("Changes"), 40).query = {redir=redir}
entry({"admin", "uci", "revert"}, post("action_revert"), _("Revert"), 30).query = {redir=redir}
local node
node.cors = true
node.sysauth_authenticator = authen
- node = entry({"admin", "uci", "confirm"}, post("action_confirm"), nil)
+ node = entry({"admin", "uci", "confirm"}, call("action_confirm"), nil)
node.cors = true
- node.sysauth_authenticator = authen
+ node.sysauth = false
end
local changes = uci:changes()
luci.template.render("admin_uci/changes", {
- changes = next(changes) and changes,
- timeout = timeout
+ changes = next(changes) and changes,
+ timeout = timeout,
+ trigger_apply = luci.http.formvalue("trigger_apply") and true or false
})
end
end
luci.template.render("admin_uci/revert", {
- changes = next(changes) and changes
+ changes = next(changes) and changes,
+ trigger_revert = true
})
end
function action_apply_rollback()
local uci = require "luci.model.uci"
- local _, errstr = uci:apply(true)
- ubus_state_to_http(errstr)
+ local token, errstr = uci:apply(true)
+ if token then
+ luci.http.prepare_content("application/json")
+ luci.http.write_json({ token = token })
+ else
+ ubus_state_to_http(errstr)
+ end
end
function action_apply_unchecked()
function action_confirm()
local uci = require "luci.model.uci"
- local _, errstr = uci:confirm()
+ local token = luci.http.formvalue("token")
+ local _, errstr = uci:confirm(token)
ubus_state_to_http(errstr)
end
<!-- physical device -->
<div class="tr cbi-rowstyle-2">
<div class="td col-2 center middle">
- <span class="ifacebadge"><img src="<%=resource%>/icons/wifi_toggled.png" id="<%=dev:name()%>-iw-upstate" /> <%=dev:name()%></span>
+ <span class="ifacebadge"><img src="<%=resource%>/icons/wifi_disabled.png" id="<%=dev:name()%>-iw-upstate" /> <%=dev:name()%></span>
</div>
<div class="td col-7 left middle">
<big><strong><%=hw%></strong></big><br />
</div>
<% end %>
<% else %>
- <div class="tr cbi-rowstyle-2">
- <div class="td left">
+ <div class="tr placeholder">
+ <div class="td">
<em><%:No network configured on this device%></em>
</div>
</div>
if (!ifc.is_dynamic && !ifc.is_alias)
{
if (ifc.macaddr)
- html += String.format('<strong><%:MAC-Address%>:</strong> %s<br />', ifc.macaddr);
+ html += String.format('<strong><%:MAC%>:</strong> %s<br />', ifc.macaddr);
html += String.format(
'<strong><%:RX%>:</strong> %.2mB (%d <%:Pkts.%>)<br />' +
html += String.format('<strong><%:Uptime%>:</strong> %t<br />', ifc.uptime);
if (ifc.macaddr)
- html += String.format('<strong><%:MAC-Address%>:</strong> %s<br />', ifc.macaddr);
+ html += String.format('<strong><%:MAC%>:</strong> %s<br />', ifc.macaddr);
html += String.format(
'<strong><%:RX%></strong>: %.2mB (%d <%:Pkts.%>)<br />' +
<% end %>
<% if has_dsl then %>
- var dsl_i = document.getElementById('dsl_i');
- var dsl_s = document.getElementById('dsl_s');
-
- var s = String.format(
- '<strong><%:Status%>: </strong>%s<br />' +
- '<strong><%:Line State%>: </strong>%s [0x%x]<br />' +
- '<strong><%:Line Mode%>: </strong>%s<br />' +
- '<strong><%:Annex%>: </strong>%s<br />' +
- '<strong><%:Profile%>: </strong>%s<br />' +
- '<strong><%:Data Rate%>: </strong>%s/s / %s/s<br />' +
- '<strong><%:Max. Attainable Data Rate (ATTNDR)%>: </strong>%s/s / %s/s<br />' +
- '<strong><%:Latency%>: </strong>%s / %s<br />' +
- '<strong><%:Line Attenuation (LATN)%>: </strong>%s dB / %s dB<br />' +
- '<strong><%:Signal Attenuation (SATN)%>: </strong>%s dB / %s dB<br />' +
- '<strong><%:Noise Margin (SNR)%>: </strong>%s dB / %s dB<br />' +
- '<strong><%:Aggregate Transmit Power(ACTATP)%>: </strong>%s dB / %s dB<br />' +
- '<strong><%:Forward Error Correction Seconds (FECS)%>: </strong>%s / %s<br />' +
- '<strong><%:Errored seconds (ES)%>: </strong>%s / %s<br />' +
- '<strong><%:Severely Errored Seconds (SES)%>: </strong>%s / %s<br />' +
- '<strong><%:Loss of Signal Seconds (LOSS)%>: </strong>%s / %s<br />' +
- '<strong><%:Unavailable Seconds (UAS)%>: </strong>%s / %s<br />' +
- '<strong><%:Header Error Code Errors (HEC)%>: </strong>%s / %s<br />' +
- '<strong><%:Non Pre-emtive CRC errors (CRC_P)%>: </strong>%s / %s<br />' +
- '<strong><%:Pre-emtive CRC errors (CRCP_P)%>: </strong>%s / %s<br />' +
- '<strong><%:Line Uptime%>: </strong>%s<br />' +
- '<strong><%:ATU-C System Vendor ID%>: </strong>%s<br />' +
- '<strong><%:Power Management Mode%>: </strong>%s<br />',
- info.dsl.line_state, info.dsl.line_state_detail,
- info.dsl.line_state_num,
- info.dsl.line_mode_s,
- info.dsl.annex_s,
- info.dsl.profile_s,
- info.dsl.data_rate_down_s, info.dsl.data_rate_up_s,
- info.dsl.max_data_rate_down_s, info.dsl.max_data_rate_up_s,
- info.dsl.latency_num_down, info.dsl.latency_num_up,
- info.dsl.line_attenuation_down, info.dsl.line_attenuation_up,
- info.dsl.signal_attenuation_down, info.dsl.signal_attenuation_up,
- info.dsl.noise_margin_down, info.dsl.noise_margin_up,
- info.dsl.actatp_down, info.dsl.actatp_up,
- info.dsl.errors_fec_near, info.dsl.errors_fec_far,
- info.dsl.errors_es_near, info.dsl.errors_es_far,
- info.dsl.errors_ses_near, info.dsl.errors_ses_far,
- info.dsl.errors_loss_near, info.dsl.errors_loss_far,
- info.dsl.errors_uas_near, info.dsl.errors_uas_far,
- info.dsl.errors_hec_near, info.dsl.errors_hec_far,
- info.dsl.errors_crc_p_near, info.dsl.errors_crc_p_far,
- info.dsl.errors_crcp_p_near, info.dsl.errors_crcp_p_far,
- info.dsl.line_uptime_s,
- info.dsl.atuc_vendor_id,
- info.dsl.power_mode_s
- );
-
- dsl_s.innerHTML = String.format('<small>%s</small>', s);
- dsl_i.innerHTML = String.format(
- '<img src="<%=resource%>/icons/ethernet.png" />' +
- '<br /><small>DSL</small>'
- );
+ var ds = document.getElementById('dsl_status_table');
+
+ while (ds.lastElementChild)
+ ds.removeChild(ds.lastElementChild);
+
+ ds.appendChild(renderBox(
+ '<%:DSL Status%>',
+ (info.dsl.line_state === 'UP'), [ ],
+ '<%:Line State%>', '%s [0x%x]'.format(info.dsl.line_state, info.dsl.line_state_detail),
+ '<%:Line Mode%>', info.dsl.line_mode_s || '-',
+ '<%:Line Uptime%>', info.dsl.line_uptime_s || '-',
+ '<%:Annex%>', info.dsl.annex_s || '-',
+ '<%:Profile%>', info.dsl.profile_s || '-',
+ '<%:Data Rate%>', '%s/s / %s/s'.format(info.dsl.data_rate_down_s, info.dsl.data_rate_up_s),
+ '<%:Max. Attainable Data Rate (ATTNDR)%>', '%s/s / %s/s'.format(info.dsl.max_data_rate_down_s, info.dsl.max_data_rate_up_s),
+ '<%:Latency%>', '%s / %s'.format(info.dsl.latency_num_down, info.dsl.latency_num_up),
+ '<%:Line Attenuation (LATN)%>', '%.1f dB / %.1f dB'.format(info.dsl.line_attenuation_down, info.dsl.line_attenuation_up),
+ '<%:Signal Attenuation (SATN)%>', '%.1f dB / %.1f dB'.format(info.dsl.signal_attenuation_down, info.dsl.signal_attenuation_up),
+ '<%:Noise Margin (SNR)%>', '%.1f dB / %.1f dB'.format(info.dsl.noise_margin_down, info.dsl.noise_margin_up),
+ '<%:Aggregate Transmit Power(ACTATP)%>', '%.1f dB / %.1f dB'.format(info.dsl.actatp_down, info.dsl.actatp_up),
+ '<%:Forward Error Correction Seconds (FECS)%>', '%d / %d'.format(info.dsl.errors_fec_near, info.dsl.errors_fec_far),
+ '<%:Errored seconds (ES)%>', '%d / %d'.format(info.dsl.errors_es_near, info.dsl.errors_es_far),
+ '<%:Severely Errored Seconds (SES)%>', '%d / %d'.format(info.dsl.errors_ses_near, info.dsl.errors_ses_far),
+ '<%:Loss of Signal Seconds (LOSS)%>', '%d / %d'.format(info.dsl.errors_loss_near, info.dsl.errors_loss_far),
+ '<%:Unavailable Seconds (UAS)%>', '%d / %d'.format(info.dsl.errors_uas_near, info.dsl.errors_uas_far),
+ '<%:Header Error Code Errors (HEC)%>', '%d / %d'.format(info.dsl.errors_hec_near, info.dsl.errors_hec_far),
+ '<%:Non Pre-emtive CRC errors (CRC_P)%>', '%d / %d'.format(info.dsl.errors_crc_p_near, info.dsl.errors_crc_p_far),
+ '<%:Pre-emtive CRC errors (CRCP_P)%>', '%d / %d'.format(info.dsl.errors_crcp_p_near, info.dsl.errors_crcp_p_far),
+ '<%:ATU-C System Vendor ID%>', info.dsl.atuc_vendor_id,
+ '<%:Power Management Mode%>', info.dsl.power_mode_s));
<% end %>
<% if has_wifi then %>
<div class="cbi-section">
<h3><%:DSL%></h3>
- <div class="table" width="100%">
- <div class="tr">
- <div class="td left" width="33%" style="vertical-align:top"><%:DSL Status%></div>
- <div class="td">
- <div class="table">
- <div class="tr">
- <div class="td" id="dsl_i" style="width:16px; text-align:center; padding:3px"><img src="<%=resource%>/icons/ethernet_disabled.png" /><br /><small>?</small></div>
- <div class="td left" id="dsl_s" style="vertical-align:middle; padding: 3px"><em><%:Collecting data...%></em></div>
- </div>
- </div>
- </div>
- </div>
+ <div id="dsl_status_table" class="network-status-table">
+ <p><em><%:Collecting data...%></em></p>
</div>
</div>
<% end %>
<html>
<head>
- <title><%=luci.sys.hostname()%> - <% if title then %><%=title%><% else %><%:Rebooting...%><% end %></title>
+ <title><%=luci.sys.hostname()%> - <%= title or translate("Rebooting...") %></title>
<link rel="stylesheet" type="text/css" media="screen" href="<%=media%>/cascade.css" />
<script type="text/javascript" src="<%=resource%>/xhr.js"></script>
<script type="text/javascript">//<![CDATA[
var interval = window.setInterval(function() {
var img = new Image();
-
+ var target = ('https:' == document.location.protocol ? 'https://' : 'http://') + <%=addr and "'%s'" % addr or "window.location.host"%>;
+
img.onload = function() {
window.clearInterval(interval);
- location.href = ('https:' == document.location.protocol ? 'https://' : 'http://') + '<%=addr or luci.http.getenv("SERVER_NAME")%>/';
+ window.location.replace(target);
};
-
- img.src = ('https:' == document.location.protocol ? 'https://' : 'http://') + '<%=addr or luci.http.getenv("SERVER_NAME")%><%=resource%>/icons/loading.gif?' + Math.random();
+
+ img.src = target + '<%=resource%>/icons/loading.gif?' + Math.random();
+
}, 5000);
//]]></script>
</head>
<body>
- <div id="maincontainer">
- <div id="maincontent">
- <h2 name="content"><%:System%> - <% if title then %><%=title%><% else %><%:Rebooting...%><% end %></h2>
- <fieldset class="cbi-section">
- <p>
- <% if msg then %><%=msg%><% else %><%:Changes applied.%><% end %>
- </p>
- <p>
- <img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" style="vertical-align:middle" />
- <%:Waiting for changes to be applied...%>
- </p>
- </fieldset>
+ <header>
+ <div class="fill">
+ <div class="container">
+ <p class="brand"><%=luci.sys.hostname() or "?"%></p>
+ </div>
+ </div>
+ </header>
+  
+ <div class="main">
+ <div id="maincontainer">
+ <div id="maincontent" class="container">
+ <h2 name="content" id="applyreboot-container" ><%:System%> - <%= title or translate("Rebooting...") %></h2>
+ <div class="cbi-section" id="applyreboot-section">
+ <div>
+ <%= msg or translate("Changes applied.") %>
+ </div>
+ <div>
+ <img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" style="vertical-align:middle" />
+ <%:Waiting for changes to be applied...%>
+ </div>
+ </div>
+ </div>
</div>
</div>
</body>
-</html>
+</html>
\ No newline at end of file
<div class="cbi-value">
<label class="cbi-value-title"><%:Download and install package%>:</label>
<div class="cbi-value-field">
- <input type="text" name="url" size="30" value="" />
+ <span><input type="text" name="url" size="30" value="" /></span>
<input class="cbi-button cbi-button-save" type="submit" name="go" value="<%:OK%>" />
</div>
</div>
<div class="cbi-value cbi-value-last">
<label class="cbi-value-title"><%:Filter%>:</label>
<div class="cbi-value-field">
- <input type="text" name="query" size="20" value="<%=pcdata(query)%>" />
+ <span><input type="text" name="query" size="20" value="<%=pcdata(query)%>" /></span>
<input type="submit" class="cbi-button cbi-button-action" name="search" value="<%:Find package%>" />
</div>
</div>
<%#
- Copyright 2010 Jo-Philipp Wich <jow@openwrt.org>
+ Copyright 2010 Jo-Philipp Wich <jo@mein.io>
Licensed to the public under the Apache License 2.0.
-%>
<div class="uci-change-list"><%
local util = luci.util
- local ret = { }
+ local tpl = {
+ ["add-3"] = "<ins>uci add %0 <strong>%3</strong> # =%2</ins>",
+ ["set-3"] = "<ins>uci set %0.<strong>%2</strong></ins>=%3",
+ ["set-4"] = "<var><ins>uci set %0.%2.%3=<strong>%4</strong></ins></var>",
+ ["remove-2"] = "<del>uci del %0.<strong>%2</strong></del>",
+ ["remove-3"] = "<var><del>uci del %0.%2.<strong>%3</strong></del></var>",
+ ["order-3"] = "<var>uci reorder %0.%2=<strong>%3</strong></var>",
+ ["list-add-4"] = "<var><ins>uci add_list %0.%2.%3=<strong>%4</strong></ins></var>",
+ ["list-del-4"] = "<var><del>uci del_list %0.%2.%3=<strong>%4</strong></del></var>",
+ ["rename-3"] = "<var>uci rename %0.%2=<strong>%3</strong></var>",
+ ["rename-4"] = "<var>uci rename %0.%2.%3=<strong>%4</strong></var>"
+ }
- for r, tbl in pairs(changes) do
- for s, os in pairs(tbl) do
- -- section add
- if os['.type'] and os['.type'] ~= "" then
- ret[#ret+1] = "<ins>%s.%s=<strong>%s</strong>" %{ r, s, os['.type'] }
- for o, v in util.kspairs(os) do
- if o:sub(1,1) ~= "." then
- if type(v) == "table" then
- local i
- for i = 1, #v do
- ret[#ret+1] = "<br />%s.%s.%s+=<strong>%s</strong>"
- %{ r, s, o, util.pcdata(v[i]) }
- end
- elseif v ~= "" then
- ret[#ret+1] = "<br />%s.%s.%s=<strong>%s</strong>"
- %{ r, s, o, util.pcdata(v) }
- else
- ret[#ret+1] = "<br /><del>%s.%s.<strong>%s</strong></del>" %{ r, s, o }
- end
- end
- end
- ret[#ret+1] = "</ins><br />"
-
- -- section delete
- elseif os['.type'] and os['.type'] == "" then
- ret[#ret+1] = "<del>%s.<strong>%s</strong></del><br />" %{ r, s }
+ local conf, deltas
+ for conf, deltas in util.kspairs(changes) do
+ write("<h3># /etc/config/%s</h3>" % conf)
- -- modifications
- else
- ret[#ret+1] = "<var>%s.%s<br />" %{ r, s }
- for o, v in util.kspairs(os) do
- if o:sub(1,1) ~= "." then
- if v and #v > 0 then
- ret[#ret+1] = "<ins>"
- if type(v) == "table" then
- local i
- for i = 1, #v do
- ret[#ret+1] = "%s.%s.%s+=<strong>%s</strong><br />"
- %{ r, s, o, util.pcdata(v[i]) }
- end
+ local _, delta, added
+ for _, delta in pairs(deltas) do
+ local t = tpl["%s-%d" %{ delta[1], #delta }]
- else
- ret[#ret+1] = "%s.%s.%s=<strong>%s</strong><br />"
- %{ r, s, o, util.pcdata(v) }
- end
- ret[#ret+1] = "</ins>"
- else
- ret[#ret+1] = "<del>%s.%s.<strong>%s</strong><br /></del>" %{ r, s, o }
- end
+ write(t:gsub("%%(%d)", function(n)
+ if n == "0" then
+ return conf
+ elseif n == "2" then
+ if added and delta[2] == added[1] then
+ return "@%s[-1]" % added[2]
+ else
+ return delta[2]
end
+ elseif n == "4" then
+ return util.shellquote(delta[4])
+ else
+ return delta[tonumber(n)]
end
- ret[#ret+1] = "</var><br />"
+ end))
+
+ if delta[1] == "add" then
+ added = { delta[2], delta[3] }
end
end
- end
- write(table.concat(ret))
+ write("<br />")
+ end
%></div>
</div>
<%- end) %>
<%-
local node, redir_url = luci.dispatcher.lookup(luci.http.formvalue("redir"))
+ export("redirect", redir_url or url("admin/uci/changes"))
- include("cbi/apply_widget")
include("admin_uci/changelog")
-
- cbi_apply_widget(redir_url or url("admin/uci/changes"))
-%>
<h2 name="content"><%:Configuration%> / <%:Changes%></h2>
</form>
<% end %>
- <input class="cbi-button cbi-button-save" type="button" id="apply_button" value="<%:Save & Apply%>" onclick="uci_apply(true); this.blur()" />
+ <form method="post" action="<%=url("admin/uci/changes")%>">
+ <input type="hidden" name="token" value="<%=token%>" />
+ <input type="hidden" name="redir" value="<%=pcdata(luci.http.formvalue("redir"))%>" />
+ <input class="cbi-button cbi-button-save" type="submit" name="trigger_apply" value="<%:Save & Apply%>" />
+ </form>
<form method="post" action="<%=url("admin/uci/revert")%>">
<input type="hidden" name="token" value="<%=token%>" />
<input type="hidden" name="redir" value="<%=pcdata(luci.http.formvalue("redir"))%>" />
<%-
local node, redir_url = luci.dispatcher.lookup(luci.http.formvalue("redir"))
+ export("redirect", redir_url or url("admin/uci/changes"))
- include("cbi/apply_widget")
include("admin_uci/changelog")
-
- cbi_apply_widget(redir_url or url("admin/uci/revert"))
-%>
<h2 name="content"><%:Configuration%> / <%:Revert%></h2>
<p><strong><%:There are no pending changes to revert!%></strong></p>
<% end %>
-<div class="alert-message" id="cbi_apply_status" style="display:none"></div>
-<script type="text/javascript">
- document.addEventListener("DOMContentLoaded", function() {
- uci_revert();
- });
-</script>
-
<% if redir_url then %>
<div class="cbi-page-actions">
<form class="inline" method="get" action="<%=luci.util.pcdata(redir_url)%>">
return true
end
+function proto.is_up(self)
+ local iface = self:get_interface()
+ return iface and iface:is_up() or false
+end
+
function proto.get_interface(self)
return device(self.sid, self)
end
return upt
end
+function proto.errors(self)
+ return nil
+end
+
function device.__init__(self, ifname, network)
self.ifname = ifname
padding: 5px;
}
-h1, h2, h3, h4, h5, h6, p, pre, a, abbr, acronym, code, del, em, img, q, s,
+h1, h2, h3, h4, h5, h6, p, pre, a, abbr, acronym, code, del, em, img, ins, q, s,
small, strike, strong, sub, sup, tt, var, dd, dl, dt, li, ol, ul, fieldset,
form, label, legend, button, table, caption, tbody, tfoot, thead, tr, th, td,
.table, .tbody, .tfoot, .thead, .tr, .th, .td {
cursor: default;
}
+select[readonly],
+textarea[readonly] {
+ pointer-events: auto;
+ cursor: auto;
+}
+
.cbi-optionals,
.cbi-section-create {
padding: 0 0 10px 10px;
margin: -.125em;
}
+#dsl_status_table .ifacebox-body > span > strong {
+ display: inline-block;
+ min-width: 35%;
+}
+
.ifacebadge.large,
.network-status-table .ifacebox-body .ifacebadge {
display: inline-flex;
}
.uci-change-list {
- font-family: monospace;
+ line-height: 170%;
+ white-space: pre;
}
+.uci-change-list del,
.uci-change-list ins,
-.uci-change-legend-label ins {
+.uci-change-list var,
+.uci-change-legend-label del,
+.uci-change-legend-label ins,
+.uci-change-legend-label var {
text-decoration: none;
- border: 1px solid #0f0;
- background-color: #cfc;
- display: block;
+ font-family: monospace;
+ font-style: normal;
+ border: 1px solid #ccc;
+ background: #eee;
padding: 2px;
+ display: block;
+ line-height: 15px;
+ margin-bottom: 1px;
+}
+
+.uci-change-list ins,
+.uci-change-legend-label ins {
+ border-color: #0f0;
+ background: #cfc;
}
.uci-change-list del,
.uci-change-legend-label del {
- text-decoration: none;
- border: 1px solid #f00;
- background-color: #fcc;
- display: block;
- font-style: normal;
- padding: 2px;
+ border-color: #f00;
+ background: #fcc;
}
.uci-change-list var,
.uci-change-legend-label var {
- text-decoration: none;
- border: 1px solid #ccc;
- background-color: #eee;
- display: block;
- font-style: normal;
- padding: 2px;
- line-height: 19px;
- white-space: pre;
+ border-color: #ccc;
+ background: #eee;
}
.uci-change-list var ins,
.uci-change-list var del {
- display: inline;
- /*border: none;*/
- white-space: pre;
- font-style: normal;
- padding: 0px;
+ display: inline-block;
+ border: none;
+ width: 100%;
+ padding: 0;
}
.uci-change-legend {
width: 10px;
height: 10px;
display: block;
+ position: relative;
}
.uci-change-legend-label var ins,
.uci-change-legend-label var del {
- line-height: 6px;
border: none;
+ position: absolute;
+ top: 2px;
+ left: 2px;
+ right: 2px;
+ bottom: 2px;
}
html body.apply-overlay-active {
height: calc(100vh - 63px);
}
+
+#applyreboot-section {
+ line-height: 300%;
+}
if tree.nodes[category] and tree.nodes[category].ucidata then
local ucichanges = 0
+ local i, j
for i, j in pairs(require("luci.model.uci").cursor():changes()) do
- for k, l in pairs(j) do
- for m, n in pairs(l) do
- ucichanges = ucichanges + 1;
- end
- end
+ ucichanges = ucichanges + #j
end
if ucichanges > 0 then
margin-right: 2em;
}
+#applyreboot-section {
+ line-height: 300%;
+}
+
.lang_de #submenu_admin_uci {
width: 12em;
}
--- /dev/null
+/**
+ * Material is a clean HTML5 theme for LuCI. It is based on luci-theme-bootstrap and MUI
+ *
+ * luci-theme-material
+ * Copyright 2015 Lutty Yang <lutty@wcan.in>
+ *
+ * Have a bug? Please create an issue here on GitHub!
+ * https://github.com/LuttyYang/luci-theme-material/issues
+ *
+ * luci-theme-bootstrap:
+ * Copyright 2008 Steven Barth <steven@midlink.org>
+ * Copyright 2008 Jo-Philipp Wich <jow@openwrt.org>
+ * Copyright 2012 David Menting <david@nut-bolt.nl>
+ *
+ * MUI:
+ * https://github.com/muicss/mui
+ *
+ * Licensed to the public under the Apache License 2.0
+ */
+
+/*
+ * Font generate by Icomoon<icomoon.io>
+ */
+@font-face {
+ font-family: 'icomoon';
+ src: url('fonts/font.eot');
+ src: url('fonts/font.eot') format('embedded-opentype'),
+ url('fonts/font.ttf') format('truetype'),
+ url('fonts/font.woff') format('woff'),
+ url('fonts/font.svg') format('svg');
+ font-weight: normal;
+ font-style: normal;
+}
+
+.table { display: table; position: relative; }
+.tr { display: table-row; }
+.thead { display: table-header-group; }
+.tbody { display: table-row-group; }
+.tfoot { display: table-footer-group; }
+.td, .th {
+ vertical-align: middle;
+ text-align: center;
+ display: table-cell;
+ padding: .5em;
+}
+
+.th {
+ font-weight: bold;
+}
+
+.tr.placeholder {
+ height: 4em;
+}
+
+.tr.placeholder > .td {
+ position: absolute;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ text-align: center;
+ line-height: 3em;
+ background: inherit;
+}
+
+.table[width="33%"], .th[width="33%"], .td[width="33%"] { width: 33%; }
+.table[width="100%"], .th[width="100%"], .td[width="100%"] { width: 100%; }
+
+.col-1 { flex: 1 1 30px !important; -webkit-flex: 1 1 30px !important; }
+.col-2 { flex: 2 2 60px !important; -webkit-flex: 2 2 60px !important; }
+.col-3 { flex: 3 3 90px !important; -webkit-flex: 3 3 90px !important; }
+.col-4 { flex: 4 4 120px !important; -webkit-flex: 4 4 120px !important; }
+.col-5 { flex: 5 5 150px !important; -webkit-flex: 5 5 150px !important; }
+.col-6 { flex: 6 6 180px !important; -webkit-flex: 6 6 180px !important; }
+.col-7 { flex: 7 7 210px !important; -webkit-flex: 7 7 210px !important; }
+.col-8 { flex: 8 8 240px !important; -webkit-flex: 8 8 240px !important; }
+.col-9 { flex: 9 9 270px !important; -webkit-flex: 9 9 270px !important; }
+.col-10 { flex: 10 10 300px !important; -webkit-flex: 10 10 300px !important; }
+
+.cbi-button-up,
+.cbi-button-down,
+.cbi-value-helpicon,
+.showSide,
+.main > .loading > span {
+ font-family: 'icomoon' !important;
+ speak: none;
+ font-style: normal !important;
+ font-weight: normal !important;
+ font-variant: normal !important;
+ text-transform: none !important;
+ line-height: 1;
+
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+* {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+}
+
+.h1, .h2, .h3, .h4, .h5, .h6, h1, h2, h3, h4, h5, h6 {
+ font-family: inherit;
+ font-weight: 400;
+ line-height: 1.1;
+ color: inherit;
+}
+
+html {
+ -webkit-text-size-adjust: 100%;
+ -ms-text-size-adjust: 100%;
+}
+
+body {
+ font-size: 0.8rem;
+ background-color: #EEE;
+}
+
+html, body {
+ margin: 0px;
+ padding: 0px;
+ height: 100%;
+ font-family: Microsoft Yahei, WenQuanYi Micro Hei, sans-serif, "Helvetica Neue", Helvetica, Hiragino Sans GB;
+}
+
+select {
+ padding: 0.36rem 0.8rem;
+ color: #555;
+ background-color: #fff;
+ background-image: none;
+ border: 1px solid #ccc;
+}
+
+select,
+input,
+.cbi-dropdown {
+ background-color: transparent;
+ color: rgba(0, 0, 0, .87);
+ border: none;
+ border-bottom: 2px solid rgba(0, 0, 0, .26);
+ outline: 0;
+ padding: 0;
+ box-shadow: none;
+ border-radius: 0;
+ background-image: none;
+ height: 1.8rem;
+ font-size: 0.8rem;
+}
+
+select:not([multiple="multiple"]):focus,
+input:focus {
+ border-color: #0099CC;
+}
+
+select[multiple="multiple"] {
+ height: auto;
+}
+
+code {
+ color: #0099CC;
+}
+
+abbr {
+ color: #005470;
+ text-decoration: underline;
+ cursor: help;
+}
+
+hr {
+ margin: 1rem 0;
+ border-color: #EEE;
+ opacity: 0.1;
+}
+
+header, .main {
+ width: 100%;
+ position: absolute;
+}
+
+header {
+ height: 4rem;
+ box-shadow: 0 2px 5px rgba(0, 0, 0, .26);
+ transition: box-shadow .2s;
+ float: left;
+ position: fixed;
+ z-index: 2000;
+}
+
+footer {
+ text-align: right;
+ padding: 1rem;
+ color: #aaa;
+ font-size: 0.8rem;
+ text-shadow: 0px 0px 2px #BBB;
+}
+
+footer > a {
+ color: #aaa;
+ text-decoration: none;
+}
+
+.main {
+ top: 4rem;
+ bottom: 0rem;
+ position: relative;
+ height: 100%;
+ height: calc(100% - 4rem);
+}
+
+.main > .loading {
+ position: fixed;
+ width: 100%;
+ height: 100%;
+ z-index: 1000;
+ display: block;
+ background-color: rgb(240, 240, 240);
+ top: 0;
+}
+
+.main > .loading > span {
+ display: block;
+ text-align: center;
+ margin-top: 2rem;
+ color: #888;
+ font-size: 1.2rem;
+}
+
+.main > .loading > span > .loading-img:before {
+ content: "\e603";
+}
+
+.main > .loading > span > .loading-img {
+ animation: anim-rotate 2s infinite linear;
+ margin-right: 0.2rem;
+ display: inline-block;
+}
+
+@keyframes anim-rotate {
+ 0% {
+ -webkit-transform: rotate(0);
+ -ms-transform: rotate(0);
+ transform: rotate(0);
+ }
+ 100% {
+ -webkit-transform: rotate(360deg);
+ -ms-transform: rotate(360deg);
+ transform: rotate(360deg)
+ }
+}
+
+.main-left {
+ float: left;
+ top: 4rem;
+ width: 15%;
+ width: calc(0% + 15rem);
+ height: 100%;
+ height: calc(100% - 4rem);
+ background-color: white;
+ overflow-x: auto;
+ position: fixed;
+}
+
+.main-right {
+ width: 85%;
+ width: calc(100% - 15rem);
+ float: right;
+ height: 100%;
+ background-color: #EEE;
+}
+
+.main-right > #maincontent {
+ background-color: #EEE;
+}
+
+.pull-right {
+ float: right;
+}
+
+.pull-left {
+ float: left;
+}
+
+header {
+ background: #0099CC;
+ color: white;
+}
+
+header > .fill > .container {
+ margin-top: 0.5rem;
+ padding: 0.5rem 1rem 0 1rem;
+}
+
+header > .fill > .container > .brand {
+ font-size: 1.4rem;
+ color: white;
+ text-decoration: none;
+ cursor: default;
+ vertical-align: text-bottom;
+}
+
+.danger {
+ background-color: #FA8072 !important;
+ color: black;
+}
+
+.warning {
+ background-color: #F0E68C !important;
+ color: black;
+}
+
+.success {
+ background-color: #90EE90 !important;
+ color: black;
+}
+
+.alert-message {
+ margin: 2rem 0 0 0;
+ padding: 1rem;
+ border: 0;
+ font-weight: normal;
+ font-style: normal;
+ line-height: 1;
+ font-family: inherit;
+ min-width: inherit;
+ overflow: auto;
+ border-radius: 0;
+ background-color: #FFF;
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .16), 0 0 2px 0 rgba(0, 0, 0, .12);
+}
+
+.error {
+ color: red;
+}
+
+.alert-message > h4 {
+ font-weight: bold;
+ font-size: 110%;
+}
+
+.alert-message > * {
+ margin: .5rem 0;
+}
+
+#maincontent > .container > div:nth-child(1).alert-message.warning > a {
+ font: inherit;
+ overflow: visible;
+ text-transform: none;
+ display: inline-block;
+ margin-bottom: 0;
+ font-weight: 400;
+ text-align: center;
+ white-space: nowrap;
+ vertical-align: middle;
+ touch-action: manipulation;
+ cursor: pointer;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ background-image: none;
+ min-width: 6rem;
+ padding: 0.5rem 1rem;
+ font-size: 0.9rem;
+ line-height: 1.42857143;
+ color: #fff;
+ background-color: #5bc0de;
+ border-color: #46b8da;
+ margin-top: 2rem;
+ text-decoration: inherit;
+}
+
+.main > .main-left > .nav {
+ margin-top: 0.5rem;
+}
+
+.main > .main-left > .nav > li a {
+ color: #404040;
+ display: block;
+}
+
+.main > .main-left > .nav > li:nth-last-child(1) {
+ margin-top: 2rem;
+ font-size: 1.2rem;
+}
+
+.main > .main-left > .nav > li {
+ padding: 0.5rem 1rem;
+ cursor: pointer;
+}
+
+.main > .main-left > .nav > .slide {
+ padding: 0;
+}
+
+.main > .main-left > .nav > .slide > ul {
+ display: none;
+}
+
+.main > .main-left > .nav > .slide > .menu {
+ display: block;
+ padding: 0.5rem 1rem;
+ text-decoration: none;
+ cursor: default;
+ font-size: 1.15rem;
+}
+
+.main > .main-left > .nav > li:hover,
+.main > .main-left > .nav > .slide > .menu:hover {
+ background: #D4D4D4;
+}
+
+.main > .main-left > .nav > .slide:hover {
+ background: none;
+}
+
+.main > .main-left > .nav > .slide > .slide-menu > li {
+ padding: 0.4rem 2rem;
+}
+
+.main > .main-left > .nav > .slide > .slide-menu > .active {
+ background-color: #0099CC;
+}
+
+.main > .main-left > .nav > .slide > .slide-menu > li > a {
+ text-decoration: none;
+ white-space: nowrap;
+}
+
+.main > .main-left > .nav > .slide > .slide-menu > .active > a {
+ color: white;
+}
+
+.main > .main-left > .nav > .slide > .slide-menu > li:hover {
+ background: #D4D4D4;
+}
+
+.main > .main-left > .nav > .slide > .slide-menu > .active:hover {
+ background-color: #0099CC;
+ cursor: hand;
+}
+
+li {
+ list-style-type: none;
+}
+
+#maincontent > .container {
+ margin: 0 2rem 1rem 2rem;
+}
+
+h1 {
+ font-size: 2rem;
+ padding-bottom: 10px;
+ border-bottom: 1px solid #eee;
+}
+
+h2 {
+ margin: 2rem 0 0 0;
+ font-size: 1.8rem;
+ padding-bottom: 10px;
+ border-bottom: 1px solid #eee;
+}
+
+h3 {
+ margin: 2rem 0 0 0;
+ font-size: 1.4rem;
+ padding-bottom: 10px;
+}
+
+h4 {
+ margin: 2rem 0 0 0;
+ font-size: 1.2rem;
+ padding-bottom: 10px;
+}
+
+.cbi-section {
+ margin: 1rem 0 0 0;
+ padding: 2rem;
+ border: 0;
+ font-weight: normal;
+ font-style: normal;
+ line-height: 1;
+ font-family: inherit;
+ min-width: inherit;
+ border-radius: 0;
+ background-color: #FFF;
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .16), 0 0 2px 0 rgba(0, 0, 0, .12);
+
+ -webkit-overflow-scrolling: touch;
+}
+
+.cbi-map-descr + fieldset {
+ margin-top: 1rem;
+}
+
+.cbi-section > legend {
+ display: none !important;
+}
+
+fieldset > fieldset {
+ margin: 0;
+ padding: 0;
+ border: none;
+ box-shadow: none;
+}
+
+.cbi-section > h3:first-child,
+.panel-title {
+ width: 100%;
+ display: block;
+ line-height: 1;
+ color: #404040;
+ font-size: 1.4rem;
+ padding-bottom: 1rem;
+ border-bottom: 1px solid #eee;
+ margin: 0;
+}
+
+table {
+ border-spacing: 0;
+ border-collapse: collapse;
+}
+
+table, .table {
+ width: 100%;
+ border: 1px solid #eee;
+}
+
+table > tbody > tr > td, table > tbody > tr > th, table > tfoot > tr > td, table > tfoot > tr > th, table > thead > tr > td, table > thead > tr > th,
+.table > .tbody > .tr > .td, .table > .tbody > .tr > .th, .table > .tfoot > .tr > .td, .table > .tfoot > .tr > .th, .table > .thead > .tr > .td, .table > .thead > .tr > .th {
+ padding: .5rem;
+ border-top: 1px solid #ddd;
+ white-space: nowrap;
+}
+
+.cbi-section-table-cell {
+ white-space: nowrap;
+ align-self: flex-end;
+ flex: 1 1 auto;
+}
+
+.cbi-section-table {
+ border: none;
+}
+
+.cbi-section-table-row {
+ text-align: center;
+ margin-bottom: 1rem;
+ background: #f4f4f4;
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .16), 0 0 2px 0 rgba(0, 0, 0, .12);
+}
+
+.cbi-section-table-row:last-child {
+ margin-bottom: 0;
+}
+
+.cbi-section-table-row > .cbi-value-field .cbi-input-select,
+.cbi-section-table-row > .cbi-value-field .cbi-input-text,
+.cbi-section-table-row > .cbi-value-field .cbi-input-password,
+.cbi-section-table-row > .cbi-value-field .cbi-dropdown {
+ width: 100%;
+}
+
+.cbi-section-table-row > .cbi-value-field [data-dynlist] > input,
+.cbi-section-table-row > .cbi-value-field input.cbi-input-password {
+ width: calc(100% - 1.5rem);
+}
+
+div > table > tbody > tr:nth-of-type(2n),
+div > .table > .tbody > .tr:nth-of-type(2n) {
+ background-color: #f9f9f9;
+}
+
+div > table > tbody > tr:nth-of-type(2n),
+div > .table > .tbody > .tr:nth-of-type(2n) {
+ background-color: #f9f9f9;
+}
+
+/* fix progress bar */
+#swaptotal > div,
+#swapfree > div,
+#memfree > div,
+#membuff > div,
+#conns > div,
+#memtotal > div {
+ width: 100% !important;
+ height: 1.2rem !important;
+}
+
+#swaptotal > div > div,
+#swapfree > div > div,
+#memfree > div > div,
+#membuff > div > div,
+#conns > div > div,
+#memtotal > div > div {
+ height: 100% !important;
+ background-color: #0099CC !important;
+}
+
+/* fix multiple table */
+
+table table,
+.table .table {
+ border: none;
+}
+
+.cbi-value-field table,
+.cbi-value-field .table {
+ border: none;
+}
+
+td > table > tbody > tr > td,
+.td > .table > .tbody > .tr > .td {
+ border: none;
+}
+
+.cbi-value-field > table > tbody > tr > td,
+.cbi-value-field > .table > .tbody > .tr > .td {
+ border: none;
+}
+
+/* button style */
+
+.btn, .cbi-button {
+ -webkit-appearance: none;
+ text-transform: uppercase;
+ color: rgba(0, 0, 0, 0.87);
+ background-color: #F0F0F0;
+ transition: all 0.2s ease-in-out;
+ display: inline-block;
+ padding: 0 0.8rem;
+ border: none;
+ border-radius: 0.2rem;
+ cursor: pointer;
+ -ms-touch-action: manipulation;
+ touch-action: manipulation;
+ background-image: none;
+ text-align: center;
+ vertical-align: middle;
+ white-space: nowrap;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ font-size: 0.8rem;
+ width: auto !important;
+ display: inline-block;
+ text-decoration: none;
+}
+
+.btn:hover,
+.btn:focus,
+.btn:active,
+.cbi-button:hover,
+.cbi-button:focus,
+.cbi-button:active,
+.cbi-page-actions .cbi-button-apply + .cbi-button-save:hover,
+.cbi-page-actions .cbi-button-apply + .cbi-button-save:focus,
+.cbi-page-actions .cbi-button-apply + .cbi-button-save:active {
+ outline: 0;
+ text-decoration: none;
+ background-color: rgba(250, 250, 250, 0.7);
+}
+
+.btn:hover,
+.btn:focus,
+.cbi-button:hover,
+.cbi-button:focus {
+ box-shadow: 0 0px 2px rgba(0, 0, 0, 0.12), 0 2px 2px rgba(0, 0, 0, 0.2);
+}
+
+.btn:active,
+.cbi-button:active {
+ box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23);
+}
+
+.btn:disabled,
+.cbi-button:disabled {
+ cursor: not-allowed;
+ pointer-events: none;
+ opacity: 0.60;
+ box-shadow: none;
+}
+
+.cbi-page-actions .cbi-button-apply,
+.cbi-section-actions .cbi-button-edit,
+.cbi-button-edit.important,
+.cbi-button-apply.important,
+.cbi-button-reload.important,
+.cbi-button-action.important {
+ color: #fff;
+ background-color: #337ab7;
+}
+
+.cbi-page-actions .cbi-button-save,
+.cbi-button-add.important,
+.cbi-button-save.important,
+.cbi-button-positive.important {
+ color: #fff;
+ background-color: #5bc0de;
+}
+
+.cbi-button-remove.important,
+.cbi-button-reset.important,
+.cbi-button-negative.important {
+ color: #fff;
+ background-color: #d9534f;
+}
+
+.cbi-button-find,
+.cbi-button-link,
+.cbi-button-up,
+.cbi-button-down,
+.cbi-button-neutral {
+ border: 1px solid #bfbfbf;
+ background-color: transparent;
+}
+
+.cbi-button-edit,
+.cbi-button-apply,
+.cbi-button-reload,
+.cbi-button-action {
+ color: #2e6da4;
+ border: 1px solid #2e6da4;
+ background-color: transparent;
+}
+
+.cbi-page-actions .cbi-button-apply + .cbi-button-save,
+.cbi-button-add,
+.cbi-button-save,
+.cbi-button-positive {
+ color: #46b8da;
+ border: 1px solid #46b8da;
+ background-color: transparent;
+}
+
+.cbi-section-remove > .cbi-button,
+.cbi-button-remove,
+.cbi-button-reset,
+.cbi-button-negative {
+ color: #d43f3a;
+ border: 1px solid #d43f3a;
+ background-color: transparent;
+}
+
+.cbi-page-actions .cbi-button-link:first-child {
+ float: left;
+}
+
+.a-to-btn {
+ text-decoration: none;
+}
+
+/* table */
+
+.tabs {
+ margin: 0 -2rem;
+ padding-left: 0.5rem;
+ background-color: #FFFFFF;
+}
+
+.cbi-tabmenu > li,
+.tabs > li {
+ display: inline-block;
+ padding: 0.6rem 0rem;
+}
+
+.cbi-tabmenu > li > a,
+.tabs > li > a {
+ text-decoration: none;
+ color: #404040;
+ padding: 0.5rem 0.8rem;
+}
+
+.tabs > li[class~="active"],
+.tabs > li:hover {
+ cursor: pointer;
+ border-bottom: 0.2rem solid #0099CC;
+ color: #0099CC;
+ margin-bottom: -0.18751rem;
+}
+
+.tabs > li[class~="active"] > a {
+ color: #0099cc;
+}
+
+.tabs > li:hover {
+ border-bottom: 0.18751rem solid #C9C9C9;
+}
+
+.cbi-tabmenu {
+ border-top: 1px solid #D4D4D4;
+ border-left: 1px solid #D4D4D4;
+ border-right: 1px solid #D4D4D4;
+}
+
+.cbi-tabmenu > li:hover {
+ background-color: #F1F1F1;
+}
+
+.cbi-tabmenu > li[class~="cbi-tab"] {
+ background-color: white;
+}
+
+.cbi-tabmenu {
+ background-color: #D4D4D4;
+}
+
+.cbi-section-remove:nth-of-type(2n),
+.cbi-section-node:nth-of-type(2n){
+ background-color: #f9f9f9;
+}
+
+.cbi-section-node-tabbed {
+ padding: 0;
+ margin-top: 0;
+ border-bottom: 1px solid #D4D4D4;
+ border-left: 1px solid #D4D4D4;
+ border-right: 1px solid #D4D4D4;
+}
+
+.cbi-tabcontainer > .cbi-value:nth-of-type(2n) {
+ background-color: #f9f9f9;
+}
+
+.cbi-value-field,
+.cbi-value-description {
+ display: table-cell;
+ line-height: 1.25;
+}
+
+.cbi-value-helpicon > img {
+ display: none;
+}
+
+.cbi-value-helpicon:before {
+ content: "\f059";
+}
+
+.cbi-value-description {
+ font-size: small;
+ opacity: 0.5;
+ padding: 0.5rem 0 0 0;
+}
+
+.cbi-value-title {
+ word-wrap: break-word;
+ padding-top: 0.6rem;
+ width: 23rem;
+ float: left;
+ text-align: right;
+ padding-right: 2rem;
+ display: table-cell;
+}
+
+.cbi-value {
+ padding: 0.3rem 1rem;
+ display: inline-block;
+ width: 100%;
+}
+
+.cbi-section-table-descr > .cbi-section-table-cell,
+.cbi-section-table-titles > .cbi-section-table-cell {
+ border: none;
+}
+
+.td[data-title]::before {
+ content: attr(data-title) ":\20";
+ font-weight: bold;
+ text-align: left;
+ display: none;
+ padding: .25rem 0;
+ white-space: nowrap;
+}
+
+.tr.placeholder .td[data-title]::before {
+ display: none;
+}
+
+.tr[data-title]::before,
+.tr.cbi-section-table-titles.named::before {
+ content: attr(data-title) "\20";
+ font-weight: bold;
+ text-align: center;
+ display: table-cell;
+ align-self: center;
+ flex: 1 1 5%;
+ padding: .25rem;
+ white-space: normal;
+ word-wrap: break-word;
+ vertical-align: middle;
+}
+
+.cbi-rowstyle-1 {
+ background-color: #f9f9f9;
+}
+
+.cbi-rowstyle-2 {
+ background-color: #eee;
+}
+
+.cbi-rowstyle-2 .cbi-button-up,
+.cbi-rowstyle-2 .cbi-button-down {
+ background-color: #FFF !important;
+}
+
+.cbi-section-table .cbi-section-table-titles .cbi-section-table-cell {
+ width: auto !important;
+}
+
+.td.cbi-section-actions {
+ text-align: right;
+ vertical-align: middle;
+}
+
+.td.cbi-section-actions > * {
+ display: flex;
+}
+
+.td.cbi-section-actions > * > *,
+.td.cbi-section-actions > * > form > * {
+ flex: 1 1 4em;
+ margin: 0 1px;
+}
+
+.td.cbi-section-actions > * > form {
+ display: inline-flex;
+ margin: 0;
+}
+
+/* desc */
+.cbi-section-descr,
+.cbi-map-descr {
+ padding: 0.5rem;
+ color: #999;
+ font-size: small;
+}
+
+
+.cbi-dropdown {
+ display: inline-flex;
+ cursor: pointer;
+ position: relative;
+ padding: 0;
+ height: auto;
+}
+
+.cbi-dropdown:focus {
+ outline: 2px solid #4b6e9b;
+}
+
+.cbi-dropdown > ul {
+ margin: 0 !important;
+ padding: 0;
+ list-style: none;
+ overflow-x: hidden;
+ overflow-y: auto;
+ display: flex;
+ width: 100%;
+}
+
+.cbi-dropdown > ul.preview {
+ display: none;
+}
+
+.cbi-dropdown > .open {
+ border: 2px outset #eee;
+ flex-basis: 15px;
+ background: #eee;
+}
+
+.cbi-dropdown > .open,
+.cbi-dropdown > .more {
+ flex-grow: 0;
+ flex-shrink: 0;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ text-align: center;
+ line-height: 2em;
+ padding: 0 .25em;
+}
+
+.cbi-dropdown > .more,
+.cbi-dropdown > ul > li[placeholder] {
+ color: #777;
+ font-weight: bold;
+ text-shadow: 1px 1px 0px #fff;
+ display: none;
+}
+
+.cbi-dropdown > ul > li {
+ display: none;
+ padding: .25em;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ flex-shrink: 1;
+ flex-grow: 1;
+ align-items: center;
+ align-self: center;
+ min-height: 20px;
+}
+
+.cbi-dropdown > ul > li .hide-open { display: initial; }
+.cbi-dropdown > ul > li .hide-close { display: none; }
+
+.cbi-dropdown > ul > li[display]:not([display="0"]) {
+ border-left: 1px solid #ccc;
+}
+
+.cbi-dropdown[empty] > ul {
+ max-width: 1px;
+}
+
+.cbi-dropdown > ul > li > form {
+ display: none;
+ margin: 0;
+ padding: 0;
+ pointer-events: none;
+}
+
+.cbi-dropdown > ul > li img {
+ vertical-align: middle;
+ margin-right: .25em;
+}
+
+.cbi-dropdown > ul > li > form > input[type="checkbox"] {
+ margin: 0;
+ height: auto;
+}
+
+.cbi-dropdown > ul > li input[type="text"] {
+ height: 20px;
+}
+
+.cbi-dropdown[open] {
+ position: relative;
+}
+
+.cbi-dropdown[open] > ul.dropdown {
+ display: block;
+ background: #f6f6f5;
+ border: 1px solid #918e8c;
+ box-shadow: 0 0 4px #918e8c;
+ position: absolute;
+ z-index: 1000;
+ max-width: none;
+ min-width: 100%;
+ width: auto;
+}
+
+.cbi-dropdown > ul > li[display],
+.cbi-dropdown[open] > ul.preview,
+.cbi-dropdown[open] > ul.dropdown > li,
+.cbi-dropdown[multiple] > ul > li > label,
+.cbi-dropdown[multiple][open] > ul.dropdown > li,
+.cbi-dropdown[multiple][more] > .more,
+.cbi-dropdown[multiple][empty] > .more {
+ flex-grow: 1;
+ display: flex;
+ align-items: center;
+}
+
+.cbi-dropdown[empty] > ul > li,
+.cbi-dropdown[optional][open] > ul.dropdown > li[placeholder],
+.cbi-dropdown[multiple][open] > ul.dropdown > li > form {
+ display: block;
+}
+
+.cbi-dropdown[open] > ul.dropdown > li .hide-open { display: none; }
+.cbi-dropdown[open] > ul.dropdown > li .hide-close { display: initial; }
+
+.cbi-dropdown[open] > ul.dropdown > li {
+ border-bottom: 1px solid #ccc;
+}
+
+.cbi-dropdown[open] > ul.dropdown > li[selected] {
+ background: #b0d0f0;
+}
+
+.cbi-dropdown[open] > ul.dropdown > li.focus {
+ background: linear-gradient(90deg, #a3c2e8 0%, #84aad9 100%);
+}
+
+.cbi-dropdown[open] > ul.dropdown > li:last-child {
+ margin-bottom: 0;
+ border-bottom: none;
+}
+
+.cbi-dropdown[disabled] {
+ pointer-events: none;
+ opacity: .6;
+}
+
+.cbi-dropdown .zonebadge {
+ width: 100%;
+}
+
+.cbi-dropdown[open] .zonebadge {
+ width: auto;
+}
+
+
+/* luci */
+
+.hidden {
+ display: none
+}
+
+.left, .left::before {
+ text-align: left !important;
+}
+
+.right, .right::before {
+ text-align: right !important;
+}
+
+.center, .center::before {
+ text-align: center !important;
+}
+
+.top {
+ align-self: flex-start !important;
+ vertical-align: top !important;
+}
+
+.bottom {
+ align-self: flex-end !important;
+ vertical-align: bottom !important;
+}
+
+.inline {
+ display: inline;
+}
+
+.cbi-page-actions {
+ border-top: 1px solid #eee;
+ padding-top: 1rem;
+ text-align: right;
+}
+
+/* input */
+.cbi-value input[type="password"],
+.cbi-value input[type="text"] {
+ min-width: 15rem;
+}
+
+/* select */
+.cbi-value-field .cbi-dropdown {
+ min-width: 15rem;
+}
+
+.cbi-value-field .cbi-input-select {
+ width: 15rem;
+}
+
+.th[data-type="button"], .td[data-type="button"],
+.th[data-type="fvalue"], .td[data-type="fvalue"] {
+ flex: 1 1 2em;
+ text-align: center;
+}
+
+.ifacebadge {
+ display: inline-flex;
+ border-bottom: 1px solid #CCCCCC;
+ padding: 0.5rem 1rem;
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
+ background: #fff;
+}
+
+td > .ifacebadge,
+.td > .ifacebadge {
+ background-color: #F0F0F0;
+ font-size: 0.9rem;
+}
+
+.ifacebadge > em,
+.ifacebadge > img {
+ display: inline-block;
+ margin: 0 .2rem;
+ align-self: flex-start;
+}
+
+.ifacebadge > img + img {
+ margin: 0 .2rem 0 0;
+}
+
+.network-status-table {
+ display: flex;
+ flex-wrap: wrap;
+}
+
+.network-status-table .ifacebox {
+ margin: .5em;
+ flex-grow: 1;
+}
+
+.network-status-table .ifacebox-body {
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+}
+
+.network-status-table .ifacebox-body > span {
+ flex: 10 10 auto;
+}
+
+.network-status-table .ifacebox-body > div {
+ display: flex;
+ flex-wrap: wrap;
+}
+
+.network-status-table .ifacebox-body .ifacebadge {
+ flex: 1 1 auto;
+ margin: .5em .25em 0 .25em;
+ padding: .5em;
+ min-width: 220px;
+ background-color: #fff;
+ align-items: center;
+}
+
+/*textarea*/
+
+.cbi-input-textarea {
+ width: 100%;
+ min-height: 14rem;
+ padding: 0.8rem;
+ font-size: 0.8rem;
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ color: black;
+}
+
+#syslog {
+ width: 100%;
+ min-height: 15rem;
+ padding: 1rem;
+ font-size: small;
+ color: #5F5F5F;
+
+ margin-bottom: 20px;
+ border-radius: 0;
+ background-color: #FFF;
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .16), 0 0 2px 0 rgba(0, 0, 0, .12);
+ border: none;
+}
+
+/* change */
+
+.uci-change-list {
+ font-family: monospace;
+}
+
+.uci-change-list ins,
+.uci-change-legend-label ins {
+ text-decoration: none;
+ border: 1px solid #00FF00;
+ background-color: #CCFFCC;
+ display: block;
+ padding: 2px;
+}
+
+.uci-change-list del,
+.uci-change-legend-label del {
+ text-decoration: none;
+ border: 1px solid #FF0000;
+ background-color: #FFCCCC;
+ display: block;
+ font-style: normal;
+ padding: 2px;
+}
+
+.uci-change-list var,
+.uci-change-legend-label var {
+ text-decoration: none;
+ border: 1px solid #CCCCCC;
+ background-color: #EEEEEE;
+ display: block;
+ font-style: normal;
+ padding: 2px;
+}
+
+.uci-change-list var ins,
+.uci-change-list var del {
+ border: none;
+ white-space: pre;
+ font-style: normal;
+ padding: 0px;
+}
+
+.uci-change-legend {
+ padding: 5px;
+}
+
+.uci-change-legend-label {
+ width: 150px;
+ float: left;
+}
+
+.uci-change-legend-label > ins,
+.uci-change-legend-label > del,
+.uci-change-legend-label > var {
+ float: left;
+ margin-right: 4px;
+ width: 10px;
+ height: 10px;
+ display: block;
+}
+
+.uci-change-legend-label var ins,
+.uci-change-legend-label var del {
+ line-height: 6px;
+ border: none;
+}
+
+.uci-change-list var,
+.uci-change-list del,
+.uci-change-list ins {
+ padding: 0.5rem;
+}
+
+/* other fix */
+#iwsvg,
+#iwsvg2,
+#bwsvg {
+ border: 1px solid #D4D4D4 !important;
+ border-top: none !important;
+}
+
+.ifacebox {
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 1px 2px rgba(0, 0, 0, 0.2);
+ border-bottom: 1px solid #ccc;
+ background-color: #f9f9f9;
+ display: inline-flex;
+ flex-direction: column;
+ line-height: 1.2em;
+ min-width: 100px;
+}
+
+.ifacebox-head {
+ padding: .25em;
+ background: #eee;
+}
+
+.ifacebox-head.active {
+ background: #90c0e0;
+}
+
+.ifacebox-body {
+ padding: .25em;
+}
+
+.cbi-image-button {
+ margin-left: 0.5rem;
+}
+
+.zonebadge {
+ padding: 0.2rem 0.5rem;
+ display: inline-block;
+}
+
+.zonebadge .ifacebadge {
+ padding: .2rem .3rem;
+ margin: 0.1rem 0.2rem;
+ border: 1px solid #6C6C6C;
+}
+
+.zonebadge > input[type="text"] {
+ padding: 0.16rem 1rem;
+ min-width: 10rem;
+ margin-top: 0.3rem;
+}
+
+.zonebadge > em,
+.zonebadge > strong {
+ margin: 0 0.2rem;
+ display: inline-block;
+}
+
+.cbi-value-field .cbi-input-checkbox,
+.cbi-value-field .cbi-input-radio {
+ margin-top: 0.5rem;
+ height: 1rem;
+}
+
+.td .cbi-input-checkbox,
+.td .cbi-input-radio {
+ margin-top: 0;
+}
+
+.cbi-value-field > input + .cbi-value-description {
+ padding: 0;
+}
+
+.cbi-value-field > ul > li {
+ display: flex;
+}
+
+.cbi-value-field > ul > li > label {
+ margin-top: 0.5rem;
+}
+
+.cbi-value-field > ul > li .ifacebadge {
+ background-color: #eee;
+ margin-left: 0.4rem;
+ margin-top: -0.5rem;
+}
+
+.cbi-section-table-row > .cbi-value-field .cbi-dropdown {
+ min-width: 7rem;
+}
+
+.cbi-section-create {
+ margin: .5rem -3px;
+ display: inline-flex;
+ align-items: center;
+}
+
+.cbi-section-create > * {
+ margin: 0.5rem;
+}
+
+.cbi-section-remove {
+ padding: 0.5rem;
+}
+
+div.cbi-value var, td.cbi-value-field var, .td.cbi-value-field var {
+ font-style: italic;
+ color: #0069D6;
+}
+
+small {
+ font-size: 90%;
+ white-space: normal;
+ line-height: 1.42857143;
+}
+
+.cbi-button-up,
+.cbi-button-down {
+ display: inline-block;
+ min-width: 0;
+ padding: 0.2rem 0.3rem;
+ font-size: 1.2rem;
+}
+
+.cbi-optionals {
+ padding: 1rem 1rem 0 1rem;
+ border-top: 1px solid #CCC;
+}
+
+.cbi-dropdown-container {
+ position: relative;
+}
+
+.cbi-tooltip-container {
+ cursor: help;
+}
+
+.cbi-tooltip {
+ position: absolute;
+ z-index: 1000;
+ left: -1000px;
+ opacity: 0;
+ transition: opacity .25s ease-out;
+ pointer-events: none;
+ box-shadow: 0 0 2px #444;
+}
+
+.cbi-tooltip-container:hover .cbi-tooltip {
+ left: auto;
+ opacity: 1;
+ transition: opacity .25s ease-in;
+}
+
+.zonebadge .cbi-tooltip {
+ padding: .25rem;
+ background: inherit;
+ margin: -1.5rem 0 0 -.5rem;
+}
+
+.zonebadge-empty {
+ background: repeating-linear-gradient(45deg,rgba(204,204,204,0.5),rgba(204,204,204,0.5) 5px,rgba(255,255,255,0.5) 5px,rgba(255,255,255,0.5) 10px);
+ color: #404040;
+}
+
+.zone-forwards {
+ display: flex;
+ min-width: 10rem;
+}
+
+.zone-forwards > * {
+ flex: 1 1 45%;
+}
+
+.zone-forwards > span {
+ flex-basis: 10%;
+ text-align: center;
+ padding: 0 .25rem;
+}
+
+.zone-forwards .zone-src,
+.zone-forwards .zone-dest {
+ display: flex;
+ flex-direction: column;
+}
+
+#diag-rc-output > pre {
+ background-color: #f5f5f5;
+ display: block;
+ padding: 8.5px;
+ margin: 0 0 18px;
+ line-height: 1.5rem;
+ -moz-border-radius: 3px;
+ white-space: pre-wrap;
+ word-wrap: break-word;
+ font-size: 1.4rem;
+ color: #404040;
+}
+
+input[name="ping"],
+input[name="traceroute"],
+input[name="nslookup"] {
+ width: 80%;
+}
+
+header > .container > .pull-right > * {
+ position: relative;
+ top: 0.45rem;
+ cursor: pointer;
+}
+
+#xhr_poll_status > .label.success {
+ background-color: #14CE14;
+}
+
+.label {
+ padding: 0.3rem 0.8rem;
+ font-size: 0.8rem;
+ font-weight: bold;
+ color: #ffffff !important;
+ text-transform: uppercase;
+ white-space: nowrap;
+ background-color: #bfbfbf;
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ border-radius: 3px;
+ text-shadow: none;
+ text-decoration: none;
+}
+
+.notice {
+ background-color: #5BC0DE;
+}
+
+.showSide {
+ display: none;
+}
+
+.darkMask {
+ width: 100%;
+ height: 100%;
+ position: fixed;
+ background-color: rgba(0, 0, 0, 0.56);
+ content: "";
+ z-index: 99;
+ display: none;
+}
+
+/* fix Main Login*/
+.node-main-login > .main > .main-left {
+ display: none;
+}
+
+.node-main-login > .main > .main-right {
+ width: 100%;
+}
+
+.node-main-login > .main fieldset {
+ padding: 0.5rem;
+ margin-bottom: 1rem;
+ display: inline;
+ background: none;
+ border: none;
+ box-shadow: none;
+ overflow: hidden;
+}
+
+.node-main-login > .main .cbi-value-title {
+ width: 7rem;
+}
+
+.node-main-login > .main #maincontent {
+
+ text-align: center;
+}
+
+.node-main-login > .main .container {
+ display: inline-block;
+ padding: 2rem 4rem;
+ margin-top: 2rem !important;
+ background-color: #FFF;
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .16), 0 0 2px 0 rgba(0, 0, 0, .12);
+ text-align: left;
+}
+
+.node-main-login > .main form > div:nth-last-child(1) {
+ float: right;
+}
+
+.node-main-login > .main .cbi-value {
+ display: block;
+}
+
+.node-main-login > .main .cbi-value > * {
+ display: inline-block !important;
+}
+
+.node-main-login > .main .cbi-input-user,
+.node-main-login > .main .cbi-input-password {
+ min-width: 15rem;
+}
+
+.node-main-login footer {
+ bottom: 0;
+ position: absolute;
+ width: 100%;
+}
+
+/* fix status overview */
+
+.node-status-overview > .main fieldset:nth-child(4) .td:nth-child(2) {
+ white-space: normal;
+}
+
+/* fix status processes */
+
+.node-status-processes > .main .table .tr .td:nth-child(3) {
+ white-space: normal;
+}
+
+.node-status-iptables > .main div > .cbi-map > form {
+ margin: 2rem 2rem 0 0;
+}
+
+/* fix system reboot */
+
+.node-system-reboot > .main > .main-right p,
+.node-system-reboot > .main > .main-right h3 {
+ padding-left: 2rem;
+}
+
+/* fix Services Network Shares*/
+.node-services-samba > .main .cbi-tabcontainer:nth-child(3) .cbi-value-title {
+ margin-bottom: 1rem;
+ width: auto;
+}
+
+.node-services-samba > .main .cbi-tabcontainer:nth-child(3) .cbi-value-field {
+ display: list-item;
+}
+
+.node-services-samba > .main .cbi-tabcontainer:nth-child(3) .cbi-value-description {
+ padding-top: 1rem;
+}
+
+/* fix System Software*/
+.node-system-packages > .main table tr td:nth-child(1) {
+ width: auto !important;
+}
+
+.node-system-packages > .main table tr td:nth-last-child(1) {
+ white-space: normal;
+ font-size: small;
+ color: #404040;
+}
+
+.node-system-packages > .main .cbi-tabmenu > li > a, .tabs > li > a {
+ padding: 0.5rem 0.8rem;
+}
+
+.node-system-packages > .main .cbi-value > pre {
+ background-color: #eee;
+ padding: 0.5rem;
+ overflow: auto;
+}
+
+.cbi-tabmenu + .cbi-section {
+ margin-top: 0;
+}
+
+.node-status-iptables fieldset,
+.node-system-packages fieldset,
+.node-system-flashops fieldset {
+ margin-top: 0;
+}
+
+.node-status-iptables .cbi-tabmenu,
+.node-system-packages .cbi-tabmenu,
+.node-system-flashops .cbi-tabmenu {
+ border: none;
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .16), 0 0 2px 0 rgba(0, 0, 0, .12);
+}
+
+.node-system-flashops form.inline + form.inline {
+ margin-left: 0;
+}
+
+#cbi-firewall-redirect table *,
+#cbi-network-switch_vlan table *,
+#cbi-firewall-zone table * {
+ font-size: small;
+}
+
+#cbi-firewall-redirect table input[type="text"],
+#cbi-network-switch_vlan table input[type="text"],
+#cbi-firewall-zone table input[type="text"] {
+ width: 5rem;
+}
+
+#cbi-firewall-redirect table select,
+#cbi-network-switch_vlan table select,
+#cbi-firewall-zone table select {
+ min-width: 3.5rem;
+}
+
+#cbi-network-switch_vlan .th,
+#cbi-network-switch_vlan .td {
+ flex-basis: 12%;
+}
+
+/* language fix */
+body.lang_pl.node-main-login .cbi-value-title {
+ width: 12rem;
+}
+
+/* applyreboot fix */
+
+#applyreboot-container {
+ margin: 2rem;
+}
+
+#applyreboot-section {
+ margin: 2rem;
+ line-height: 300%;
+}
+
+@media screen and (max-width: 1600px) {
+ .main-left {
+ width: calc(0% + 13rem);
+ }
+
+ .main-right {
+ width: calc(100% - 13rem);
+ }
+
+ .btn,
+ .cbi-button {
+ padding: 0.3rem 0.6rem;
+ font-size: 0.8rem;
+ }
+
+ header > .container > .pull-right > * {
+ top: 0.35rem;
+ }
+
+ .label {
+ padding: 0.2rem 0.6rem;
+ }
+
+ .cbi-value-title {
+ width: 15rem;
+ padding-right: 0.6rem;
+ }
+
+ fieldset {
+ padding: 1rem;
+ }
+
+ .cbi-input-textarea {
+ font-size: small;
+ }
+
+ .node-status-iptables > .main fieldset li > a {
+ padding: 0.3rem 0.6rem;
+ }
+}
+
+@media screen and (max-width: 1280px) {
+ header {
+ height: 3.5rem;
+ }
+
+ header > .container {
+ margin-top: 0.25rem;
+ }
+
+ .main {
+ top: 3.5rem;
+ height: calc(100% - 3.5rem);
+ }
+
+ .main-left {
+ width: calc(0% + 13rem);
+ top: 3.5rem;
+ height: calc(100% - 3.5rem);
+ }
+
+ .main-right {
+ width: calc(100% - 13rem);
+ }
+
+ .cbi-tabmenu > li > a, .tabs > li > a {
+ padding: 0.2rem 0.5rem;
+ }
+
+ .panel-title {
+ font-size: 1.1rem;
+ padding-bottom: 1rem;
+ }
+
+ table {
+ font-size: 0.7rem !important;
+ width: 100% !important;
+ }
+
+ .main > .main-left > .nav > li,
+ .main > .main-left > .nav > li a,
+ .main > .main-left > .nav > .slide > .menu {
+ font-size: 0.9rem;
+ }
+
+ .main > .main-left > .nav > .slide > .slide-menu > li > a {
+ font-size: 0.7rem;
+ }
+}
+
+@media screen and (max-width: 992px) {
+ .main-left {
+ width: 0;
+ position: fixed;
+ z-index: 100;
+ }
+
+ .main-right {
+ width: 100%;
+ }
+
+ .showSide {
+ padding: 0.1rem;
+ margin-right: 0.5rem;
+ display: inline-block;
+ }
+
+ .showSide:before {
+ content: "\e20e";
+ font-size: 1.7rem;
+ }
+
+ .node-main-login .showSide {
+ display: none !important;
+ }
+
+ .cbi-value-title {
+ width: 9rem;
+ padding-right: 1rem;
+ }
+
+ .node-network-diagnostics > .main .cbi-map fieldset > div * {
+ width: 100% !important;
+ }
+
+ .node-network-diagnostics > .main .cbi-map fieldset > div input[type="text"] {
+ margin: 3rem 0 0 0 !important;
+ }
+
+ .node-network-diagnostics > .main .cbi-map fieldset > div:nth-child(4) input[type="text"] {
+ margin: 0 !important;
+ }
+
+ .node-network-diagnostics > .main .cbi-map fieldset > div select,
+ .node-network-diagnostics > .main .cbi-map fieldset > div input[type="button"] {
+ margin: 1rem 0 0 0;
+ }
+
+ .node-network-diagnostics > .main .cbi-map fieldset > div {
+ width: 100% !important;
+ }
+
+ #diag-rc-output > pre {
+ font-size: 1rem;
+ }
+
+ .node-main-login > .main .cbi-value-title {
+ text-align: left;
+ }
+
+ .tr {
+ display: flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+ }
+
+ .th, .td {
+ flex: 2 2 25%;
+ align-self: flex-start;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ word-wrap: break-word;
+ display: inline-block;
+ }
+
+ .td select,
+ .td input[type="text"] {
+ word-wrap: normal;
+ width: 100%;
+ }
+
+ .td [data-dynlist] > input,
+ .td input.cbi-input-password {
+ width: calc(100% - 1.5rem);
+ }
+
+ .td[data-type="button"],
+ .td[data-type="fvalue"] {
+ flex: 1 1 12.5%;
+ text-align: left;
+ }
+
+ .th.cbi-value-field,
+ .td.cbi-value-field,
+ .th.cbi-section-table-cell,
+ .td.cbi-section-table-cell {
+ flex-basis: auto;
+ }
+
+ .cbi-section-table-row {
+ display: flex;
+ flex-wrap: wrap;
+ flex-direction: row;
+ justify-content: space-between;
+ }
+
+ .td.cbi-value-field,
+ .cbi-section-table-cell {
+ text-align: center;
+ display: inline-block;
+ flex: 10 10 auto;
+ }
+
+ .td.cbi-section-actions {
+ text-align: right;
+ align-self: flex-end;
+ vertical-align: bottom;
+ }
+
+ .tr.table-titles,
+ .tr.cbi-section-table-titles,
+ .tr.cbi-section-table-descr {
+ display: none;
+ }
+
+ .tr[data-title]::before,
+ .tr.cbi-section-table-titles.named::before {
+ display: block;
+ flex: 1 1 100%;
+ background: #eef;
+ font-size: .9rem;
+ border-bottom: 1px solid rgba(0, 0, 0, .26);
+ }
+
+ .td[data-title] {
+ text-align: left;
+ }
+
+ .td[data-title]::before {
+ display: block;
+ }
+
+ .hide-sm,
+ .hide-xs {
+ display: none;
+ }
+}
+
+@media screen and (max-width: 480px) {
+ body {
+ font-size: 1rem;
+ }
+
+ fieldset {
+ padding: 1rem;
+ margin: 1rem 0 0 0;
+ }
+
+ .tabs {
+ margin: 0 -1rem;
+ }
+
+ #maincontent > .container {
+ margin: 0 1rem 1.5rem 1rem;
+ }
+
+ .main > .main-left > .nav > .slide > .menu {
+ font-size: 1.3rem;
+ }
+
+ .main > .main-left > .nav > .slide > .slide-menu > li > a {
+ font-size: 1.1rem;
+ }
+
+ .cbi-value-title {
+ width: 100%;
+ min-width: 0rem !important;
+ display: block;
+ margin-top: 1rem;
+ margin-bottom: 0.5rem;
+ text-align: left;
+ }
+
+ .cbi-value-field, .cbi-value-description {
+ width: 100%;
+ }
+
+ .cbi-value > .cbi-value-field {
+ display: inline-block;
+ }
+
+ .cbi-tabmenu > li, .tabs > li {
+ padding: 0.6rem 0rem;
+ }
+
+ .cbi-tabmenu > li > a, .tabs > li > a {
+ padding: 0.2rem 0.3rem;
+ font-size: 0.9rem;
+ }
+
+ .cbi-page-actions > div > input {
+ display: none;
+ }
+
+ .node-main-login > .main .container {
+ padding: 0.5rem 1rem 2rem 1rem;
+ }
+
+ .node-main-login > .main .cbi-value {
+ padding: 0;
+ }
+
+ .node-main-login > .main form > div:nth-last-child(1) {
+ margin-top: 2rem;
+ }
+
+ .node-main-login > .main .cbi-value-title {
+ width: 100% !important;
+ font-size: 1.2rem;
+ }
+
+ .node-main-login > .main fieldset {
+ margin: 0;
+ padding: 0.5rem;
+ }
+
+ h2 {
+ font-size: 2rem;
+ }
+
+ .tabs > li > a {
+ font-size: 0.9rem;
+ }
+
+ select,
+ input {
+ font-size: 0.9rem;
+ }
+
+ .mobile-hide {
+ display: none;
+ }
+
+ .panel-title {
+ font-size: 1.4rem;
+ padding-bottom: 1rem;
+ }
+
+ .node-system-packages > .main .cbi-value.cbi-value-last > div {
+ width: 100% !important;
+ }
+
+ .node-system-packages > .main .cbi-value .cbi-value-field input {
+ width: 100%;
+ }
+
+ .node-status-iptables > .main div > .cbi-map > form {
+ position: static !important;
+ margin: 0 0 2rem 0;
+ padding: 2rem;
+ border: 0;
+ font-weight: normal;
+ font-style: normal;
+ line-height: 1;
+ font-family: inherit;
+ min-width: inherit;
+ border-radius: 0;
+ background-color: #FFF;
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .16), 0 0 2px 0 rgba(0, 0, 0, .12);
+ -webkit-overflow-scrolling: touch;
+ }
+
+ .node-status-iptables > .main div > .cbi-map > form input[type="submit"] {
+ width: 100% !important;
+ margin: 0;
+ }
+
+ .node-status-iptables > .main div > .cbi-map > form input[type="submit"] + input[type="submit"] {
+ margin-top: 1rem;
+ }
+
+ .th, .td {
+ flex-basis: 50%;
+ }
+
+ .td.cbi-value-field {
+ flex-basis: 100%;
+ }
+
+ .td.cbi-value-field[data-type="dvalue"] {
+ flex-basis: 50%;
+ }
+
+ .td.cbi-value-field[data-type="button"],
+ .td.cbi-value-field[data-type="fvalue"] {
+ flex-basis: 25%;
+ text-align: left;
+ }
+
+ .tr[data-title]::before,
+ .tr.cbi-section-table-titles.named::before {
+ font-size: 1rem;
+ }
+
+ .hide-xs {
+ display: none;
+ }
+}
+
+@media screen and (min-width: 992px) {
+ .cbi-value input[type="password"],
+ .cbi-value input[type="text"],
+ .cbi-value-field .cbi-input-select {
+ width: 20rem;
+ }
+
+ .cbi-value-field .cbi-dropdown {
+ min-width: 20rem;
+ }
+}
+
+@media screen and (min-width: 1280px) {
+ .cbi-value input[type="password"],
+ .cbi-value input[type="text"],
+ .cbi-value-field .cbi-input-select {
+ width: 22rem;
+ }
+
+ .cbi-value-field .cbi-dropdown {
+ min-width: 22rem;
+ }
+}
+
+@media screen and (min-width: 1600px) {
+ .cbi-value input[type="password"],
+ .cbi-value input[type="text"],
+ .cbi-value-field .cbi-input-select {
+ width: 25rem;
+ }
+
+ .cbi-value-field .cbi-dropdown {
+ min-width: 25rem;
+ }
+}
+++ /dev/null
-/**
- * Material is a clean HTML5 theme for LuCI. It is based on luci-theme-bootstrap and MUI
- *
- * luci-theme-material
- * Copyright 2015 Lutty Yang <lutty@wcan.in>
- *
- * Have a bug? Please create an issue here on GitHub!
- * https://github.com/LuttyYang/luci-theme-material/issues
- *
- * luci-theme-bootstrap:
- * Copyright 2008 Steven Barth <steven@midlink.org>
- * Copyright 2008 Jo-Philipp Wich <jow@openwrt.org>
- * Copyright 2012 David Menting <david@nut-bolt.nl>
- *
- * MUI:
- * https://github.com/muicss/mui
- *
- * Licensed to the public under the Apache License 2.0
- */
-
-/*
- * Font generate by Icomoon<icomoon.io>
- */
-@font-face {
- font-family: 'icomoon';
- src: url('../fonts/font.eot');
- src: url('../fonts/font.eot') format('embedded-opentype'),
- url('../fonts/font.ttf') format('truetype'),
- url('../fonts/font.woff') format('woff'),
- url('../fonts/font.svg') format('svg');
- font-weight: normal;
- font-style: normal;
-}
-
-.table { display: table; position: relative; }
-.tr { display: table-row; }
-.thead { display: table-header-group; }
-.tbody { display: table-row-group; }
-.tfoot { display: table-footer-group; }
-.td, .th {
- vertical-align: middle;
- text-align: center;
- display: table-cell;
- padding: .5em;
-}
-
-.th {
- font-weight: bold;
-}
-
-.tr.placeholder {
- height: 4em;
-}
-
-.tr.placeholder > .td {
- position: absolute;
- left: 0;
- right: 0;
- bottom: 0;
- text-align: center;
- line-height: 3em;
- background: inherit;
-}
-
-.table[width="33%"], .th[width="33%"], .td[width="33%"] { width: 33%; }
-.table[width="100%"], .th[width="100%"], .td[width="100%"] { width: 100%; }
-
-.col-1 { flex: 1 1 30px !important; -webkit-flex: 1 1 30px !important; }
-.col-2 { flex: 2 2 60px !important; -webkit-flex: 2 2 60px !important; }
-.col-3 { flex: 3 3 90px !important; -webkit-flex: 3 3 90px !important; }
-.col-4 { flex: 4 4 120px !important; -webkit-flex: 4 4 120px !important; }
-.col-5 { flex: 5 5 150px !important; -webkit-flex: 5 5 150px !important; }
-.col-6 { flex: 6 6 180px !important; -webkit-flex: 6 6 180px !important; }
-.col-7 { flex: 7 7 210px !important; -webkit-flex: 7 7 210px !important; }
-.col-8 { flex: 8 8 240px !important; -webkit-flex: 8 8 240px !important; }
-.col-9 { flex: 9 9 270px !important; -webkit-flex: 9 9 270px !important; }
-.col-10 { flex: 10 10 300px !important; -webkit-flex: 10 10 300px !important; }
-
-.cbi-button-up,
-.cbi-button-down,
-.cbi-value-helpicon,
-.showSide,
-.main > .loading > span {
- font-family: 'icomoon' !important;
- speak: none;
- font-style: normal !important;
- font-weight: normal !important;
- font-variant: normal !important;
- text-transform: none !important;
- line-height: 1;
-
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
-}
-
-* {
- margin: 0;
- padding: 0;
- box-sizing: border-box;
-}
-
-.h1, .h2, .h3, .h4, .h5, .h6, h1, h2, h3, h4, h5, h6 {
- font-family: inherit;
- font-weight: 400;
- line-height: 1.1;
- color: inherit;
-}
-
-html {
- -webkit-text-size-adjust: 100%;
- -ms-text-size-adjust: 100%;
-}
-
-body {
- font-size: 0.8rem;
- background-color: #EEE;
-}
-
-html, body {
- margin: 0px;
- padding: 0px;
- height: 100%;
- font-family: Microsoft Yahei, WenQuanYi Micro Hei, sans-serif, "Helvetica Neue", Helvetica, Hiragino Sans GB;
-}
-
-select {
- padding: 0.36rem 0.8rem;
- color: #555;
- background-color: #fff;
- background-image: none;
- border: 1px solid #ccc;
-}
-
-select,
-input,
-.cbi-dropdown {
- background-color: transparent;
- color: rgba(0, 0, 0, .87);
- border: none;
- border-bottom: 2px solid rgba(0, 0, 0, .26);
- outline: 0;
- padding: 0;
- box-shadow: none;
- border-radius: 0;
- background-image: none;
- height: 1.8rem;
- font-size: 0.8rem;
-}
-
-select:not([multiple="multiple"]):focus,
-input:focus {
- border-color: #0099CC;
-}
-
-select[multiple="multiple"] {
- height: auto;
-}
-
-code {
- color: #0099CC;
-}
-
-abbr {
- color: #005470;
- text-decoration: underline;
- cursor: help;
-}
-
-hr {
- margin: 1rem 0;
- border-color: #EEE;
- opacity: 0.1;
-}
-
-header, .main {
- width: 100%;
- position: absolute;
-}
-
-header {
- height: 4rem;
- box-shadow: 0 2px 5px rgba(0, 0, 0, .26);
- transition: box-shadow .2s;
- float: left;
- position: fixed;
- z-index: 2000;
-}
-
-footer {
- text-align: right;
- padding: 1rem;
- color: #aaa;
- font-size: 0.8rem;
- text-shadow: 0px 0px 2px #BBB;
-}
-
-footer > a {
- color: #aaa;
- text-decoration: none;
-}
-
-.main {
- top: 4rem;
- bottom: 0rem;
- position: relative;
- height: 100%;
- height: calc(100% - 4rem);
-}
-
-.main > .loading {
- position: fixed;
- width: 100%;
- height: 100%;
- z-index: 1000;
- display: block;
- background-color: rgb(240, 240, 240);
- top: 0;
-}
-
-.main > .loading > span {
- display: block;
- text-align: center;
- margin-top: 2rem;
- color: #888;
- font-size: 1.2rem;
-}
-
-.main > .loading > span > .loading-img:before {
- content: "\e603";
-}
-
-.main > .loading > span > .loading-img {
- animation: anim-rotate 2s infinite linear;
- margin-right: 0.2rem;
- display: inline-block;
-}
-
-@keyframes anim-rotate {
- 0% {
- -webkit-transform: rotate(0);
- -ms-transform: rotate(0);
- transform: rotate(0);
- }
- 100% {
- -webkit-transform: rotate(360deg);
- -ms-transform: rotate(360deg);
- transform: rotate(360deg)
- }
-}
-
-.main-left {
- float: left;
- top: 4rem;
- width: 15%;
- width: calc(0% + 15rem);
- height: 100%;
- height: calc(100% - 4rem);
- background-color: white;
- overflow-x: auto;
- position: fixed;
-}
-
-.main-right {
- width: 85%;
- width: calc(100% - 15rem);
- float: right;
- height: 100%;
- background-color: #EEE;
-}
-
-.main-right > #maincontent {
- background-color: #EEE;
-}
-
-.pull-right {
- float: right;
-}
-
-.pull-left {
- float: left;
-}
-
-header {
- background: #0099CC;
- color: white;
-}
-
-header > .container {
- margin-top: 0.5rem;
- padding: 0.5rem 1rem 0 1rem;
-}
-
-header > .container > .brand {
- font-size: 1.4rem;
- color: white;
- text-decoration: none;
- cursor: default;
- vertical-align: text-bottom;
-}
-
-.danger {
- background-color: #FA8072 !important;
- color: black;
-}
-
-.warning {
- background-color: #F0E68C !important;
- color: black;
-}
-
-.success {
- background-color: #90EE90 !important;
- color: black;
-}
-
-.alert-message {
- margin: 2rem 0 0 0;
- padding: 1rem;
- border: 0;
- font-weight: normal;
- font-style: normal;
- line-height: 1;
- font-family: inherit;
- min-width: inherit;
- overflow: auto;
- border-radius: 0;
- background-color: #FFF;
- box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .16), 0 0 2px 0 rgba(0, 0, 0, .12);
-}
-
-.error {
- color: red;
-}
-
-.alert-message > h4 {
- font-weight: bold;
- font-size: 110%;
-}
-
-.alert-message > * {
- margin: .5rem 0;
-}
-
-#maincontent > .container > div:nth-child(1).alert-message.warning > a {
- font: inherit;
- overflow: visible;
- text-transform: none;
- display: inline-block;
- margin-bottom: 0;
- font-weight: 400;
- text-align: center;
- white-space: nowrap;
- vertical-align: middle;
- touch-action: manipulation;
- cursor: pointer;
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
- background-image: none;
- min-width: 6rem;
- padding: 0.5rem 1rem;
- font-size: 0.9rem;
- line-height: 1.42857143;
- color: #fff;
- background-color: #5bc0de;
- border-color: #46b8da;
- margin-top: 2rem;
- text-decoration: inherit;
-}
-
-.main > .main-left > .nav {
- margin-top: 0.5rem;
-}
-
-.main > .main-left > .nav > li a {
- color: #404040;
- display: block;
-}
-
-.main > .main-left > .nav > li:nth-last-child(1) {
- margin-top: 2rem;
- font-size: 1.2rem;
-}
-
-.main > .main-left > .nav > li {
- padding: 0.5rem 1rem;
- cursor: pointer;
-}
-
-.main > .main-left > .nav > .slide {
- padding: 0;
-}
-
-.main > .main-left > .nav > .slide > ul {
- display: none;
-}
-
-.main > .main-left > .nav > .slide > .menu {
- display: block;
- padding: 0.5rem 1rem;
- text-decoration: none;
- cursor: default;
- font-size: 1.15rem;
-}
-
-.main > .main-left > .nav > li:hover,
-.main > .main-left > .nav > .slide > .menu:hover {
- background: #D4D4D4;
-}
-
-.main > .main-left > .nav > .slide:hover {
- background: none;
-}
-
-.main > .main-left > .nav > .slide > .slide-menu > li {
- padding: 0.4rem 2rem;
-}
-
-.main > .main-left > .nav > .slide > .slide-menu > .active {
- background-color: #0099CC;
-}
-
-.main > .main-left > .nav > .slide > .slide-menu > li > a {
- text-decoration: none;
- white-space: nowrap;
-}
-
-.main > .main-left > .nav > .slide > .slide-menu > .active > a {
- color: white;
-}
-
-.main > .main-left > .nav > .slide > .slide-menu > li:hover {
- background: #D4D4D4;
-}
-
-.main > .main-left > .nav > .slide > .slide-menu > .active:hover {
- background-color: #0099CC;
- cursor: hand;
-}
-
-li {
- list-style-type: none;
-}
-
-#maincontent > .container {
- margin: 0 2rem 1rem 2rem;
-}
-
-h1 {
- font-size: 2rem;
- padding-bottom: 10px;
- border-bottom: 1px solid #eee;
-}
-
-h2 {
- margin: 2rem 0 0 0;
- font-size: 1.8rem;
- padding-bottom: 10px;
- border-bottom: 1px solid #eee;
-}
-
-h3 {
- margin: 2rem 0 0 0;
- font-size: 1.4rem;
- padding-bottom: 10px;
-}
-
-h4 {
- margin: 2rem 0 0 0;
- font-size: 1.2rem;
- padding-bottom: 10px;
-}
-
-.cbi-section {
- margin: 1rem 0 0 0;
- padding: 2rem;
- border: 0;
- font-weight: normal;
- font-style: normal;
- line-height: 1;
- font-family: inherit;
- min-width: inherit;
- border-radius: 0;
- background-color: #FFF;
- box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .16), 0 0 2px 0 rgba(0, 0, 0, .12);
-
- -webkit-overflow-scrolling: touch;
-}
-
-.cbi-map-descr + fieldset {
- margin-top: 1rem;
-}
-
-.cbi-section > legend {
- display: none !important;
-}
-
-fieldset > fieldset {
- margin: 0;
- padding: 0;
- border: none;
- box-shadow: none;
-}
-
-.cbi-section > h3:first-child,
-.panel-title {
- width: 100%;
- display: block;
- line-height: 1;
- color: #404040;
- font-size: 1.4rem;
- padding-bottom: 1rem;
- border-bottom: 1px solid #eee;
- margin: 0;
-}
-
-table {
- border-spacing: 0;
- border-collapse: collapse;
-}
-
-table, .table {
- width: 100%;
- border: 1px solid #eee;
-}
-
-table > tbody > tr > td, table > tbody > tr > th, table > tfoot > tr > td, table > tfoot > tr > th, table > thead > tr > td, table > thead > tr > th,
-.table > .tbody > .tr > .td, .table > .tbody > .tr > .th, .table > .tfoot > .tr > .td, .table > .tfoot > .tr > .th, .table > .thead > .tr > .td, .table > .thead > .tr > .th {
- padding: .5rem;
- border-top: 1px solid #ddd;
- white-space: nowrap;
-}
-
-.cbi-section-table-cell {
- white-space: nowrap;
- align-self: flex-end;
- flex: 1 1 auto;
-}
-
-.cbi-section-table {
- border: none;
-}
-
-.cbi-section-table-row {
- text-align: center;
- margin-bottom: 1rem;
- background: #f4f4f4;
- box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .16), 0 0 2px 0 rgba(0, 0, 0, .12);
-}
-
-.cbi-section-table-row:last-child {
- margin-bottom: 0;
-}
-
-.cbi-section-table-row > .cbi-value-field .cbi-input-select,
-.cbi-section-table-row > .cbi-value-field .cbi-input-text,
-.cbi-section-table-row > .cbi-value-field .cbi-input-password,
-.cbi-section-table-row > .cbi-value-field .cbi-dropdown {
- width: 100%;
-}
-
-.cbi-section-table-row > .cbi-value-field [data-dynlist] > input,
-.cbi-section-table-row > .cbi-value-field input.cbi-input-password {
- width: calc(100% - 1.5rem);
-}
-
-div > table > tbody > tr:nth-of-type(2n),
-div > .table > .tbody > .tr:nth-of-type(2n) {
- background-color: #f9f9f9;
-}
-
-div > table > tbody > tr:nth-of-type(2n),
-div > .table > .tbody > .tr:nth-of-type(2n) {
- background-color: #f9f9f9;
-}
-
-/* fix progress bar */
-#swaptotal > div,
-#swapfree > div,
-#memfree > div,
-#membuff > div,
-#conns > div,
-#memtotal > div {
- width: 100% !important;
- height: 1.2rem !important;
-}
-
-#swaptotal > div > div,
-#swapfree > div > div,
-#memfree > div > div,
-#membuff > div > div,
-#conns > div > div,
-#memtotal > div > div {
- height: 100% !important;
- background-color: #0099CC !important;
-}
-
-/* fix multiple table */
-
-table table,
-.table .table {
- border: none;
-}
-
-.cbi-value-field table,
-.cbi-value-field .table {
- border: none;
-}
-
-td > table > tbody > tr > td,
-.td > .table > .tbody > .tr > .td {
- border: none;
-}
-
-.cbi-value-field > table > tbody > tr > td,
-.cbi-value-field > .table > .tbody > .tr > .td {
- border: none;
-}
-
-/* button style */
-
-.btn, .cbi-button {
- -webkit-appearance: none;
- text-transform: uppercase;
- color: rgba(0, 0, 0, 0.87);
- background-color: #F0F0F0;
- transition: all 0.2s ease-in-out;
- display: inline-block;
- padding: 0 0.8rem;
- border: none;
- border-radius: 0.2rem;
- cursor: pointer;
- -ms-touch-action: manipulation;
- touch-action: manipulation;
- background-image: none;
- text-align: center;
- vertical-align: middle;
- white-space: nowrap;
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
- font-size: 0.8rem;
- width: auto !important;
- display: inline-block;
- text-decoration: none;
-}
-
-.btn:hover,
-.btn:focus,
-.btn:active,
-.cbi-button:hover,
-.cbi-button:focus,
-.cbi-button:active,
-.cbi-page-actions .cbi-button-apply + .cbi-button-save:hover,
-.cbi-page-actions .cbi-button-apply + .cbi-button-save:focus,
-.cbi-page-actions .cbi-button-apply + .cbi-button-save:active {
- outline: 0;
- text-decoration: none;
- background-color: rgba(250, 250, 250, 0.7);
-}
-
-.btn:hover,
-.btn:focus,
-.cbi-button:hover,
-.cbi-button:focus {
- box-shadow: 0 0px 2px rgba(0, 0, 0, 0.12), 0 2px 2px rgba(0, 0, 0, 0.2);
-}
-
-.btn:active,
-.cbi-button:active {
- box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23);
-}
-
-.btn:disabled,
-.cbi-button:disabled {
- cursor: not-allowed;
- pointer-events: none;
- opacity: 0.60;
- box-shadow: none;
-}
-
-.cbi-page-actions .cbi-button-apply,
-.cbi-section-actions .cbi-button-edit,
-.cbi-button-edit.important,
-.cbi-button-apply.important,
-.cbi-button-reload.important,
-.cbi-button-action.important {
- color: #fff;
- background-color: #337ab7;
-}
-
-.cbi-page-actions .cbi-button-save,
-.cbi-button-add.important,
-.cbi-button-save.important,
-.cbi-button-positive.important {
- color: #fff;
- background-color: #5bc0de;
-}
-
-.cbi-button-remove.important,
-.cbi-button-reset.important,
-.cbi-button-negative.important {
- color: #fff;
- background-color: #d9534f;
-}
-
-.cbi-button-find,
-.cbi-button-link,
-.cbi-button-up,
-.cbi-button-down,
-.cbi-button-neutral {
- border: 1px solid #bfbfbf;
- background-color: transparent;
-}
-
-.cbi-button-edit,
-.cbi-button-apply,
-.cbi-button-reload,
-.cbi-button-action {
- color: #2e6da4;
- border: 1px solid #2e6da4;
- background-color: transparent;
-}
-
-.cbi-page-actions .cbi-button-apply + .cbi-button-save,
-.cbi-button-add,
-.cbi-button-save,
-.cbi-button-positive {
- color: #46b8da;
- border: 1px solid #46b8da;
- background-color: transparent;
-}
-
-.cbi-section-remove > .cbi-button,
-.cbi-button-remove,
-.cbi-button-reset,
-.cbi-button-negative {
- color: #d43f3a;
- border: 1px solid #d43f3a;
- background-color: transparent;
-}
-
-.cbi-page-actions .cbi-button-link:first-child {
- float: left;
-}
-
-.a-to-btn {
- text-decoration: none;
-}
-
-/* table */
-
-.tabs {
- margin: 0 -2rem;
- padding-left: 0.5rem;
- background-color: #FFFFFF;
-}
-
-.cbi-tabmenu > li,
-.tabs > li {
- display: inline-block;
- padding: 0.6rem 0rem;
-}
-
-.cbi-tabmenu > li > a,
-.tabs > li > a {
- text-decoration: none;
- color: #404040;
- padding: 0.5rem 0.8rem;
-}
-
-.tabs > li[class~="active"],
-.tabs > li:hover {
- cursor: pointer;
- border-bottom: 0.2rem solid #0099CC;
- color: #0099CC;
- margin-bottom: -0.18751rem;
-}
-
-.tabs > li[class~="active"] > a {
- color: #0099cc;
-}
-
-.tabs > li:hover {
- border-bottom: 0.18751rem solid #C9C9C9;
-}
-
-.cbi-tabmenu {
- border-top: 1px solid #D4D4D4;
- border-left: 1px solid #D4D4D4;
- border-right: 1px solid #D4D4D4;
-}
-
-.cbi-tabmenu > li:hover {
- background-color: #F1F1F1;
-}
-
-.cbi-tabmenu > li[class~="cbi-tab"] {
- background-color: white;
-}
-
-.cbi-tabmenu {
- background-color: #D4D4D4;
-}
-
-.cbi-section-remove:nth-of-type(2n),
-.cbi-section-node:nth-of-type(2n){
- background-color: #f9f9f9;
-}
-
-.cbi-section-node-tabbed {
- padding: 0;
- margin-top: 0;
- border-bottom: 1px solid #D4D4D4;
- border-left: 1px solid #D4D4D4;
- border-right: 1px solid #D4D4D4;
-}
-
-.cbi-tabcontainer > .cbi-value:nth-of-type(2n) {
- background-color: #f9f9f9;
-}
-
-.cbi-value-field,
-.cbi-value-description {
- display: table-cell;
- line-height: 1.25;
-}
-
-.cbi-value-helpicon > img {
- display: none;
-}
-
-.cbi-value-helpicon:before {
- content: "\f059";
-}
-
-.cbi-value-description {
- font-size: small;
- opacity: 0.5;
- padding: 0.5rem 0 0 0;
-}
-
-.cbi-value-title {
- word-wrap: break-word;
- padding-top: 0.6rem;
- width: 23rem;
- float: left;
- text-align: right;
- padding-right: 2rem;
- display: table-cell;
-}
-
-.cbi-value {
- padding: 0.3rem 1rem;
- display: inline-block;
- width: 100%;
-}
-
-.cbi-section-table-descr > .cbi-section-table-cell,
-.cbi-section-table-titles > .cbi-section-table-cell {
- border: none;
-}
-
-.td[data-title]::before {
- content: attr(data-title) ":\20";
- font-weight: bold;
- text-align: left;
- display: none;
- padding: .25rem 0;
- white-space: nowrap;
-}
-
-.tr.placeholder .td[data-title]::before {
- display: none;
-}
-
-.tr[data-title]::before,
-.tr.cbi-section-table-titles.named::before {
- content: attr(data-title) "\20";
- font-weight: bold;
- text-align: center;
- display: table-cell;
- align-self: center;
- flex: 1 1 5%;
- padding: .25rem;
- white-space: normal;
- word-wrap: break-word;
- vertical-align: middle;
-}
-
-.cbi-rowstyle-1 {
- background-color: #f9f9f9;
-}
-
-.cbi-rowstyle-2 {
- background-color: #eee;
-}
-
-.cbi-rowstyle-2 .cbi-button-up,
-.cbi-rowstyle-2 .cbi-button-down {
- background-color: #FFF !important;
-}
-
-.cbi-section-table .cbi-section-table-titles .cbi-section-table-cell {
- width: auto !important;
-}
-
-.td.cbi-section-actions {
- text-align: right;
- vertical-align: middle;
-}
-
-.td.cbi-section-actions > * {
- display: flex;
-}
-
-.td.cbi-section-actions > * > *,
-.td.cbi-section-actions > * > form > * {
- flex: 1 1 4em;
- margin: 0 1px;
-}
-
-.td.cbi-section-actions > * > form {
- display: inline-flex;
- margin: 0;
-}
-
-/* desc */
-.cbi-section-descr,
-.cbi-map-descr {
- padding: 0.5rem;
- color: #999;
- font-size: small;
-}
-
-
-.cbi-dropdown {
- display: inline-flex;
- cursor: pointer;
- position: relative;
- padding: 0;
- height: auto;
-}
-
-.cbi-dropdown:focus {
- outline: 2px solid #4b6e9b;
-}
-
-.cbi-dropdown > ul {
- margin: 0 !important;
- padding: 0;
- list-style: none;
- overflow-x: hidden;
- overflow-y: auto;
- display: flex;
- width: 100%;
-}
-
-.cbi-dropdown > ul.preview {
- display: none;
-}
-
-.cbi-dropdown > .open {
- border: 2px outset #eee;
- flex-basis: 15px;
- background: #eee;
-}
-
-.cbi-dropdown > .open,
-.cbi-dropdown > .more {
- flex-grow: 0;
- flex-shrink: 0;
- display: flex;
- flex-direction: column;
- justify-content: center;
- text-align: center;
- line-height: 2em;
- padding: 0 .25em;
-}
-
-.cbi-dropdown > .more,
-.cbi-dropdown > ul > li[placeholder] {
- color: #777;
- font-weight: bold;
- text-shadow: 1px 1px 0px #fff;
- display: none;
-}
-
-.cbi-dropdown > ul > li {
- display: none;
- padding: .25em;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- flex-shrink: 1;
- flex-grow: 1;
- align-items: center;
- align-self: center;
- min-height: 20px;
-}
-
-.cbi-dropdown > ul > li .hide-open { display: initial; }
-.cbi-dropdown > ul > li .hide-close { display: none; }
-
-.cbi-dropdown > ul > li[display]:not([display="0"]) {
- border-left: 1px solid #ccc;
-}
-
-.cbi-dropdown[empty] > ul {
- max-width: 1px;
-}
-
-.cbi-dropdown > ul > li > form {
- display: none;
- margin: 0;
- padding: 0;
- pointer-events: none;
-}
-
-.cbi-dropdown > ul > li img {
- vertical-align: middle;
- margin-right: .25em;
-}
-
-.cbi-dropdown > ul > li > form > input[type="checkbox"] {
- margin: 0;
- height: auto;
-}
-
-.cbi-dropdown > ul > li input[type="text"] {
- height: 20px;
-}
-
-.cbi-dropdown[open] {
- position: relative;
-}
-
-.cbi-dropdown[open] > ul.dropdown {
- display: block;
- background: #f6f6f5;
- border: 1px solid #918e8c;
- box-shadow: 0 0 4px #918e8c;
- position: absolute;
- z-index: 1000;
- max-width: none;
- min-width: 100%;
- width: auto;
-}
-
-.cbi-dropdown > ul > li[display],
-.cbi-dropdown[open] > ul.preview,
-.cbi-dropdown[open] > ul.dropdown > li,
-.cbi-dropdown[multiple] > ul > li > label,
-.cbi-dropdown[multiple][open] > ul.dropdown > li,
-.cbi-dropdown[multiple][more] > .more,
-.cbi-dropdown[multiple][empty] > .more {
- flex-grow: 1;
- display: flex;
- align-items: center;
-}
-
-.cbi-dropdown[empty] > ul > li,
-.cbi-dropdown[optional][open] > ul.dropdown > li[placeholder],
-.cbi-dropdown[multiple][open] > ul.dropdown > li > form {
- display: block;
-}
-
-.cbi-dropdown[open] > ul.dropdown > li .hide-open { display: none; }
-.cbi-dropdown[open] > ul.dropdown > li .hide-close { display: initial; }
-
-.cbi-dropdown[open] > ul.dropdown > li {
- border-bottom: 1px solid #ccc;
-}
-
-.cbi-dropdown[open] > ul.dropdown > li[selected] {
- background: #b0d0f0;
-}
-
-.cbi-dropdown[open] > ul.dropdown > li.focus {
- background: linear-gradient(90deg, #a3c2e8 0%, #84aad9 100%);
-}
-
-.cbi-dropdown[open] > ul.dropdown > li:last-child {
- margin-bottom: 0;
- border-bottom: none;
-}
-
-.cbi-dropdown[disabled] {
- pointer-events: none;
- opacity: .6;
-}
-
-.cbi-dropdown .zonebadge {
- width: 100%;
-}
-
-.cbi-dropdown[open] .zonebadge {
- width: auto;
-}
-
-
-/* luci */
-
-.hidden {
- display: none
-}
-
-.left, .left::before {
- text-align: left !important;
-}
-
-.right, .right::before {
- text-align: right !important;
-}
-
-.center, .center::before {
- text-align: center !important;
-}
-
-.top {
- align-self: flex-start !important;
- vertical-align: top !important;
-}
-
-.bottom {
- align-self: flex-end !important;
- vertical-align: bottom !important;
-}
-
-.inline {
- display: inline;
-}
-
-.cbi-page-actions {
- border-top: 1px solid #eee;
- padding-top: 1rem;
- text-align: right;
-}
-
-/* input */
-.cbi-value input[type="password"],
-.cbi-value input[type="text"] {
- min-width: 15rem;
-}
-
-/* select */
-.cbi-value-field .cbi-dropdown {
- min-width: 15rem;
-}
-
-.cbi-value-field .cbi-input-select {
- width: 15rem;
-}
-
-.th[data-type="button"], .td[data-type="button"],
-.th[data-type="fvalue"], .td[data-type="fvalue"] {
- flex: 1 1 2em;
- text-align: center;
-}
-
-.ifacebadge {
- display: inline-flex;
- border-bottom: 1px solid #CCCCCC;
- padding: 0.5rem 1rem;
- box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
- background: #fff;
-}
-
-td > .ifacebadge,
-.td > .ifacebadge {
- background-color: #F0F0F0;
- font-size: 0.9rem;
-}
-
-.ifacebadge > em,
-.ifacebadge > img {
- display: inline-block;
- margin: 0 .2rem;
- align-self: flex-start;
-}
-
-.ifacebadge > img + img {
- margin: 0 .2rem 0 0;
-}
-
-.network-status-table {
- display: flex;
- flex-wrap: wrap;
-}
-
-.network-status-table .ifacebox {
- margin: .5em;
- flex-grow: 1;
-}
-
-.network-status-table .ifacebox-body {
- display: flex;
- flex-direction: column;
- height: 100%;
-}
-
-.network-status-table .ifacebox-body > span {
- flex: 10 10 auto;
-}
-
-.network-status-table .ifacebox-body > div {
- display: flex;
- flex-wrap: wrap;
-}
-
-.network-status-table .ifacebox-body .ifacebadge {
- flex: 1 1 auto;
- margin: .5em .25em 0 .25em;
- padding: .5em;
- min-width: 220px;
- background-color: #fff;
- align-items: center;
-}
-
-/*textarea*/
-
-.cbi-input-textarea {
- width: 100%;
- min-height: 14rem;
- padding: 0.8rem;
- font-size: 0.8rem;
- font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
- color: black;
-}
-
-#syslog {
- width: 100%;
- min-height: 15rem;
- padding: 1rem;
- font-size: small;
- color: #5F5F5F;
-
- margin-bottom: 20px;
- border-radius: 0;
- background-color: #FFF;
- box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .16), 0 0 2px 0 rgba(0, 0, 0, .12);
- border: none;
-}
-
-/* change */
-
-.uci-change-list {
- font-family: monospace;
-}
-
-.uci-change-list ins,
-.uci-change-legend-label ins {
- text-decoration: none;
- border: 1px solid #00FF00;
- background-color: #CCFFCC;
- display: block;
- padding: 2px;
-}
-
-.uci-change-list del,
-.uci-change-legend-label del {
- text-decoration: none;
- border: 1px solid #FF0000;
- background-color: #FFCCCC;
- display: block;
- font-style: normal;
- padding: 2px;
-}
-
-.uci-change-list var,
-.uci-change-legend-label var {
- text-decoration: none;
- border: 1px solid #CCCCCC;
- background-color: #EEEEEE;
- display: block;
- font-style: normal;
- padding: 2px;
-}
-
-.uci-change-list var ins,
-.uci-change-list var del {
- border: none;
- white-space: pre;
- font-style: normal;
- padding: 0px;
-}
-
-.uci-change-legend {
- padding: 5px;
-}
-
-.uci-change-legend-label {
- width: 150px;
- float: left;
-}
-
-.uci-change-legend-label > ins,
-.uci-change-legend-label > del,
-.uci-change-legend-label > var {
- float: left;
- margin-right: 4px;
- width: 10px;
- height: 10px;
- display: block;
-}
-
-.uci-change-legend-label var ins,
-.uci-change-legend-label var del {
- line-height: 6px;
- border: none;
-}
-
-.uci-change-list var,
-.uci-change-list del,
-.uci-change-list ins {
- padding: 0.5rem;
-}
-
-/* other fix */
-#iwsvg,
-#iwsvg2,
-#bwsvg {
- border: 1px solid #D4D4D4 !important;
- border-top: none !important;
-}
-
-.ifacebox {
- box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 1px 2px rgba(0, 0, 0, 0.2);
- border-bottom: 1px solid #ccc;
- background-color: #f9f9f9;
- display: inline-flex;
- flex-direction: column;
- line-height: 1.2em;
- min-width: 100px;
-}
-
-.ifacebox-head {
- padding: .25em;
- background: #eee;
-}
-
-.ifacebox-head.active {
- background: #90c0e0;
-}
-
-.ifacebox-body {
- padding: .25em;
-}
-
-.cbi-image-button {
- margin-left: 0.5rem;
-}
-
-.zonebadge {
- padding: 0.2rem 0.5rem;
- display: inline-block;
-}
-
-.zonebadge .ifacebadge {
- padding: .2rem .3rem;
- margin: 0.1rem 0.2rem;
- border: 1px solid #6C6C6C;
-}
-
-.zonebadge > input[type="text"] {
- padding: 0.16rem 1rem;
- min-width: 10rem;
- margin-top: 0.3rem;
-}
-
-.zonebadge > em,
-.zonebadge > strong {
- margin: 0 0.2rem;
- display: inline-block;
-}
-
-.cbi-value-field .cbi-input-checkbox,
-.cbi-value-field .cbi-input-radio {
- margin-top: 0.5rem;
- height: 1rem;
-}
-
-.td .cbi-input-checkbox,
-.td .cbi-input-radio {
- margin-top: 0;
-}
-
-.cbi-value-field > input + .cbi-value-description {
- padding: 0;
-}
-
-.cbi-value-field > ul > li {
- display: flex;
-}
-
-.cbi-value-field > ul > li > label {
- margin-top: 0.5rem;
-}
-
-.cbi-value-field > ul > li .ifacebadge {
- background-color: #eee;
- margin-left: 0.4rem;
- margin-top: -0.5rem;
-}
-
-.cbi-section-table-row > .cbi-value-field .cbi-dropdown {
- min-width: 7rem;
-}
-
-.cbi-section-create {
- margin: .5rem -3px;
- display: inline-flex;
- align-items: center;
-}
-
-.cbi-section-create > * {
- margin: 0.5rem;
-}
-
-.cbi-section-remove {
- padding: 0.5rem;
-}
-
-div.cbi-value var, td.cbi-value-field var, .td.cbi-value-field var {
- font-style: italic;
- color: #0069D6;
-}
-
-small {
- font-size: 90%;
- white-space: normal;
- line-height: 1.42857143;
-}
-
-.cbi-button-up,
-.cbi-button-down {
- display: inline-block;
- min-width: 0;
- padding: 0.2rem 0.3rem;
- font-size: 1.2rem;
-}
-
-.cbi-optionals {
- padding: 1rem 1rem 0 1rem;
- border-top: 1px solid #CCC;
-}
-
-.cbi-dropdown-container {
- position: relative;
-}
-
-.cbi-tooltip-container {
- cursor: help;
-}
-
-.cbi-tooltip {
- position: absolute;
- z-index: 1000;
- left: -1000px;
- opacity: 0;
- transition: opacity .25s ease-out;
- pointer-events: none;
- box-shadow: 0 0 2px #444;
-}
-
-.cbi-tooltip-container:hover .cbi-tooltip {
- left: auto;
- opacity: 1;
- transition: opacity .25s ease-in;
-}
-
-.zonebadge .cbi-tooltip {
- padding: .25rem;
- background: inherit;
- margin: -1.5rem 0 0 -.5rem;
-}
-
-.zonebadge-empty {
- background: repeating-linear-gradient(45deg,rgba(204,204,204,0.5),rgba(204,204,204,0.5) 5px,rgba(255,255,255,0.5) 5px,rgba(255,255,255,0.5) 10px);
- color: #404040;
-}
-
-.zone-forwards {
- display: flex;
- min-width: 10rem;
-}
-
-.zone-forwards > * {
- flex: 1 1 45%;
-}
-
-.zone-forwards > span {
- flex-basis: 10%;
- text-align: center;
- padding: 0 .25rem;
-}
-
-.zone-forwards .zone-src,
-.zone-forwards .zone-dest {
- display: flex;
- flex-direction: column;
-}
-
-#diag-rc-output > pre {
- background-color: #f5f5f5;
- display: block;
- padding: 8.5px;
- margin: 0 0 18px;
- line-height: 1.5rem;
- -moz-border-radius: 3px;
- white-space: pre-wrap;
- word-wrap: break-word;
- font-size: 1.4rem;
- color: #404040;
-}
-
-input[name="ping"],
-input[name="traceroute"],
-input[name="nslookup"] {
- width: 80%;
-}
-
-header > .container > .pull-right > * {
- position: relative;
- top: 0.45rem;
- cursor: pointer;
-}
-
-#xhr_poll_status > .label.success {
- background-color: #14CE14;
-}
-
-.label {
- padding: 0.3rem 0.8rem;
- font-size: 0.8rem;
- font-weight: bold;
- color: #ffffff !important;
- text-transform: uppercase;
- white-space: nowrap;
- background-color: #bfbfbf;
- -webkit-border-radius: 3px;
- -moz-border-radius: 3px;
- border-radius: 3px;
- text-shadow: none;
- text-decoration: none;
-}
-
-.notice {
- background-color: #5BC0DE;
-}
-
-.showSide {
- display: none;
-}
-
-.darkMask {
- width: 100%;
- height: 100%;
- position: fixed;
- background-color: rgba(0, 0, 0, 0.56);
- content: "";
- z-index: 99;
- display: none;
-}
-
-/* fix Main Login*/
-.node-main-login > .main > .main-left {
- display: none;
-}
-
-.node-main-login > .main > .main-right {
- width: 100%;
-}
-
-.node-main-login > .main fieldset {
- padding: 0.5rem;
- margin-bottom: 1rem;
- display: inline;
- background: none;
- border: none;
- box-shadow: none;
- overflow: hidden;
-}
-
-.node-main-login > .main .cbi-value-title {
- width: 7rem;
-}
-
-.node-main-login > .main #maincontent {
-
- text-align: center;
-}
-
-.node-main-login > .main .container {
- display: inline-block;
- padding: 2rem 4rem;
- margin-top: 2rem !important;
- background-color: #FFF;
- box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .16), 0 0 2px 0 rgba(0, 0, 0, .12);
- text-align: left;
-}
-
-.node-main-login > .main form > div:nth-last-child(1) {
- float: right;
-}
-
-.node-main-login > .main .cbi-value {
- display: block;
-}
-
-.node-main-login > .main .cbi-value > * {
- display: inline-block !important;
-}
-
-.node-main-login > .main .cbi-input-user,
-.node-main-login > .main .cbi-input-password {
- min-width: 15rem;
-}
-
-.node-main-login footer {
- bottom: 0;
- position: absolute;
- width: 100%;
-}
-
-/* fix status overview */
-
-.node-status-overview > .main fieldset:nth-child(4) .td:nth-child(2) {
- white-space: normal;
-}
-
-/* fix status processes */
-
-.node-status-processes > .main .table .tr .td:nth-child(3) {
- white-space: normal;
-}
-
-.node-status-iptables > .main div > .cbi-map > form {
- margin: 2rem 2rem 0 0;
-}
-
-/* fix system reboot */
-
-.node-system-reboot > .main > .main-right p,
-.node-system-reboot > .main > .main-right h3 {
- padding-left: 2rem;
-}
-
-/* fix Services Network Shares*/
-.node-services-samba > .main .cbi-tabcontainer:nth-child(3) .cbi-value-title {
- margin-bottom: 1rem;
- width: auto;
-}
-
-.node-services-samba > .main .cbi-tabcontainer:nth-child(3) .cbi-value-field {
- display: list-item;
-}
-
-.node-services-samba > .main .cbi-tabcontainer:nth-child(3) .cbi-value-description {
- padding-top: 1rem;
-}
-
-/* fix System Software*/
-.node-system-packages > .main table tr td:nth-child(1) {
- width: auto !important;
-}
-
-.node-system-packages > .main table tr td:nth-last-child(1) {
- white-space: normal;
- font-size: small;
- color: #404040;
-}
-
-.node-system-packages > .main .cbi-tabmenu > li > a, .tabs > li > a {
- padding: 0.5rem 0.8rem;
-}
-
-.node-system-packages > .main .cbi-value > pre {
- background-color: #eee;
- padding: 0.5rem;
- overflow: auto;
-}
-
-.cbi-tabmenu + .cbi-section {
- margin-top: 0;
-}
-
-.node-status-iptables fieldset,
-.node-system-packages fieldset,
-.node-system-flashops fieldset {
- margin-top: 0;
-}
-
-.node-status-iptables .cbi-tabmenu,
-.node-system-packages .cbi-tabmenu,
-.node-system-flashops .cbi-tabmenu {
- border: none;
- box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .16), 0 0 2px 0 rgba(0, 0, 0, .12);
-}
-
-.node-system-flashops form.inline + form.inline {
- margin-left: 0;
-}
-
-#cbi-firewall-redirect table *,
-#cbi-network-switch_vlan table *,
-#cbi-firewall-zone table * {
- font-size: small;
-}
-
-#cbi-firewall-redirect table input[type="text"],
-#cbi-network-switch_vlan table input[type="text"],
-#cbi-firewall-zone table input[type="text"] {
- width: 5rem;
-}
-
-#cbi-firewall-redirect table select,
-#cbi-network-switch_vlan table select,
-#cbi-firewall-zone table select {
- min-width: 3.5rem;
-}
-
-#cbi-network-switch_vlan .th,
-#cbi-network-switch_vlan .td {
- flex-basis: 12%;
-}
-
-/* language fix */
-body.lang_pl.node-main-login .cbi-value-title {
- width: 12rem;
-}
-
-@media screen and (max-width: 1600px) {
- .main-left {
- width: calc(0% + 13rem);
- }
-
- .main-right {
- width: calc(100% - 13rem);
- }
-
- .btn,
- .cbi-button {
- padding: 0.3rem 0.6rem;
- font-size: 0.8rem;
- }
-
- header > .container > .pull-right > * {
- top: 0.35rem;
- }
-
- .label {
- padding: 0.2rem 0.6rem;
- }
-
- .cbi-value-title {
- width: 15rem;
- padding-right: 0.6rem;
- }
-
- fieldset {
- padding: 1rem;
- }
-
- .cbi-input-textarea {
- font-size: small;
- }
-
- .node-status-iptables > .main fieldset li > a {
- padding: 0.3rem 0.6rem;
- }
-}
-
-@media screen and (max-width: 1280px) {
- header {
- height: 3.5rem;
- }
-
- header > .container {
- margin-top: 0.25rem;
- }
-
- .main {
- top: 3.5rem;
- height: calc(100% - 3.5rem);
- }
-
- .main-left {
- width: calc(0% + 13rem);
- top: 3.5rem;
- height: calc(100% - 3.5rem);
- }
-
- .main-right {
- width: calc(100% - 13rem);
- }
-
- .cbi-tabmenu > li > a, .tabs > li > a {
- padding: 0.2rem 0.5rem;
- }
-
- .panel-title {
- font-size: 1.1rem;
- padding-bottom: 1rem;
- }
-
- table {
- font-size: 0.7rem !important;
- width: 100% !important;
- }
-
- .main > .main-left > .nav > li,
- .main > .main-left > .nav > li a,
- .main > .main-left > .nav > .slide > .menu {
- font-size: 0.9rem;
- }
-
- .main > .main-left > .nav > .slide > .slide-menu > li > a {
- font-size: 0.7rem;
- }
-}
-
-@media screen and (max-width: 992px) {
- .main-left {
- width: 0;
- position: fixed;
- z-index: 100;
- }
-
- .main-right {
- width: 100%;
- }
-
- .showSide {
- padding: 0.1rem;
- margin-right: 0.5rem;
- display: inline-block;
- }
-
- .showSide:before {
- content: "\e20e";
- font-size: 1.7rem;
- }
-
- .node-main-login .showSide {
- display: none !important;
- }
-
- .cbi-value-title {
- width: 9rem;
- padding-right: 1rem;
- }
-
- .node-network-diagnostics > .main .cbi-map fieldset > div * {
- width: 100% !important;
- }
-
- .node-network-diagnostics > .main .cbi-map fieldset > div input[type="text"] {
- margin: 3rem 0 0 0 !important;
- }
-
- .node-network-diagnostics > .main .cbi-map fieldset > div:nth-child(4) input[type="text"] {
- margin: 0 !important;
- }
-
- .node-network-diagnostics > .main .cbi-map fieldset > div select,
- .node-network-diagnostics > .main .cbi-map fieldset > div input[type="button"] {
- margin: 1rem 0 0 0;
- }
-
- .node-network-diagnostics > .main .cbi-map fieldset > div {
- width: 100% !important;
- }
-
- #diag-rc-output > pre {
- font-size: 1rem;
- }
-
- .node-main-login > .main .cbi-value-title {
- text-align: left;
- }
-
- .tr {
- display: flex;
- flex-direction: row;
- flex-wrap: wrap;
- }
-
- .th, .td {
- flex: 2 2 25%;
- align-self: flex-start;
- overflow: hidden;
- text-overflow: ellipsis;
- word-wrap: break-word;
- display: inline-block;
- }
-
- .td select,
- .td input[type="text"] {
- word-wrap: normal;
- width: 100%;
- }
-
- .td [data-dynlist] > input,
- .td input.cbi-input-password {
- width: calc(100% - 1.5rem);
- }
-
- .td[data-type="button"],
- .td[data-type="fvalue"] {
- flex: 1 1 12.5%;
- text-align: left;
- }
-
- .th.cbi-value-field,
- .td.cbi-value-field,
- .th.cbi-section-table-cell,
- .td.cbi-section-table-cell {
- flex-basis: auto;
- }
-
- .cbi-section-table-row {
- display: flex;
- flex-wrap: wrap;
- flex-direction: row;
- justify-content: space-between;
- }
-
- .td.cbi-value-field,
- .cbi-section-table-cell {
- text-align: center;
- display: inline-block;
- flex: 10 10 auto;
- }
-
- .td.cbi-section-actions {
- text-align: right;
- align-self: flex-end;
- vertical-align: bottom;
- }
-
- .tr.table-titles,
- .tr.cbi-section-table-titles,
- .tr.cbi-section-table-descr {
- display: none;
- }
-
- .tr[data-title]::before,
- .tr.cbi-section-table-titles.named::before {
- display: block;
- flex: 1 1 100%;
- background: #eef;
- font-size: .9rem;
- border-bottom: 1px solid rgba(0, 0, 0, .26);
- }
-
- .td[data-title] {
- text-align: left;
- }
-
- .td[data-title]::before {
- display: block;
- }
-
- .hide-sm,
- .hide-xs {
- display: none;
- }
-}
-
-@media screen and (max-width: 480px) {
- body {
- font-size: 1rem;
- }
-
- fieldset {
- padding: 1rem;
- margin: 1rem 0 0 0;
- }
-
- .tabs {
- margin: 0 -1rem;
- }
-
- #maincontent > .container {
- margin: 0 1rem 1.5rem 1rem;
- }
-
- .main > .main-left > .nav > .slide > .menu {
- font-size: 1.3rem;
- }
-
- .main > .main-left > .nav > .slide > .slide-menu > li > a {
- font-size: 1.1rem;
- }
-
- .cbi-value-title {
- width: 100%;
- min-width: 0rem !important;
- display: block;
- margin-top: 1rem;
- margin-bottom: 0.5rem;
- text-align: left;
- }
-
- .cbi-value-field, .cbi-value-description {
- width: 100%;
- }
-
- .cbi-value > .cbi-value-field {
- display: inline-block;
- }
-
- .cbi-tabmenu > li, .tabs > li {
- padding: 0.6rem 0rem;
- }
-
- .cbi-tabmenu > li > a, .tabs > li > a {
- padding: 0.2rem 0.3rem;
- font-size: 0.9rem;
- }
-
- .cbi-page-actions > div > input {
- display: none;
- }
-
- .node-main-login > .main .container {
- padding: 0.5rem 1rem 2rem 1rem;
- }
-
- .node-main-login > .main .cbi-value {
- padding: 0;
- }
-
- .node-main-login > .main form > div:nth-last-child(1) {
- margin-top: 2rem;
- }
-
- .node-main-login > .main .cbi-value-title {
- width: 100% !important;
- font-size: 1.2rem;
- }
-
- .node-main-login > .main fieldset {
- margin: 0;
- padding: 0.5rem;
- }
-
- h2 {
- font-size: 2rem;
- }
-
- .tabs > li > a {
- font-size: 0.9rem;
- }
-
- select,
- input {
- font-size: 0.9rem;
- }
-
- .mobile-hide {
- display: none;
- }
-
- .panel-title {
- font-size: 1.4rem;
- padding-bottom: 1rem;
- }
-
- .node-system-packages > .main .cbi-value.cbi-value-last > div {
- width: 100% !important;
- }
-
- .node-system-packages > .main .cbi-value .cbi-value-field input {
- width: 100%;
- }
-
- .node-status-iptables > .main div > .cbi-map > form {
- position: static !important;
- margin: 0 0 2rem 0;
- padding: 2rem;
- border: 0;
- font-weight: normal;
- font-style: normal;
- line-height: 1;
- font-family: inherit;
- min-width: inherit;
- border-radius: 0;
- background-color: #FFF;
- box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .16), 0 0 2px 0 rgba(0, 0, 0, .12);
- -webkit-overflow-scrolling: touch;
- }
-
- .node-status-iptables > .main div > .cbi-map > form input[type="submit"] {
- width: 100% !important;
- margin: 0;
- }
-
- .node-status-iptables > .main div > .cbi-map > form input[type="submit"] + input[type="submit"] {
- margin-top: 1rem;
- }
-
- .th, .td {
- flex-basis: 50%;
- }
-
- .td.cbi-value-field {
- flex-basis: 100%;
- }
-
- .td.cbi-value-field[data-type="dvalue"] {
- flex-basis: 50%;
- }
-
- .td.cbi-value-field[data-type="button"],
- .td.cbi-value-field[data-type="fvalue"] {
- flex-basis: 25%;
- text-align: left;
- }
-
- .tr[data-title]::before,
- .tr.cbi-section-table-titles.named::before {
- font-size: 1rem;
- }
-
- .hide-xs {
- display: none;
- }
-}
-
-@media screen and (min-width: 992px) {
- .cbi-value input[type="password"],
- .cbi-value input[type="text"],
- .cbi-value-field .cbi-input-select {
- width: 20rem;
- }
-
- .cbi-value-field .cbi-dropdown {
- min-width: 20rem;
- }
-}
-
-@media screen and (min-width: 1280px) {
- .cbi-value input[type="password"],
- .cbi-value input[type="text"],
- .cbi-value-field .cbi-input-select {
- width: 22rem;
- }
-
- .cbi-value-field .cbi-dropdown {
- min-width: 22rem;
- }
-}
-
-@media screen and (min-width: 1600px) {
- .cbi-value input[type="password"],
- .cbi-value input[type="text"],
- .cbi-value-field .cbi-input-select {
- width: 25rem;
- }
-
- .cbi-value-field .cbi-dropdown {
- min-width: 25rem;
- }
-}
-- calculate the number of unsaved changes
if tree.nodes[category] and tree.nodes[category].ucidata then
local ucichanges = 0
-
+ local i, j
for i, j in pairs(require("luci.model.uci").cursor():changes()) do
- for k, l in pairs(j) do
- for m, n in pairs(l) do
- ucichanges = ucichanges + 1;
- end
- end
+ ucichanges = ucichanges + #j
end
if ucichanges > 0 then
<link rel="icon" href="<%=media%>/logo.png" sizes="144x144">
<link rel="apple-touch-icon-precomposed" href="<%=media%>/logo.png" sizes="144x144">
- <link rel="stylesheet" href="<%=media%>/css/style.css">
+ <link rel="stylesheet" href="<%=media%>/cascade.css">
<link rel="shortcut icon" href="<%=media%>/favicon.ico">
<% if node and node.css then %>
<link rel="stylesheet" href="<%=resource%>/<%=node.css%>">
</head>
<body class="lang_<%=luci.i18n.context.lang%> <%- if node then %><%= striptags( node.title ) %><%- end %> <% if luci.dispatcher.context.authsession then %>logged-in<% end %>">
<header>
- <div class="container">
- <span class="showSide"></span>
- <a class="brand" href="#"><%=boardinfo.hostname or "?"%></a>
- <div class="pull-right">
- <% render_changes() %>
- <span id="xhr_poll_status" style="display:none" onclick="XHR.running() ? XHR.halt() : XHR.run()">
- <span class="label success" id="xhr_poll_status_on"><span class="mobile-hide"><%:Auto Refresh%></span> <%:on%></span>
- <span class="label" id="xhr_poll_status_off" style="display:none"><span class="mobile-hide"><%:Auto Refresh%></span> <%:off%></span>
- </span>
+ <div class="fill">
+ <div class="container">
+ <span class="showSide"></span>
+ <a class="brand" href="#"><%=boardinfo.hostname or "?"%></a>
+ <div class="pull-right">
+ <% render_changes() %>
+ <span id="xhr_poll_status" style="display:none" onclick="XHR.running() ? XHR.halt() : XHR.run()">
+ <span class="label success" id="xhr_poll_status_on"><span class="mobile-hide"><%:Auto Refresh%></span> <%:on%></span>
+ <span class="label" id="xhr_poll_status_off" style="display:none"><span class="mobile-hide"><%:Auto Refresh%></span> <%:off%></span>
+ </span>
+ </div>
</div>
</div>
</header>
border-color: #444444;
}
+#applyreboot-section {
+ margin: 2rem;
+ line-height: 300%;
+}
+
.lang_he #maincontent {
direction: rtl;
}
margin: .5em 0 0 0;
}
+#dsl_status_table .ifacebox-body > span > strong {
+ display: inline-block;
+ min-width: 35%;
+}
+
.zonebadge {
padding: 2px;
.uci-change-list {
font-family: monospace;
+ white-space: pre;
}
+.uci-change-list del,
.uci-change-list ins,
-.uci-change-legend-label ins {
+.uci-change-list var,
+.uci-change-legend-label del,
+.uci-change-legend-label ins,
+.uci-change-legend-label var {
text-decoration: none;
- border: 1px solid #00FF00;
- background-color: #CCFFCC;
- display: block;
+ font-style: normal;
+ border: 1px solid #ccc;
+ background: #eee;
padding: 2px;
+ display: block;
+ line-height: 15px;
+ margin-bottom: 1px;
+}
+
+.uci-change-list ins,
+.uci-change-legend-label ins {
+ border-color: #0f0;
+ background: #cfc;
}
.uci-change-list del,
.uci-change-legend-label del {
- text-decoration: none;
- border: 1px solid #FF0000;
- background-color: #FFCCCC;
- display: block;
- font-style: normal;
- padding: 2px;
+ border-color: #f00;
+ background: #fcc;
}
.uci-change-list var,
.uci-change-legend-label var {
- text-decoration: none;
- border: 1px solid #CCCCCC;
- background-color: #EEEEEE;
- display: block;
- font-style: normal;
- padding: 2px;
+ border-color: #ccc;
+ background: #eee;
}
.uci-change-list var ins,
.uci-change-list var del {
- /*display: inline;*/
+ display: inline-block;
border: none;
- white-space: pre;
- font-style: normal;
- padding: 0px;
+ width: 100%;
+ padding: 0;
}
.uci-change-legend {
.uci-change-legend-label>var {
float: left;
margin-right: 4px;
- width: 10px;
- height: 10px;
+ width: 12px;
+ height: 12px;
display: block;
+ position: relative;
}
.uci-change-legend-label var ins,
.uci-change-legend-label var del {
- line-height: 6px;
border: none;
+ position: absolute;
+ top: 1px;
+ left: 1px;
+ right: 1px;
+ bottom: 1px;
}
.hide-xs {
display: none;
}
+
+ #dsl_status_table .ifacebox-body > span > strong {
+ min-width: 50%;
+ }
}
@media screen and (max-width: 480px) {
#cbi-network-switch_vlan .td.cbi-section-actions {
flex-basis: 100%;
}
+
+ #dsl_status_table .ifacebox-body > span > strong {
+ display: block;
+ width: 100%;
+ margin-top: .5em;
+ }
}
local function render_changes()
if tree.nodes[category] and tree.nodes[category].ucidata then
local ucic = 0
+ local i, j
for i, j in pairs(require("luci.model.uci").cursor():changes()) do
- for k, l in pairs(j) do
- for m, n in pairs(l) do
- ucic = ucic + 1;
- end
- end
+ ucic = ucic + #j
end
if ucic > 0 then