Add Luci Theme argon and app
- Also added missing depends from source: https://dl.openwrt.ai/packages-24.10/aarch64_cortex-a53/ - Argon theme and app source: https://github.com/jerrykuku/luci-theme-argon
@@ -0,0 +1,14 @@
|
||||
Package: libucode20230711
|
||||
Version: 2024.07.22~b610860d-r3
|
||||
Depends: libc, libjson-c5
|
||||
Provides: libucode
|
||||
Source: feeds/base/package/utils/ucode
|
||||
SourceName: ucode
|
||||
License: ISC
|
||||
Section: libs
|
||||
SourceDateEpoch: 1729600843
|
||||
ABIVersion: 20230711
|
||||
Maintainer: Jo-Philipp Wich <jo@mein.io>
|
||||
Architecture: aarch64_cortex-a53
|
||||
Installed-Size: 204800
|
||||
Description: The libucode package provides the shared runtime library for the ucode interpreter.
|
||||
5
ipk-source/libucode20230711_aarch64_cortex-a53/CONTROL/postinst
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
[ "${IPKG_NO_SCRIPT}" = "1" ] && exit 0
|
||||
[ -s ${IPKG_INSTROOT}/lib/functions.sh ] || exit 0
|
||||
. ${IPKG_INSTROOT}/lib/functions.sh
|
||||
default_postinst $0 $@
|
||||
4
ipk-source/libucode20230711_aarch64_cortex-a53/CONTROL/prerm
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
[ -s ${IPKG_INSTROOT}/lib/functions.sh ] || exit 0
|
||||
. ${IPKG_INSTROOT}/lib/functions.sh
|
||||
default_prerm $0 $@
|
||||
74
ipk-source/libucode20230711_aarch64_cortex-a53/build-ipk
Executable file
@@ -0,0 +1,74 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Script for building OpenWRT .ipk packages using tar by iamromulan
|
||||
# Works with SDXPPINN OpenWRT - iamromulan
|
||||
# This script accepts an optional path to the directory containing the `CONTROL` and `root` directories.
|
||||
# Usage: ./build-ipk.sh [path]
|
||||
# If no path is provided, the script will look in the current directory for `CONTROL` and `root` directories.
|
||||
# This will spit out an ipk in the current directory
|
||||
|
||||
# Check if the script is run as root. If not, rerun with sudo.
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo "Script is not running as root. Re-executing with sudo..."
|
||||
exec sudo "$0" "$@"
|
||||
fi
|
||||
|
||||
# Set the default build path to the current directory
|
||||
build_path="."
|
||||
|
||||
# Check if a path is provided as the first argument
|
||||
if [ "$1" ]; then
|
||||
build_path="$1"
|
||||
fi
|
||||
|
||||
# Check if the required directories are present in the specified path
|
||||
if [ ! -d "${build_path}/CONTROL" ] || [ ! -d "${build_path}/root" ]; then
|
||||
echo "Error: CONTROL and root directories must be present in the specified path (${build_path})."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Extract values from the CONTROL/control file in the specified path
|
||||
pkgname=$(grep -i '^Package:' "${build_path}/CONTROL/control" | awk '{print $2}')
|
||||
version=$(grep -i '^Version:' "${build_path}/CONTROL/control" | awk '{print $2}')
|
||||
architecture=$(grep -i '^Architecture:' "${build_path}/CONTROL/control" | awk '{print $2}')
|
||||
|
||||
# Check if values are extracted correctly
|
||||
if [ -z "$pkgname" ] || [ -z "$version" ] || [ -z "$architecture" ]; then
|
||||
echo "Error: Failed to extract Package, Version, or Architecture from ${build_path}/CONTROL/control."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Set the final IPK name based on the extracted values
|
||||
ipkname="${pkgname}_${version}_${architecture}.ipk"
|
||||
|
||||
# Ensure all CONTROL scripts are executable
|
||||
echo "Setting permissions for CONTROL scripts..."
|
||||
chmod +x "${build_path}/CONTROL"/*
|
||||
|
||||
# Set ownership for CONTROL and root files
|
||||
echo "Setting ownership for all package files..."
|
||||
chown -R root:root "${build_path}/CONTROL"/*
|
||||
chown -R root:root "${build_path}/root"/*
|
||||
|
||||
# Create control.tar.gz from the CONTROL directory
|
||||
echo "Creating control.tar.gz..."
|
||||
tar -czvf control.tar.gz -C "${build_path}/CONTROL" .
|
||||
|
||||
# Create data.tar.gz from the root directory
|
||||
echo "Creating data.tar.gz..."
|
||||
tar -czvf data.tar.gz -C "${build_path}/root" .
|
||||
|
||||
# Create debian-binary file (must contain exactly "2.0" without a newline)
|
||||
echo -n "2.0" > debian-binary
|
||||
chown -R root:root debian-binary
|
||||
|
||||
# Combine the components into the final .ipk file using tar
|
||||
echo "Packaging ${ipkname}..."
|
||||
tar -czvf "$ipkname" debian-binary control.tar.gz data.tar.gz
|
||||
|
||||
# Clean up intermediate files
|
||||
echo "Cleaning up temporary files..."
|
||||
rm -f control.tar.gz data.tar.gz debian-binary
|
||||
|
||||
echo "IPK package ${ipkname} created successfully using tar."
|
||||
|
||||
1
ipk-source/luci-app-argon-config/CONTROL/conffiles
Normal file
@@ -0,0 +1 @@
|
||||
/etc/config/argon
|
||||
11
ipk-source/luci-app-argon-config/CONTROL/control
Normal file
@@ -0,0 +1,11 @@
|
||||
Package: luci-app-argon-config
|
||||
Version: 0.9
|
||||
Depends: libc, luci-compat
|
||||
Source: /home/runner/work/gl-sdk-action/gl-sdk-action/buildsource/luci-app-argon-config
|
||||
SourceName: luci-app-argon-config
|
||||
Section: luci
|
||||
SourceDateEpoch: 1650782942
|
||||
Maintainer: OpenWrt LuCI community
|
||||
Architecture: all
|
||||
Installed-Size: 3586
|
||||
Description: LuCI page for Argon Config
|
||||
5
ipk-source/luci-app-argon-config/CONTROL/postinst
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
[ "${IPKG_NO_SCRIPT}" = "1" ] && exit 0
|
||||
[ -s ${IPKG_INSTROOT}/lib/functions.sh ] || exit 0
|
||||
. ${IPKG_INSTROOT}/lib/functions.sh
|
||||
default_postinst $0 $@
|
||||
7
ipk-source/luci-app-argon-config/CONTROL/postinst-pkg
Executable file
@@ -0,0 +1,7 @@
|
||||
[ -n "${IPKG_INSTROOT}" ] || {
|
||||
(. /etc/uci-defaults/luci-argon-config) && rm -f /etc/uci-defaults/luci-argon-config
|
||||
rm -f /tmp/luci-indexcache
|
||||
rm -rf /tmp/luci-modulecache/
|
||||
killall -HUP rpcd 2>/dev/null
|
||||
exit 0
|
||||
}
|
||||
4
ipk-source/luci-app-argon-config/CONTROL/prerm
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
[ -s ${IPKG_INSTROOT}/lib/functions.sh ] || exit 0
|
||||
. ${IPKG_INSTROOT}/lib/functions.sh
|
||||
default_prerm $0 $@
|
||||
74
ipk-source/luci-app-argon-config/build-ipk
Executable file
@@ -0,0 +1,74 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Script for building OpenWRT .ipk packages using tar by iamromulan
|
||||
# Works with SDXPPINN OpenWRT - iamromulan
|
||||
# This script accepts an optional path to the directory containing the `CONTROL` and `root` directories.
|
||||
# Usage: ./build-ipk.sh [path]
|
||||
# If no path is provided, the script will look in the current directory for `CONTROL` and `root` directories.
|
||||
# This will spit out an ipk in the current directory
|
||||
|
||||
# Check if the script is run as root. If not, rerun with sudo.
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo "Script is not running as root. Re-executing with sudo..."
|
||||
exec sudo "$0" "$@"
|
||||
fi
|
||||
|
||||
# Set the default build path to the current directory
|
||||
build_path="."
|
||||
|
||||
# Check if a path is provided as the first argument
|
||||
if [ "$1" ]; then
|
||||
build_path="$1"
|
||||
fi
|
||||
|
||||
# Check if the required directories are present in the specified path
|
||||
if [ ! -d "${build_path}/CONTROL" ] || [ ! -d "${build_path}/root" ]; then
|
||||
echo "Error: CONTROL and root directories must be present in the specified path (${build_path})."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Extract values from the CONTROL/control file in the specified path
|
||||
pkgname=$(grep -i '^Package:' "${build_path}/CONTROL/control" | awk '{print $2}')
|
||||
version=$(grep -i '^Version:' "${build_path}/CONTROL/control" | awk '{print $2}')
|
||||
architecture=$(grep -i '^Architecture:' "${build_path}/CONTROL/control" | awk '{print $2}')
|
||||
|
||||
# Check if values are extracted correctly
|
||||
if [ -z "$pkgname" ] || [ -z "$version" ] || [ -z "$architecture" ]; then
|
||||
echo "Error: Failed to extract Package, Version, or Architecture from ${build_path}/CONTROL/control."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Set the final IPK name based on the extracted values
|
||||
ipkname="${pkgname}_${version}_${architecture}.ipk"
|
||||
|
||||
# Ensure all CONTROL scripts are executable
|
||||
echo "Setting permissions for CONTROL scripts..."
|
||||
chmod +x "${build_path}/CONTROL"/*
|
||||
|
||||
# Set ownership for CONTROL and root files
|
||||
echo "Setting ownership for all package files..."
|
||||
chown -R root:root "${build_path}/CONTROL"/*
|
||||
chown -R root:root "${build_path}/root"/*
|
||||
|
||||
# Create control.tar.gz from the CONTROL directory
|
||||
echo "Creating control.tar.gz..."
|
||||
tar -czvf control.tar.gz -C "${build_path}/CONTROL" .
|
||||
|
||||
# Create data.tar.gz from the root directory
|
||||
echo "Creating data.tar.gz..."
|
||||
tar -czvf data.tar.gz -C "${build_path}/root" .
|
||||
|
||||
# Create debian-binary file (must contain exactly "2.0" without a newline)
|
||||
echo -n "2.0" > debian-binary
|
||||
chown -R root:root debian-binary
|
||||
|
||||
# Combine the components into the final .ipk file using tar
|
||||
echo "Packaging ${ipkname}..."
|
||||
tar -czvf "$ipkname" debian-binary control.tar.gz data.tar.gz
|
||||
|
||||
# Clean up intermediate files
|
||||
echo "Cleaning up temporary files..."
|
||||
rm -f control.tar.gz data.tar.gz debian-binary
|
||||
|
||||
echo "IPK package ${ipkname} created successfully using tar."
|
||||
|
||||
9
ipk-source/luci-app-argon-config/root/etc/config/argon
Normal file
@@ -0,0 +1,9 @@
|
||||
config global
|
||||
option primary '#5e72e4'
|
||||
option dark_primary '#483d8b'
|
||||
option blur '10'
|
||||
option blur_dark '10'
|
||||
option transparency '0.5'
|
||||
option transparency_dark '0.5'
|
||||
option mode 'normal'
|
||||
option bing_background '0'
|
||||
6
ipk-source/luci-app-argon-config/root/etc/uci-defaults/luci-argon-config
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
sed -i 's/cbi.submit\"] = true/cbi.submit\"] = \"1\"/g' /usr/lib/lua/luci/dispatcher.lua
|
||||
|
||||
rm -f /tmp/luci-indexcache
|
||||
exit 0
|
||||
@@ -0,0 +1,10 @@
|
||||
module("luci.controller.argon-config", package.seeall)
|
||||
|
||||
function index()
|
||||
if not nixio.fs.access('/www/luci-static/argon/css/cascade.css') then
|
||||
return
|
||||
end
|
||||
|
||||
local page = entry({"admin", "system", "argon-config"}, form("argon-config"), _("Argon Config"), 90)
|
||||
page.acl_depends = { "luci-app-argon-config" }
|
||||
end
|
||||
@@ -0,0 +1,217 @@
|
||||
local nxfs = require 'nixio.fs'
|
||||
local wa = require 'luci.tools.webadmin'
|
||||
local opkg = require 'luci.model.ipkg'
|
||||
local sys = require 'luci.sys'
|
||||
local http = require 'luci.http'
|
||||
local nutil = require 'nixio.util'
|
||||
local name = 'argon'
|
||||
local uci = require 'luci.model.uci'.cursor()
|
||||
|
||||
local fstat = nxfs.statvfs(opkg.overlay_root())
|
||||
local space_total = fstat and fstat.blocks or 0
|
||||
local space_free = fstat and fstat.bfree or 0
|
||||
local space_used = space_total - space_free
|
||||
|
||||
local free_byte = space_free * fstat.frsize
|
||||
|
||||
local primary, dark_primary, blur_radius, blur_radius_dark, blur_opacity, mode
|
||||
if nxfs.access('/etc/config/argon') then
|
||||
primary = uci:get_first('argon', 'global', 'primary')
|
||||
dark_primary = uci:get_first('argon', 'global', 'dark_primary')
|
||||
blur_radius = uci:get_first('argon', 'global', 'blur')
|
||||
blur_radius_dark = uci:get_first('argon', 'global', 'blur_dark')
|
||||
blur_opacity = uci:get_first('argon', 'global', 'transparency')
|
||||
blur_opacity_dark = uci:get_first('argon', 'global', 'transparency_dark')
|
||||
mode = uci:get_first('argon', 'global', 'mode')
|
||||
bing_background = uci:get_first('argon', 'global', 'bing_background')
|
||||
end
|
||||
|
||||
function glob(...)
|
||||
local iter, code, msg = nxfs.glob(...)
|
||||
if iter then
|
||||
return nutil.consume(iter)
|
||||
else
|
||||
return nil, code, msg
|
||||
end
|
||||
end
|
||||
|
||||
local transparency_sets = {
|
||||
0,
|
||||
0.1,
|
||||
0.2,
|
||||
0.3,
|
||||
0.4,
|
||||
0.5,
|
||||
0.6,
|
||||
0.7,
|
||||
0.8,
|
||||
0.9,
|
||||
1
|
||||
}
|
||||
|
||||
-- [[ 模糊设置 ]]--
|
||||
br = SimpleForm('config', translate('Argon Config'), translate('Here you can set the blur and transparency of the login page of argon theme, and manage the background pictures and videos.[Chrome is recommended]'))
|
||||
br.reset = false
|
||||
br.submit = false
|
||||
s = br:section(SimpleSection)
|
||||
|
||||
o = s:option(ListValue, 'bing_background', translate('Wallpaper Source'))
|
||||
o:value('0', translate('Built-in'))
|
||||
o:value('1', translate('Bing Wallpapers'))
|
||||
o.default = bing_background
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(ListValue, 'mode', translate('Theme mode'))
|
||||
o:value('normal', translate('Follow System'))
|
||||
o:value('light', translate('Force Light'))
|
||||
o:value('dark', translate('Force Dark'))
|
||||
o.default = mode
|
||||
o.rmempty = false
|
||||
o.description = translate('You can choose Theme color mode here')
|
||||
|
||||
o = s:option(Value, 'primary', translate('[Light mode] Primary Color'), translate('A HEX Color ; ( Default: #5e72e4 )'))
|
||||
o.default = primary
|
||||
o.datatype = ufloat
|
||||
o.rmempty = false
|
||||
|
||||
|
||||
|
||||
o = s:option(ListValue, 'transparency', translate('[Light mode] Transparency'), translate('0 transparent - 1 opaque ; ( Suggest: transparent: 0 or translucent preset: 0.5 )'))
|
||||
for _, v in ipairs(transparency_sets) do
|
||||
o:value(v)
|
||||
end
|
||||
o.default = blur_opacity
|
||||
o.datatype = ufloat
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, 'blur', translate('[Light mode] Frosted Glass Radius'), translate('Larger value will more blurred ; ( Suggest: clear: 1 or blur preset: 10 )'))
|
||||
o.default = blur_radius
|
||||
o.datatype = ufloat
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, 'dark_primary', translate('[Dark mode] Primary Color'), translate('A HEX Color ; ( Default: #483d8b )'))
|
||||
o.default = dark_primary
|
||||
o.datatype = ufloat
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(ListValue, 'transparency_dark', translate('[Dark mode] Transparency'), translate('0 transparent - 1 opaque ; ( Suggest: Black translucent preset: 0.5 )'))
|
||||
for _, v in ipairs(transparency_sets) do
|
||||
o:value(v)
|
||||
end
|
||||
o.default = blur_opacity_dark
|
||||
o.datatype = ufloat
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, 'blur_dark', translate('[Dark mode] Frosted Glass Radius'), translate('Larger value will more blurred ; ( Suggest: clear: 1 or blur preset: 10 )'))
|
||||
o.default = blur_radius_dark
|
||||
o.datatype = ufloat
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Button, 'save', translate('Save Changes'))
|
||||
o.inputstyle = 'reload'
|
||||
|
||||
function br.handle(self, state, data)
|
||||
if (state == FORM_VALID and data.blur ~= nil and data.blur_dark ~= nil and data.transparency ~= nil and data.transparency_dark ~= nil and data.mode ~= nil) then
|
||||
nxfs.writefile('/tmp/aaa', data)
|
||||
for key, value in pairs(data) do
|
||||
uci:set('argon','@global[0]',key,value)
|
||||
end
|
||||
uci:commit('argon')
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
ful = SimpleForm('upload', translate('Upload (Free: ') .. wa.byte_format(free_byte) .. ')', translate("You can upload files such as jpg,png,gif,mp4,webm files, To change the login page background."))
|
||||
ful.reset = false
|
||||
ful.submit = false
|
||||
|
||||
sul = ful:section(SimpleSection, '', translate("Upload file to '/www/luci-static/argon/background/'"))
|
||||
fu = sul:option(FileUpload, '')
|
||||
fu.template = 'argon-config/other_upload'
|
||||
um = sul:option(DummyValue, '', nil)
|
||||
um.template = 'argon-config/other_dvalue'
|
||||
|
||||
local dir, fd
|
||||
dir = '/www/luci-static/argon/background/'
|
||||
nxfs.mkdir(dir)
|
||||
http.setfilehandler(
|
||||
function(meta, chunk, eof)
|
||||
if not fd then
|
||||
if not meta then
|
||||
return
|
||||
end
|
||||
|
||||
if meta and chunk then
|
||||
fd = nixio.open(dir .. meta.file, 'w')
|
||||
end
|
||||
|
||||
if not fd then
|
||||
um.value = translate('Create upload file error.')
|
||||
return
|
||||
end
|
||||
end
|
||||
if chunk and fd then
|
||||
fd:write(chunk)
|
||||
end
|
||||
if eof and fd then
|
||||
fd:close()
|
||||
fd = nil
|
||||
um.value = translate('File saved to') .. ' "/www/luci-static/argon/background/' .. meta.file .. '"'
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
if http.formvalue('upload') then
|
||||
local f = http.formvalue('ulfile')
|
||||
if #f <= 0 then
|
||||
um.value = translate('No specify upload file.')
|
||||
end
|
||||
end
|
||||
|
||||
local function getSizeStr(size)
|
||||
local i = 0
|
||||
local byteUnits = {' kB', ' MB', ' GB', ' TB'}
|
||||
repeat
|
||||
size = size / 1024
|
||||
i = i + 1
|
||||
until (size <= 1024)
|
||||
return string.format('%.1f', size) .. byteUnits[i]
|
||||
end
|
||||
|
||||
local inits, attr = {}
|
||||
for i, f in ipairs(glob(dir .. '*')) do
|
||||
attr = nxfs.stat(f)
|
||||
if attr then
|
||||
inits[i] = {}
|
||||
inits[i].name = nxfs.basename(f)
|
||||
inits[i].mtime = os.date('%Y-%m-%d %H:%M:%S', attr.mtime)
|
||||
inits[i].modestr = attr.modestr
|
||||
inits[i].size = getSizeStr(attr.size)
|
||||
inits[i].remove = 0
|
||||
inits[i].install = false
|
||||
end
|
||||
end
|
||||
|
||||
form = SimpleForm('filelist', translate('Background file list'), nil)
|
||||
form.reset = false
|
||||
form.submit = false
|
||||
|
||||
tb = form:section(Table, inits)
|
||||
nm = tb:option(DummyValue, 'name', translate('File name'))
|
||||
mt = tb:option(DummyValue, 'mtime', translate('Modify time'))
|
||||
sz = tb:option(DummyValue, 'size', translate('Size'))
|
||||
btnrm = tb:option(Button, 'remove', translate('Remove'))
|
||||
btnrm.render = function(self, section, scope)
|
||||
self.inputstyle = 'remove'
|
||||
Button.render(self, section, scope)
|
||||
end
|
||||
|
||||
btnrm.write = function(self, section)
|
||||
local v = nxfs.unlink(dir .. nxfs.basename(inits[section].name))
|
||||
if v then
|
||||
table.remove(inits, section)
|
||||
end
|
||||
return v
|
||||
end
|
||||
|
||||
return br, ful, form
|
||||
@@ -0,0 +1,7 @@
|
||||
<%+cbi/valueheader%>
|
||||
<% if self:cfgvalue(section) ~= false then %>
|
||||
<input class="cbi-button cbi-input-<%=self.inputstyle or "button" %>" style="display: <%= display %>" type="submit"<%= attr("name", cbid) .. attr("id", cbid) .. attr("value", self.inputtitle or self.title)%> />
|
||||
<% else %>
|
||||
-
|
||||
<% end %>
|
||||
<%+cbi/valuefooter%>
|
||||
@@ -0,0 +1,8 @@
|
||||
<%+cbi/valueheader%>
|
||||
<span style="color: red">
|
||||
<%
|
||||
local val = self:cfgvalue(section) or self.default or ""
|
||||
write(pcdata(val))
|
||||
%>
|
||||
</span>
|
||||
<%+cbi/valuefooter%>
|
||||
@@ -0,0 +1,5 @@
|
||||
<%+cbi/valueheader%>
|
||||
<label class="cbi-value" style="display:inline-block; width: 130px" for="ulfile"><%:Choose local file:%></label>
|
||||
<input class="cbi-input-file" style="width: 400px" type="file" id="ulfile" name="ulfile" accept="image/png, image/jpeg, image/gif, video/mp4, video/webm"/>
|
||||
<input type="submit" class="btn cbi-button cbi-input-apply" name="upload" value="<%:Upload%>" />
|
||||
<%+cbi/valuefooter%>
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"luci-app-argon-config": {
|
||||
"description": "Grant UCI access for luci-app-argon-config",
|
||||
"read": {
|
||||
"uci": [ "argon" ]
|
||||
},
|
||||
"write": {
|
||||
"uci": [ "argon" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
Package: luci-lua-runtime
|
||||
Version: 25.034.70690~7b0663a
|
||||
Depends: libc, luci-base, lua, luci-lib-base, luci-lib-nixio, luci-lib-ip, luci-lib-jsonc, libubus-lua, liblucihttp-lua, ucode-mod-lua
|
||||
Source: feeds/luci/modules/luci-lua-runtime
|
||||
SourceName: luci-lua-runtime
|
||||
License: Apache-2.0
|
||||
Section: luci
|
||||
SourceDateEpoch: 1738611490
|
||||
URL: https://github.com/openwrt/luci
|
||||
Maintainer: OpenWrt LuCI community
|
||||
Architecture: aarch64_cortex-a53
|
||||
Installed-Size: 153600
|
||||
Description: LuCI Lua runtime libraries
|
||||
5
ipk-source/luci-lua-runtime_aarch64_cortex-a53/CONTROL/postinst
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
[ "${IPKG_NO_SCRIPT}" = "1" ] && exit 0
|
||||
[ -s ${IPKG_INSTROOT}/lib/functions.sh ] || exit 0
|
||||
. ${IPKG_INSTROOT}/lib/functions.sh
|
||||
default_postinst $0 $@
|
||||
5
ipk-source/luci-lua-runtime_aarch64_cortex-a53/CONTROL/postinst-pkg
Executable file
@@ -0,0 +1,5 @@
|
||||
[ -n "${IPKG_INSTROOT}" ] || { rm -f /tmp/luci-indexcache.*
|
||||
rm -rf /tmp/luci-modulecache/
|
||||
killall -HUP rpcd 2>/dev/null
|
||||
exit 0
|
||||
}
|
||||
4
ipk-source/luci-lua-runtime_aarch64_cortex-a53/CONTROL/prerm
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
[ -s ${IPKG_INSTROOT}/lib/functions.sh ] || exit 0
|
||||
. ${IPKG_INSTROOT}/lib/functions.sh
|
||||
default_prerm $0 $@
|
||||
74
ipk-source/luci-lua-runtime_aarch64_cortex-a53/build-ipk
Executable file
@@ -0,0 +1,74 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Script for building OpenWRT .ipk packages using tar by iamromulan
|
||||
# Works with SDXPPINN OpenWRT - iamromulan
|
||||
# This script accepts an optional path to the directory containing the `CONTROL` and `root` directories.
|
||||
# Usage: ./build-ipk.sh [path]
|
||||
# If no path is provided, the script will look in the current directory for `CONTROL` and `root` directories.
|
||||
# This will spit out an ipk in the current directory
|
||||
|
||||
# Check if the script is run as root. If not, rerun with sudo.
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo "Script is not running as root. Re-executing with sudo..."
|
||||
exec sudo "$0" "$@"
|
||||
fi
|
||||
|
||||
# Set the default build path to the current directory
|
||||
build_path="."
|
||||
|
||||
# Check if a path is provided as the first argument
|
||||
if [ "$1" ]; then
|
||||
build_path="$1"
|
||||
fi
|
||||
|
||||
# Check if the required directories are present in the specified path
|
||||
if [ ! -d "${build_path}/CONTROL" ] || [ ! -d "${build_path}/root" ]; then
|
||||
echo "Error: CONTROL and root directories must be present in the specified path (${build_path})."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Extract values from the CONTROL/control file in the specified path
|
||||
pkgname=$(grep -i '^Package:' "${build_path}/CONTROL/control" | awk '{print $2}')
|
||||
version=$(grep -i '^Version:' "${build_path}/CONTROL/control" | awk '{print $2}')
|
||||
architecture=$(grep -i '^Architecture:' "${build_path}/CONTROL/control" | awk '{print $2}')
|
||||
|
||||
# Check if values are extracted correctly
|
||||
if [ -z "$pkgname" ] || [ -z "$version" ] || [ -z "$architecture" ]; then
|
||||
echo "Error: Failed to extract Package, Version, or Architecture from ${build_path}/CONTROL/control."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Set the final IPK name based on the extracted values
|
||||
ipkname="${pkgname}_${version}_${architecture}.ipk"
|
||||
|
||||
# Ensure all CONTROL scripts are executable
|
||||
echo "Setting permissions for CONTROL scripts..."
|
||||
chmod +x "${build_path}/CONTROL"/*
|
||||
|
||||
# Set ownership for CONTROL and root files
|
||||
echo "Setting ownership for all package files..."
|
||||
chown -R root:root "${build_path}/CONTROL"/*
|
||||
chown -R root:root "${build_path}/root"/*
|
||||
|
||||
# Create control.tar.gz from the CONTROL directory
|
||||
echo "Creating control.tar.gz..."
|
||||
tar -czvf control.tar.gz -C "${build_path}/CONTROL" .
|
||||
|
||||
# Create data.tar.gz from the root directory
|
||||
echo "Creating data.tar.gz..."
|
||||
tar -czvf data.tar.gz -C "${build_path}/root" .
|
||||
|
||||
# Create debian-binary file (must contain exactly "2.0" without a newline)
|
||||
echo -n "2.0" > debian-binary
|
||||
chown -R root:root debian-binary
|
||||
|
||||
# Combine the components into the final .ipk file using tar
|
||||
echo "Packaging ${ipkname}..."
|
||||
tar -czvf "$ipkname" debian-binary control.tar.gz data.tar.gz
|
||||
|
||||
# Clean up intermediate files
|
||||
echo "Cleaning up temporary files..."
|
||||
rm -f control.tar.gz data.tar.gz debian-binary
|
||||
|
||||
echo "IPK package ${ipkname} created successfully using tar."
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
-- Copyright 2008 Steven Barth <steven@midlink.org>
|
||||
-- Copyright 2008 Jo-Philipp Wich <jow@openwrt.org>
|
||||
-- Licensed to the public under the Apache License 2.0.
|
||||
|
||||
local config = require "luci.config"
|
||||
local ccache = require "luci.ccache"
|
||||
|
||||
module "luci.cacheloader"
|
||||
|
||||
if config.ccache and config.ccache.enable == "1" then
|
||||
ccache.cache_ondemand()
|
||||
end
|
||||
@@ -0,0 +1,76 @@
|
||||
-- Copyright 2008 Steven Barth <steven@midlink.org>
|
||||
-- Copyright 2008 Jo-Philipp Wich <jow@openwrt.org>
|
||||
-- Licensed to the public under the Apache License 2.0.
|
||||
|
||||
local io = require "io"
|
||||
local fs = require "nixio.fs"
|
||||
local util = require "luci.util"
|
||||
local nixio = require "nixio"
|
||||
local debug = require "debug"
|
||||
local string = require "string"
|
||||
local package = require "package"
|
||||
|
||||
local type, loadfile = type, loadfile
|
||||
|
||||
|
||||
module "luci.ccache"
|
||||
|
||||
function cache_ondemand(...)
|
||||
if debug.getinfo(1, 'S').source ~= "=?" then
|
||||
cache_enable(...)
|
||||
end
|
||||
end
|
||||
|
||||
function cache_enable(cachepath, mode)
|
||||
cachepath = cachepath or "/tmp/luci-modulecache"
|
||||
mode = mode or "r--r--r--"
|
||||
|
||||
local loader = package.loaders[2]
|
||||
local uid = nixio.getuid()
|
||||
|
||||
if not fs.stat(cachepath) then
|
||||
fs.mkdir(cachepath)
|
||||
end
|
||||
|
||||
local function _encode_filename(name)
|
||||
local encoded = ""
|
||||
for i=1, #name do
|
||||
encoded = encoded .. ("%2X" % string.byte(name, i))
|
||||
end
|
||||
return encoded
|
||||
end
|
||||
|
||||
local function _load_sane(file)
|
||||
local stat = fs.stat(file)
|
||||
if stat and stat.uid == uid and stat.modestr == mode then
|
||||
return loadfile(file)
|
||||
end
|
||||
end
|
||||
|
||||
local function _write_sane(file, func)
|
||||
if nixio.getuid() == uid then
|
||||
local fp = io.open(file, "w")
|
||||
if fp then
|
||||
fp:write(util.get_bytecode(func))
|
||||
fp:close()
|
||||
fs.chmod(file, mode)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
package.loaders[2] = function(mod)
|
||||
local encoded = cachepath .. "/" .. _encode_filename(mod)
|
||||
local modcons = _load_sane(encoded)
|
||||
|
||||
if modcons then
|
||||
return modcons
|
||||
end
|
||||
|
||||
-- No cachefile
|
||||
modcons = loader(mod)
|
||||
if type(modcons) == "function" then
|
||||
_write_sane(encoded, modcons)
|
||||
end
|
||||
return modcons
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,18 @@
|
||||
-- Copyright 2008 Steven Barth <steven@midlink.org>
|
||||
-- Licensed to the public under the Apache License 2.0.
|
||||
|
||||
local util = require "luci.util"
|
||||
module("luci.config",
|
||||
function(m)
|
||||
if pcall(require, "luci.model.uci") then
|
||||
local config = util.threadlocal()
|
||||
setmetatable(m, {
|
||||
__index = function(tbl, key)
|
||||
if not config[key] then
|
||||
config[key] = luci.model.uci.cursor():get_all("luci", key)
|
||||
end
|
||||
return config[key]
|
||||
end
|
||||
})
|
||||
end
|
||||
end)
|
||||
@@ -0,0 +1,484 @@
|
||||
-- Copyright 2008 Steven Barth <steven@midlink.org>
|
||||
-- Copyright 2008-2015 Jo-Philipp Wich <jow@openwrt.org>
|
||||
-- Licensed to the public under the Apache License 2.0.
|
||||
|
||||
module("luci.dispatcher", package.seeall)
|
||||
|
||||
local http = _G.L.http
|
||||
|
||||
context = setmetatable({}, {
|
||||
__index = function(t, k)
|
||||
if k == "request" or k == "requestpath" then
|
||||
return _G.L.ctx.request_path
|
||||
elseif k == "requestargs" then
|
||||
return _G.L.ctx.request_args
|
||||
else
|
||||
return _G.L.ctx[k]
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
uci = require "luci.model.uci"
|
||||
uci:set_session_id(_G.L.ctx.authsession)
|
||||
|
||||
i18n = require "luci.i18n"
|
||||
i18n.setlanguage(_G.L.dispatcher.lang)
|
||||
|
||||
build_url = _G.L.dispatcher.build_url
|
||||
menu_json = _G.L.dispatcher.menu_json
|
||||
error404 = _G.L.dispatcher.error404
|
||||
error500 = _G.L.dispatcher.error500
|
||||
|
||||
function is_authenticated(auth)
|
||||
local session = _G.L.dispatcher.is_authenticated(auth)
|
||||
if session then
|
||||
return session.sid, session.data, session.acls
|
||||
end
|
||||
end
|
||||
|
||||
function assign(path, clone, title, order)
|
||||
local obj = node(unpack(path))
|
||||
|
||||
obj.title = title
|
||||
obj.order = order
|
||||
|
||||
setmetatable(obj, {__index = node(unpack(clone))})
|
||||
|
||||
return obj
|
||||
end
|
||||
|
||||
function entry(path, target, title, order)
|
||||
local c = node(unpack(path))
|
||||
|
||||
c.title = title
|
||||
c.order = order
|
||||
c.action = target
|
||||
|
||||
return c
|
||||
end
|
||||
|
||||
-- enabling the node.
|
||||
function get(...)
|
||||
return node(...)
|
||||
end
|
||||
|
||||
function node(...)
|
||||
local p = table.concat({ ... }, "/")
|
||||
|
||||
if not __entries[p] then
|
||||
__entries[p] = {}
|
||||
end
|
||||
|
||||
return __entries[p]
|
||||
end
|
||||
|
||||
function lookup(...)
|
||||
local i, path = nil, {}
|
||||
for i = 1, select('#', ...) do
|
||||
local name, arg = nil, tostring(select(i, ...))
|
||||
for name in arg:gmatch("[^/]+") do
|
||||
path[#path+1] = name
|
||||
end
|
||||
end
|
||||
|
||||
local node = menu_json()
|
||||
for i = 1, #path do
|
||||
node = node.children[path[i]]
|
||||
|
||||
if not node then
|
||||
return nil
|
||||
elseif node.leaf then
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
return node, build_url(unpack(path))
|
||||
end
|
||||
|
||||
|
||||
function process_lua_controller(path)
|
||||
local base = "/usr/lib/lua/luci/controller/"
|
||||
local modname = "luci.controller." .. path:sub(#base+1, #path-4):gsub("/", ".")
|
||||
local mod = require(modname)
|
||||
assert(mod ~= true,
|
||||
"Invalid controller file found\n" ..
|
||||
"The file '" .. path .. "' contains an invalid module line.\n" ..
|
||||
"Please verify whether the module name is set to '" .. modname ..
|
||||
"' - It must correspond to the file path!")
|
||||
|
||||
local idx = mod.index
|
||||
if type(idx) ~= "function" then
|
||||
return nil
|
||||
end
|
||||
|
||||
local entries = {}
|
||||
|
||||
__entries = entries
|
||||
__controller = modname
|
||||
|
||||
setfenv(idx, setmetatable({}, { __index = luci.dispatcher }))()
|
||||
|
||||
__entries = nil
|
||||
__controller = nil
|
||||
|
||||
-- fixup gathered node specs
|
||||
for path, entry in pairs(entries) do
|
||||
if entry.leaf then
|
||||
entry.wildcard = true
|
||||
end
|
||||
|
||||
if type(entry.file_depends) == "table" then
|
||||
for _, v in ipairs(entry.file_depends) do
|
||||
entry.depends = entry.depends or {}
|
||||
entry.depends.fs = entry.depends.fs or {}
|
||||
|
||||
local ft = fs.stat(v, "type")
|
||||
if ft == "dir" then
|
||||
entry.depends.fs[v] = "directory"
|
||||
elseif v:match("/s?bin/") then
|
||||
entry.depends.fs[v] = "executable"
|
||||
else
|
||||
entry.depends.fs[v] = "file"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if type(entry.uci_depends) == "table" then
|
||||
for k, v in pairs(entry.uci_depends) do
|
||||
entry.depends = entry.depends or {}
|
||||
entry.depends.uci = entry.depends.uci or {}
|
||||
entry.depends.uci[k] = v
|
||||
end
|
||||
end
|
||||
|
||||
if type(entry.acl_depends) == "table" then
|
||||
for _, acl in ipairs(entry.acl_depends) do
|
||||
entry.depends = entry.depends or {}
|
||||
entry.depends.acl = entry.depends.acl or {}
|
||||
entry.depends.acl[#entry.depends.acl + 1] = acl
|
||||
end
|
||||
end
|
||||
|
||||
if (entry.sysauth_authenticator ~= nil) or
|
||||
(entry.sysauth ~= nil and entry.sysauth ~= false)
|
||||
then
|
||||
if entry.sysauth_authenticator == "htmlauth" then
|
||||
entry.auth = {
|
||||
login = true,
|
||||
methods = { "cookie:sysauth_https", "cookie:sysauth_http" }
|
||||
}
|
||||
elseif path == "rpc" and modname == "luci.controller.rpc" then
|
||||
entry.auth = {
|
||||
login = false,
|
||||
methods = { "query:auth", "cookie:sysauth_https", "cookie:sysauth_http", "cookie:sysauth" }
|
||||
}
|
||||
elseif modname == "luci.controller.admin.uci" then
|
||||
entry.auth = {
|
||||
login = false,
|
||||
methods = { "param:sid" }
|
||||
}
|
||||
end
|
||||
elseif entry.sysauth == false then
|
||||
entry.auth = {}
|
||||
end
|
||||
|
||||
if entry.action == nil and type(entry.target) == "table" then
|
||||
entry.action = entry.target
|
||||
entry.target = nil
|
||||
end
|
||||
|
||||
entry.leaf = nil
|
||||
|
||||
entry.file_depends = nil
|
||||
entry.uci_depends = nil
|
||||
entry.acl_depends = nil
|
||||
|
||||
entry.sysauth = nil
|
||||
entry.sysauth_authenticator = nil
|
||||
end
|
||||
|
||||
return entries
|
||||
end
|
||||
|
||||
function invoke_cbi_action(model, config, ...)
|
||||
local cbi = require "luci.cbi"
|
||||
local tpl = require "luci.template"
|
||||
local util = require "luci.util"
|
||||
|
||||
if not config then
|
||||
config = {}
|
||||
end
|
||||
|
||||
local maps = cbi.load(model, ...)
|
||||
|
||||
local state = nil
|
||||
|
||||
local function has_uci_access(config, level)
|
||||
local rv = util.ubus("session", "access", {
|
||||
ubus_rpc_session = context.authsession,
|
||||
scope = "uci", object = config,
|
||||
["function"] = level
|
||||
})
|
||||
|
||||
return (type(rv) == "table" and rv.access == true) or false
|
||||
end
|
||||
|
||||
local i, res
|
||||
for i, res in ipairs(maps) do
|
||||
if util.instanceof(res, cbi.SimpleForm) then
|
||||
io.stderr:write("Model %s returns SimpleForm but is dispatched via cbi(),\n"
|
||||
% model)
|
||||
|
||||
io.stderr:write("please change %s to use the form() action instead.\n"
|
||||
% table.concat(context.request, "/"))
|
||||
end
|
||||
|
||||
res.flow = config
|
||||
local cstate = res:parse()
|
||||
if cstate and (not state or cstate < state) then
|
||||
state = cstate
|
||||
end
|
||||
end
|
||||
|
||||
local function _resolve_path(path)
|
||||
return type(path) == "table" and build_url(unpack(path)) or path
|
||||
end
|
||||
|
||||
if config.on_valid_to and state and state > 0 and state < 2 then
|
||||
http:redirect(_resolve_path(config.on_valid_to))
|
||||
return
|
||||
end
|
||||
|
||||
if config.on_changed_to and state and state > 1 then
|
||||
http:redirect(_resolve_path(config.on_changed_to))
|
||||
return
|
||||
end
|
||||
|
||||
if config.on_success_to and state and state > 0 then
|
||||
http:redirect(_resolve_path(config.on_success_to))
|
||||
return
|
||||
end
|
||||
|
||||
if config.state_handler then
|
||||
if not config.state_handler(state, maps) then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
http:header("X-CBI-State", state or 0)
|
||||
|
||||
if not config.noheader then
|
||||
_G.L.include("cbi/header", {state = state})
|
||||
end
|
||||
|
||||
local redirect
|
||||
local messages
|
||||
local applymap = false
|
||||
local pageaction = true
|
||||
local parsechain = { }
|
||||
local writable = false
|
||||
|
||||
for i, res in ipairs(maps) do
|
||||
if res.apply_needed and res.parsechain then
|
||||
local c
|
||||
for _, c in ipairs(res.parsechain) do
|
||||
parsechain[#parsechain+1] = c
|
||||
end
|
||||
applymap = true
|
||||
end
|
||||
|
||||
if res.redirect then
|
||||
redirect = redirect or res.redirect
|
||||
end
|
||||
|
||||
if res.pageaction == false then
|
||||
pageaction = false
|
||||
end
|
||||
|
||||
if res.message then
|
||||
messages = messages or { }
|
||||
messages[#messages+1] = res.message
|
||||
end
|
||||
end
|
||||
|
||||
for i, res in ipairs(maps) do
|
||||
local is_readable_map = has_uci_access(res.config, "read")
|
||||
local is_writable_map = has_uci_access(res.config, "write")
|
||||
|
||||
writable = writable or is_writable_map
|
||||
|
||||
res:render({
|
||||
firstmap = (i == 1),
|
||||
redirect = redirect,
|
||||
messages = messages,
|
||||
pageaction = pageaction,
|
||||
parsechain = parsechain,
|
||||
readable = is_readable_map,
|
||||
writable = is_writable_map
|
||||
})
|
||||
end
|
||||
|
||||
if not config.nofooter then
|
||||
_G.L.include("cbi/footer", {
|
||||
flow = config,
|
||||
pageaction = pageaction,
|
||||
redirect = redirect,
|
||||
state = state,
|
||||
autoapply = config.autoapply,
|
||||
trigger_apply = applymap,
|
||||
writable = writable
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
function invoke_form_action(model, ...)
|
||||
local cbi = require "luci.cbi"
|
||||
local tpl = require "luci.template"
|
||||
|
||||
local maps = luci.cbi.load(model, ...)
|
||||
local state = nil
|
||||
|
||||
local i, res
|
||||
for i, res in ipairs(maps) do
|
||||
local cstate = res:parse()
|
||||
if cstate and (not state or cstate < state) then
|
||||
state = cstate
|
||||
end
|
||||
end
|
||||
|
||||
http:header("X-CBI-State", state or 0)
|
||||
_G.L.include("header")
|
||||
for i, res in ipairs(maps) do
|
||||
res:render()
|
||||
end
|
||||
_G.L.include("footer")
|
||||
end
|
||||
|
||||
function render_lua_template(path)
|
||||
local tpl = require "luci.template"
|
||||
|
||||
tpl.render(path, getfenv(1))
|
||||
end
|
||||
|
||||
function test_post_security()
|
||||
if http:getenv("REQUEST_METHOD") ~= "POST" then
|
||||
http:status(405, "Method Not Allowed")
|
||||
http:header("Allow", "POST")
|
||||
return false
|
||||
end
|
||||
|
||||
if http:formvalue("token") ~= context.authtoken then
|
||||
http:status(403, "Forbidden")
|
||||
_G.L.include("csrftoken")
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
function call(name, ...)
|
||||
return {
|
||||
["type"] = "call",
|
||||
["module"] = __controller,
|
||||
["function"] = name,
|
||||
["parameters"] = select('#', ...) > 0 and {...} or nil
|
||||
}
|
||||
end
|
||||
|
||||
function post_on(params, name, ...)
|
||||
return {
|
||||
["type"] = "call",
|
||||
["module"] = __controller,
|
||||
["function"] = name,
|
||||
["parameters"] = select('#', ...) > 0 and {...} or nil,
|
||||
["post"] = params
|
||||
}
|
||||
end
|
||||
|
||||
function post(...)
|
||||
return post_on(true, ...)
|
||||
end
|
||||
|
||||
function view(name)
|
||||
return {
|
||||
["type"] = "view",
|
||||
["path"] = name
|
||||
}
|
||||
end
|
||||
|
||||
function template(name)
|
||||
return {
|
||||
["type"] = "template",
|
||||
["path"] = name
|
||||
}
|
||||
end
|
||||
|
||||
function cbi(model, config)
|
||||
return {
|
||||
["type"] = "call",
|
||||
["module"] = "luci.dispatcher",
|
||||
["function"] = "invoke_cbi_action",
|
||||
["parameters"] = { model, config or {} },
|
||||
["post"] = {
|
||||
["cbi.submit"] = true
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
function form(model)
|
||||
return {
|
||||
["type"] = "call",
|
||||
["module"] = "luci.dispatcher",
|
||||
["function"] = "invoke_form_action",
|
||||
["parameters"] = { model },
|
||||
["post"] = {
|
||||
["cbi.submit"] = true
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
function firstchild()
|
||||
return {
|
||||
["type"] = "firstchild"
|
||||
}
|
||||
end
|
||||
|
||||
function firstnode()
|
||||
return {
|
||||
["type"] = "firstchild",
|
||||
["recurse"] = true
|
||||
}
|
||||
end
|
||||
|
||||
function arcombine(trg1, trg2)
|
||||
return {
|
||||
["type"] = "arcombine",
|
||||
["targets"] = { trg1, trg2 } --,
|
||||
--env = getfenv(),
|
||||
}
|
||||
end
|
||||
|
||||
function alias(...)
|
||||
return {
|
||||
["type"] = "alias",
|
||||
["path"] = table.concat({ ... }, "/")
|
||||
}
|
||||
end
|
||||
|
||||
function rewrite(n, ...)
|
||||
return {
|
||||
["type"] = "rewrite",
|
||||
["path"] = table.concat({ ... }, "/"),
|
||||
["remove"] = n
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
translate = i18n.translate
|
||||
|
||||
-- This function does not actually translate the given argument but
|
||||
-- is used by build/i18n-scan.pl to find translatable entries.
|
||||
function _(text)
|
||||
return text
|
||||
end
|
||||
@@ -0,0 +1,55 @@
|
||||
-- Copyright 2008 Steven Barth <steven@midlink.org>
|
||||
-- Licensed to the public under the Apache License 2.0.
|
||||
|
||||
local tparser = require "luci.template.parser"
|
||||
local util = require "luci.util"
|
||||
local tostring = tostring
|
||||
|
||||
module "luci.i18n"
|
||||
|
||||
i18ndir = util.libpath() .. "/i18n/"
|
||||
context = util.threadlocal()
|
||||
default = "en"
|
||||
|
||||
|
||||
function setlanguage(lang)
|
||||
local code, subcode = lang:match("^([A-Za-z][A-Za-z])[%-_]([A-Za-z][A-Za-z])$")
|
||||
if not (code and subcode) then
|
||||
subcode = lang:match("^([A-Za-z][A-Za-z])$")
|
||||
if not subcode then
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
context.parent = code and code:lower()
|
||||
context.lang = context.parent and context.parent.."-"..subcode:lower() or subcode:lower()
|
||||
|
||||
if tparser.load_catalog(context.lang, i18ndir) and
|
||||
tparser.change_catalog(context.lang)
|
||||
then
|
||||
return context.lang
|
||||
|
||||
elseif context.parent then
|
||||
if tparser.load_catalog(context.parent, i18ndir) and
|
||||
tparser.change_catalog(context.parent)
|
||||
then
|
||||
return context.parent
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
function translate(key)
|
||||
return tparser.translate(key) or key
|
||||
end
|
||||
|
||||
function translatef(key, ...)
|
||||
return tostring(translate(key)):format(...)
|
||||
end
|
||||
|
||||
function dump()
|
||||
local rv = {}
|
||||
tparser.get_translations(function(k, v) rv[k] = v end)
|
||||
return rv
|
||||
end
|
||||
@@ -0,0 +1,508 @@
|
||||
-- Copyright 2008 Steven Barth <steven@midlink.org>
|
||||
-- Licensed to the public under the Apache License 2.0.
|
||||
|
||||
local os = require "os"
|
||||
local util = require "luci.util"
|
||||
local table = require "table"
|
||||
|
||||
|
||||
local setmetatable, rawget, rawset = setmetatable, rawget, rawset
|
||||
local require, getmetatable, assert = require, getmetatable, assert
|
||||
local error, pairs, ipairs, select = error, pairs, ipairs, select
|
||||
local type, tostring, tonumber, unpack = type, tostring, tonumber, unpack
|
||||
|
||||
-- The typical workflow for UCI is: Get a cursor instance from the
|
||||
-- cursor factory, modify data (via Cursor.add, Cursor.delete, etc.),
|
||||
-- save the changes to the staging area via Cursor.save and finally
|
||||
-- Cursor.commit the data to the actual config files.
|
||||
-- LuCI then needs to Cursor.apply the changes so daemons etc. are
|
||||
-- reloaded.
|
||||
module "luci.model.uci"
|
||||
|
||||
local ERRSTR = {
|
||||
"Invalid command",
|
||||
"Invalid argument",
|
||||
"Method not found",
|
||||
"Entry not found",
|
||||
"No data",
|
||||
"Permission denied",
|
||||
"Timeout",
|
||||
"Not supported",
|
||||
"Unknown error",
|
||||
"Connection failed"
|
||||
}
|
||||
|
||||
local session_id = nil
|
||||
|
||||
local function call(cmd, args)
|
||||
if type(args) == "table" and session_id then
|
||||
args.ubus_rpc_session = session_id
|
||||
end
|
||||
return util.ubus("uci", cmd, args)
|
||||
end
|
||||
|
||||
|
||||
function cursor()
|
||||
return _M
|
||||
end
|
||||
|
||||
function cursor_state()
|
||||
return _M
|
||||
end
|
||||
|
||||
function substate(self)
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
function get_confdir(self)
|
||||
return "/etc/config"
|
||||
end
|
||||
|
||||
function get_savedir(self)
|
||||
return "/tmp/.uci"
|
||||
end
|
||||
|
||||
function get_session_id(self)
|
||||
return session_id
|
||||
end
|
||||
|
||||
function set_confdir(self, directory)
|
||||
return false
|
||||
end
|
||||
|
||||
function set_savedir(self, directory)
|
||||
return false
|
||||
end
|
||||
|
||||
function set_session_id(self, id)
|
||||
session_id = id
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
function load(self, config)
|
||||
return true
|
||||
end
|
||||
|
||||
function save(self, config)
|
||||
return true
|
||||
end
|
||||
|
||||
function unload(self, config)
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
function changes(self, config)
|
||||
local rv, err = call("changes", { config = config })
|
||||
|
||||
if type(rv) == "table" and type(rv.changes) == "table" then
|
||||
return rv.changes
|
||||
elseif err then
|
||||
return nil, ERRSTR[err]
|
||||
else
|
||||
return { }
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function revert(self, config)
|
||||
local _, err = call("revert", { config = config })
|
||||
return (err == nil), ERRSTR[err]
|
||||
end
|
||||
|
||||
function commit(self, config)
|
||||
local _, err = call("commit", { config = config })
|
||||
return (err == nil), ERRSTR[err]
|
||||
end
|
||||
|
||||
function apply(self, rollback)
|
||||
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 90) or 0
|
||||
|
||||
_, err = call("apply", {
|
||||
timeout = (timeout > 90) and timeout or 90,
|
||||
rollback = true
|
||||
})
|
||||
|
||||
if not err then
|
||||
local now = os.time()
|
||||
local token = sys.uniqueid(16)
|
||||
|
||||
util.ubus("session", "set", {
|
||||
ubus_rpc_session = "00000000000000000000000000000000",
|
||||
values = {
|
||||
rollback = {
|
||||
token = token,
|
||||
session = session_id,
|
||||
timeout = now + timeout
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return token
|
||||
end
|
||||
else
|
||||
_, err = call("changes", {})
|
||||
|
||||
if not err then
|
||||
if type(_) == "table" and type(_.changes) == "table" then
|
||||
local k, v
|
||||
for k, v in pairs(_.changes) do
|
||||
_, err = call("commit", { config = k })
|
||||
if err then
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if not err then
|
||||
_, err = call("apply", { rollback = false })
|
||||
end
|
||||
end
|
||||
|
||||
return (err == nil), ERRSTR[err]
|
||||
end
|
||||
|
||||
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 false, "No data"
|
||||
end
|
||||
|
||||
function rollback(self)
|
||||
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 false, "No data"
|
||||
end
|
||||
|
||||
function rollback_pending(self)
|
||||
local rv, err = util.ubus("session", "get", {
|
||||
ubus_rpc_session = "00000000000000000000000000000000",
|
||||
keys = { "rollback" }
|
||||
})
|
||||
|
||||
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,
|
||||
rv.values.rollback.timeout - now,
|
||||
rv.values.rollback.session,
|
||||
rv.values.rollback.token
|
||||
end
|
||||
|
||||
return false, ERRSTR[err]
|
||||
end
|
||||
|
||||
|
||||
function foreach(self, config, stype, callback)
|
||||
if type(callback) == "function" then
|
||||
local rv, err = call("get", {
|
||||
config = config,
|
||||
type = stype
|
||||
})
|
||||
|
||||
if type(rv) == "table" and type(rv.values) == "table" then
|
||||
local sections = { }
|
||||
local res = false
|
||||
local index = 1
|
||||
|
||||
local _, section
|
||||
for _, section in pairs(rv.values) do
|
||||
section[".index"] = section[".index"] or index
|
||||
sections[index] = section
|
||||
index = index + 1
|
||||
end
|
||||
|
||||
table.sort(sections, function(a, b)
|
||||
return a[".index"] < b[".index"]
|
||||
end)
|
||||
|
||||
for _, section in ipairs(sections) do
|
||||
local continue = callback(section)
|
||||
res = true
|
||||
if continue == false then
|
||||
break
|
||||
end
|
||||
end
|
||||
return res
|
||||
else
|
||||
return false, ERRSTR[err] or "No data"
|
||||
end
|
||||
else
|
||||
return false, "Invalid argument"
|
||||
end
|
||||
end
|
||||
|
||||
local function _get(self, operation, config, section, option)
|
||||
if section == nil then
|
||||
return nil
|
||||
elseif type(option) == "string" and option:byte(1) ~= 46 then
|
||||
local rv, err = call(operation, {
|
||||
config = config,
|
||||
section = section,
|
||||
option = option
|
||||
})
|
||||
|
||||
if type(rv) == "table" then
|
||||
return rv.value or nil
|
||||
elseif err then
|
||||
return false, ERRSTR[err]
|
||||
else
|
||||
return nil
|
||||
end
|
||||
elseif option == nil then
|
||||
local values = self:get_all(config, section)
|
||||
if values then
|
||||
return values[".type"], values[".name"]
|
||||
else
|
||||
return nil
|
||||
end
|
||||
else
|
||||
return false, "Invalid argument"
|
||||
end
|
||||
end
|
||||
|
||||
function get(self, ...)
|
||||
return _get(self, "get", ...)
|
||||
end
|
||||
|
||||
function get_state(self, ...)
|
||||
return _get(self, "state", ...)
|
||||
end
|
||||
|
||||
function get_all(self, config, section)
|
||||
local rv, err = call("get", {
|
||||
config = config,
|
||||
section = section
|
||||
})
|
||||
|
||||
if type(rv) == "table" and type(rv.values) == "table" then
|
||||
return rv.values
|
||||
elseif err then
|
||||
return false, ERRSTR[err]
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
function get_bool(self, ...)
|
||||
local val = self:get(...)
|
||||
return (val == "1" or val == "true" or val == "yes" or val == "on")
|
||||
end
|
||||
|
||||
function get_first(self, config, stype, option, default)
|
||||
local rv = default
|
||||
|
||||
self:foreach(config, stype, function(s)
|
||||
local val = not option and s[".name"] or s[option]
|
||||
|
||||
if type(default) == "number" then
|
||||
val = tonumber(val)
|
||||
elseif type(default) == "boolean" then
|
||||
val = (val == "1" or val == "true" or
|
||||
val == "yes" or val == "on")
|
||||
end
|
||||
|
||||
if val ~= nil then
|
||||
rv = val
|
||||
return false
|
||||
end
|
||||
end)
|
||||
|
||||
return rv
|
||||
end
|
||||
|
||||
function get_list(self, config, section, option)
|
||||
if config and section and option then
|
||||
local val = self:get(config, section, option)
|
||||
return (type(val) == "table" and val or { val })
|
||||
end
|
||||
return { }
|
||||
end
|
||||
|
||||
|
||||
function section(self, config, stype, name, values)
|
||||
local rv, err = call("add", {
|
||||
config = config,
|
||||
type = stype,
|
||||
name = name,
|
||||
values = values
|
||||
})
|
||||
|
||||
if type(rv) == "table" then
|
||||
return rv.section
|
||||
elseif err then
|
||||
return false, ERRSTR[err]
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function add(self, config, stype)
|
||||
return self:section(config, stype)
|
||||
end
|
||||
|
||||
function set(self, config, section, option, ...)
|
||||
if select('#', ...) == 0 then
|
||||
local sname, err = self:section(config, option, section)
|
||||
return (not not sname), err
|
||||
else
|
||||
local _, err = call("set", {
|
||||
config = config,
|
||||
section = section,
|
||||
values = { [option] = select(1, ...) }
|
||||
})
|
||||
return (err == nil), ERRSTR[err]
|
||||
end
|
||||
end
|
||||
|
||||
function set_list(self, config, section, option, value)
|
||||
if section == nil or option == nil then
|
||||
return false
|
||||
elseif value == nil or (type(value) == "table" and #value == 0) then
|
||||
return self:delete(config, section, option)
|
||||
elseif type(value) == "table" then
|
||||
return self:set(config, section, option, value)
|
||||
else
|
||||
return self:set(config, section, option, { value })
|
||||
end
|
||||
end
|
||||
|
||||
function tset(self, config, section, values)
|
||||
local _, err = call("set", {
|
||||
config = config,
|
||||
section = section,
|
||||
values = values
|
||||
})
|
||||
return (err == nil), ERRSTR[err]
|
||||
end
|
||||
|
||||
function reorder(self, config, section, index)
|
||||
local sections
|
||||
|
||||
if type(section) == "string" and type(index) == "number" then
|
||||
local pos = 0
|
||||
|
||||
sections = { }
|
||||
|
||||
self:foreach(config, nil, function(s)
|
||||
if pos == index then
|
||||
pos = pos + 1
|
||||
end
|
||||
|
||||
if s[".name"] ~= section then
|
||||
pos = pos + 1
|
||||
sections[pos] = s[".name"]
|
||||
else
|
||||
sections[index + 1] = section
|
||||
end
|
||||
end)
|
||||
elseif type(section) == "table" then
|
||||
sections = section
|
||||
else
|
||||
return false, "Invalid argument"
|
||||
end
|
||||
|
||||
local _, err = call("order", {
|
||||
config = config,
|
||||
sections = sections
|
||||
})
|
||||
|
||||
return (err == nil), ERRSTR[err]
|
||||
end
|
||||
|
||||
|
||||
function delete(self, config, section, option)
|
||||
local _, err = call("delete", {
|
||||
config = config,
|
||||
section = section,
|
||||
option = option
|
||||
})
|
||||
return (err == nil), ERRSTR[err]
|
||||
end
|
||||
|
||||
function delete_all(self, config, stype, comparator)
|
||||
local _, err
|
||||
if type(comparator) == "table" then
|
||||
_, err = call("delete", {
|
||||
config = config,
|
||||
type = stype,
|
||||
match = comparator
|
||||
})
|
||||
elseif type(comparator) == "function" then
|
||||
local rv = call("get", {
|
||||
config = config,
|
||||
type = stype
|
||||
})
|
||||
|
||||
if type(rv) == "table" and type(rv.values) == "table" then
|
||||
local sname, section
|
||||
for sname, section in pairs(rv.values) do
|
||||
if comparator(section) then
|
||||
_, err = call("delete", {
|
||||
config = config,
|
||||
section = sname
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif comparator == nil then
|
||||
_, err = call("delete", {
|
||||
config = config,
|
||||
type = stype
|
||||
})
|
||||
else
|
||||
return false, "Invalid argument"
|
||||
end
|
||||
|
||||
return (err == nil), ERRSTR[err]
|
||||
end
|
||||
@@ -0,0 +1,6 @@
|
||||
-- Copyright 2009 Steven Barth <steven@midlink.org>
|
||||
-- Copyright 2009 Jo-Philipp Wich <jow@openwrt.org>
|
||||
-- Licensed to the public under the Apache License 2.0.
|
||||
|
||||
local util = require "luci.util"
|
||||
module("luci.store", util.threadlocal)
|
||||
@@ -0,0 +1,615 @@
|
||||
-- Copyright 2008 Steven Barth <steven@midlink.org>
|
||||
-- Licensed to the public under the Apache License 2.0.
|
||||
|
||||
local io = require "io"
|
||||
local os = require "os"
|
||||
local table = require "table"
|
||||
local nixio = require "nixio"
|
||||
local fs = require "nixio.fs"
|
||||
local uci = require "luci.model.uci"
|
||||
|
||||
local luci = {}
|
||||
luci.util = require "luci.util"
|
||||
luci.ip = require "luci.ip"
|
||||
|
||||
local tonumber, ipairs, pairs, pcall, type, next, setmetatable, require, select, unpack =
|
||||
tonumber, ipairs, pairs, pcall, type, next, setmetatable, require, select, unpack
|
||||
|
||||
|
||||
module "luci.sys"
|
||||
|
||||
function call(...)
|
||||
return os.execute(...) / 256
|
||||
end
|
||||
|
||||
exec = luci.util.exec
|
||||
|
||||
-- containing the whole environment is returned otherwise this function returns
|
||||
-- the corresponding string value for the given name or nil if no such variable
|
||||
-- exists.
|
||||
getenv = nixio.getenv
|
||||
|
||||
function hostname(newname)
|
||||
if type(newname) == "string" and #newname > 0 then
|
||||
fs.writefile( "/proc/sys/kernel/hostname", newname )
|
||||
return newname
|
||||
else
|
||||
return nixio.uname().nodename
|
||||
end
|
||||
end
|
||||
|
||||
function httpget(url, stream, target)
|
||||
if not target then
|
||||
local source = stream and io.popen or luci.util.exec
|
||||
return source("wget -qO- %s" % luci.util.shellquote(url))
|
||||
else
|
||||
return os.execute("wget -qO %s %s" %
|
||||
{luci.util.shellquote(target), luci.util.shellquote(url)})
|
||||
end
|
||||
end
|
||||
|
||||
function reboot()
|
||||
return os.execute("reboot >/dev/null 2>&1")
|
||||
end
|
||||
|
||||
function syslog()
|
||||
return luci.util.exec("logread")
|
||||
end
|
||||
|
||||
function dmesg()
|
||||
return luci.util.exec("dmesg")
|
||||
end
|
||||
|
||||
function uniqueid(bytes)
|
||||
local rand = fs.readfile("/dev/urandom", bytes)
|
||||
return rand and nixio.bin.hexlify(rand)
|
||||
end
|
||||
|
||||
function uptime()
|
||||
return nixio.sysinfo().uptime
|
||||
end
|
||||
|
||||
|
||||
net = {}
|
||||
|
||||
local function _nethints(what, callback)
|
||||
local _, k, e, mac, ip, name, duid, iaid
|
||||
local cur = uci.cursor()
|
||||
local ifn = { }
|
||||
local hosts = { }
|
||||
local lookup = { }
|
||||
|
||||
local function _add(i, ...)
|
||||
local k = select(i, ...)
|
||||
if k then
|
||||
if not hosts[k] then hosts[k] = { } end
|
||||
hosts[k][1] = select(1, ...) or hosts[k][1]
|
||||
hosts[k][2] = select(2, ...) or hosts[k][2]
|
||||
hosts[k][3] = select(3, ...) or hosts[k][3]
|
||||
hosts[k][4] = select(4, ...) or hosts[k][4]
|
||||
end
|
||||
end
|
||||
|
||||
luci.ip.neighbors(nil, function(neigh)
|
||||
if neigh.mac and neigh.family == 4 then
|
||||
_add(what, neigh.mac:string(), neigh.dest:string(), nil, nil)
|
||||
elseif neigh.mac and neigh.family == 6 then
|
||||
_add(what, neigh.mac:string(), nil, neigh.dest:string(), nil)
|
||||
end
|
||||
end)
|
||||
|
||||
if fs.access("/etc/ethers") then
|
||||
for e in io.lines("/etc/ethers") do
|
||||
mac, name = e:match("^([a-fA-F0-9:-]+)%s+(%S+)")
|
||||
mac = luci.ip.checkmac(mac)
|
||||
if mac and name then
|
||||
if luci.ip.checkip4(name) then
|
||||
_add(what, mac, name, nil, nil)
|
||||
else
|
||||
_add(what, mac, nil, nil, name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
cur:foreach("dhcp", "dnsmasq",
|
||||
function(s)
|
||||
if s.leasefile and fs.access(s.leasefile) then
|
||||
for e in io.lines(s.leasefile) do
|
||||
mac, ip, name = e:match("^%d+ (%S+) (%S+) (%S+)")
|
||||
mac = luci.ip.checkmac(mac)
|
||||
if mac and ip then
|
||||
_add(what, mac, ip, nil, name ~= "*" and name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
cur:foreach("dhcp", "odhcpd",
|
||||
function(s)
|
||||
if type(s.leasefile) == "string" and fs.access(s.leasefile) then
|
||||
for e in io.lines(s.leasefile) do
|
||||
duid, iaid, name, _, ip = e:match("^# %S+ (%S+) (%S+) (%S+) (-?%d+) %S+ %S+ ([0-9a-f:.]+)/[0-9]+")
|
||||
mac = net.duid_to_mac(duid)
|
||||
if mac then
|
||||
if ip and iaid == "ipv4" then
|
||||
_add(what, mac, ip, nil, name ~= "*" and name)
|
||||
elseif ip then
|
||||
_add(what, mac, nil, ip, name ~= "*" and name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
cur:foreach("dhcp", "host",
|
||||
function(s)
|
||||
for mac in luci.util.imatch(s.mac) do
|
||||
mac = luci.ip.checkmac(mac)
|
||||
if mac then
|
||||
_add(what, mac, s.ip, nil, s.name)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
for _, e in ipairs(nixio.getifaddrs()) do
|
||||
if e.name ~= "lo" then
|
||||
ifn[e.name] = ifn[e.name] or { }
|
||||
if e.family == "packet" and e.addr and #e.addr == 17 then
|
||||
ifn[e.name][1] = e.addr:upper()
|
||||
elseif e.family == "inet" then
|
||||
ifn[e.name][2] = e.addr
|
||||
elseif e.family == "inet6" then
|
||||
ifn[e.name][3] = e.addr
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for _, e in pairs(ifn) do
|
||||
if e[what] and (e[2] or e[3]) then
|
||||
_add(what, e[1], e[2], e[3], e[4])
|
||||
end
|
||||
end
|
||||
|
||||
for _, e in pairs(hosts) do
|
||||
lookup[#lookup+1] = (what > 1) and e[what] or (e[2] or e[3])
|
||||
end
|
||||
|
||||
if #lookup > 0 then
|
||||
lookup = luci.util.ubus("network.rrdns", "lookup", {
|
||||
addrs = lookup,
|
||||
timeout = 250,
|
||||
limit = 1000
|
||||
}) or { }
|
||||
end
|
||||
|
||||
for _, e in luci.util.kspairs(hosts) do
|
||||
callback(e[1], e[2], e[3], lookup[e[2]] or lookup[e[3]] or e[4])
|
||||
end
|
||||
end
|
||||
|
||||
-- Each entry contains the values in the following order:
|
||||
-- [ "mac", "name" ]
|
||||
function net.mac_hints(callback)
|
||||
if callback then
|
||||
_nethints(1, function(mac, v4, v6, name)
|
||||
name = name or v4
|
||||
if name and name ~= mac then
|
||||
callback(mac, name or v4)
|
||||
end
|
||||
end)
|
||||
else
|
||||
local rv = { }
|
||||
_nethints(1, function(mac, v4, v6, name)
|
||||
name = name or v4
|
||||
if name and name ~= mac then
|
||||
rv[#rv+1] = { mac, name or v4 }
|
||||
end
|
||||
end)
|
||||
return rv
|
||||
end
|
||||
end
|
||||
|
||||
-- Each entry contains the values in the following order:
|
||||
-- [ "ip", "name" ]
|
||||
function net.ipv4_hints(callback)
|
||||
if callback then
|
||||
_nethints(2, function(mac, v4, v6, name)
|
||||
name = name or mac
|
||||
if name and name ~= v4 then
|
||||
callback(v4, name)
|
||||
end
|
||||
end)
|
||||
else
|
||||
local rv = { }
|
||||
_nethints(2, function(mac, v4, v6, name)
|
||||
name = name or mac
|
||||
if name and name ~= v4 then
|
||||
rv[#rv+1] = { v4, name }
|
||||
end
|
||||
end)
|
||||
return rv
|
||||
end
|
||||
end
|
||||
|
||||
-- Each entry contains the values in the following order:
|
||||
-- [ "ip", "name" ]
|
||||
function net.ipv6_hints(callback)
|
||||
if callback then
|
||||
_nethints(3, function(mac, v4, v6, name)
|
||||
name = name or mac
|
||||
if name and name ~= v6 then
|
||||
callback(v6, name)
|
||||
end
|
||||
end)
|
||||
else
|
||||
local rv = { }
|
||||
_nethints(3, function(mac, v4, v6, name)
|
||||
name = name or mac
|
||||
if name and name ~= v6 then
|
||||
rv[#rv+1] = { v6, name }
|
||||
end
|
||||
end)
|
||||
return rv
|
||||
end
|
||||
end
|
||||
|
||||
function net.host_hints(callback)
|
||||
if callback then
|
||||
_nethints(1, function(mac, v4, v6, name)
|
||||
if mac and mac ~= "00:00:00:00:00:00" and (v4 or v6 or name) then
|
||||
callback(mac, v4, v6, name)
|
||||
end
|
||||
end)
|
||||
else
|
||||
local rv = { }
|
||||
_nethints(1, function(mac, v4, v6, name)
|
||||
if mac and mac ~= "00:00:00:00:00:00" and (v4 or v6 or name) then
|
||||
local e = { }
|
||||
if v4 then e.ipv4 = v4 end
|
||||
if v6 then e.ipv6 = v6 end
|
||||
if name then e.name = name end
|
||||
rv[mac] = e
|
||||
end
|
||||
end)
|
||||
return rv
|
||||
end
|
||||
end
|
||||
|
||||
function net.conntrack(callback)
|
||||
local ok, nfct = pcall(io.lines, "/proc/net/nf_conntrack")
|
||||
if not ok or not nfct then
|
||||
return nil
|
||||
end
|
||||
|
||||
local line, connt = nil, (not callback) and { }
|
||||
for line in nfct do
|
||||
local fam, l3, l4, rest =
|
||||
line:match("^(ipv[46]) +(%d+) +%S+ +(%d+) +(.+)$")
|
||||
|
||||
local timeout, tuples = rest:match("^(%d+) +(.+)$")
|
||||
|
||||
if not tuples then
|
||||
tuples = rest
|
||||
end
|
||||
|
||||
if fam and l3 and l4 and not tuples:match("^TIME_WAIT ") then
|
||||
l4 = nixio.getprotobynumber(l4)
|
||||
|
||||
local entry = {
|
||||
bytes = 0,
|
||||
packets = 0,
|
||||
layer3 = fam,
|
||||
layer4 = l4 and l4.name or "unknown",
|
||||
timeout = tonumber(timeout, 10)
|
||||
}
|
||||
|
||||
local key, val
|
||||
for key, val in tuples:gmatch("(%w+)=(%S+)") do
|
||||
if key == "bytes" or key == "packets" then
|
||||
entry[key] = entry[key] + tonumber(val, 10)
|
||||
elseif key == "src" or key == "dst" then
|
||||
if entry[key] == nil then
|
||||
entry[key] = luci.ip.new(val):string()
|
||||
end
|
||||
elseif key == "sport" or key == "dport" then
|
||||
if entry[key] == nil then
|
||||
entry[key] = val
|
||||
end
|
||||
elseif val then
|
||||
entry[key] = val
|
||||
end
|
||||
end
|
||||
|
||||
if callback then
|
||||
callback(entry)
|
||||
else
|
||||
connt[#connt+1] = entry
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return callback and true or connt
|
||||
end
|
||||
|
||||
function net.devices()
|
||||
local devs = {}
|
||||
local seen = {}
|
||||
for k, v in ipairs(nixio.getifaddrs()) do
|
||||
if v.name and not seen[v.name] then
|
||||
seen[v.name] = true
|
||||
devs[#devs+1] = v.name
|
||||
end
|
||||
end
|
||||
return devs
|
||||
end
|
||||
|
||||
function net.duid_to_mac(duid)
|
||||
local b1, b2, b3, b4, b5, b6
|
||||
|
||||
if type(duid) == "string" then
|
||||
-- DUID-LLT / Ethernet
|
||||
if #duid == 28 then
|
||||
b1, b2, b3, b4, b5, b6 = duid:match("^00010001(%x%x)(%x%x)(%x%x)(%x%x)(%x%x)(%x%x)%x%x%x%x%x%x%x%x$")
|
||||
|
||||
-- DUID-LL / Ethernet
|
||||
elseif #duid == 20 then
|
||||
b1, b2, b3, b4, b5, b6 = duid:match("^00030001(%x%x)(%x%x)(%x%x)(%x%x)(%x%x)(%x%x)$")
|
||||
|
||||
-- DUID-LL / Ethernet (Without Header)
|
||||
elseif #duid == 12 then
|
||||
b1, b2, b3, b4, b5, b6 = duid:match("^(%x%x)(%x%x)(%x%x)(%x%x)(%x%x)(%x%x)$")
|
||||
end
|
||||
end
|
||||
|
||||
return b1 and luci.ip.checkmac(table.concat({ b1, b2, b3, b4, b5, b6 }, ":"))
|
||||
end
|
||||
|
||||
process = {}
|
||||
|
||||
function process.info(key)
|
||||
local s = {uid = nixio.getuid(), gid = nixio.getgid()}
|
||||
return not key and s or s[key]
|
||||
end
|
||||
|
||||
function process.list()
|
||||
local data = {}
|
||||
local k
|
||||
local ps = luci.util.execi("/bin/busybox top -bn1")
|
||||
|
||||
if not ps then
|
||||
return
|
||||
end
|
||||
|
||||
for line in ps do
|
||||
local pid, ppid, user, stat, vsz, mem, cpu, cmd = line:match(
|
||||
"^ *(%d+) +(%d+) +(%S.-%S) +([RSDZTW][<NW ][<N ]) +(%d+m?) +(%d+%%) +(%d+%%) +(.+)"
|
||||
)
|
||||
|
||||
local idx = tonumber(pid)
|
||||
if idx and not cmd:match("top %-bn1") then
|
||||
data[idx] = {
|
||||
['PID'] = pid,
|
||||
['PPID'] = ppid,
|
||||
['USER'] = user,
|
||||
['STAT'] = stat,
|
||||
['VSZ'] = vsz,
|
||||
['%MEM'] = mem,
|
||||
['%CPU'] = cpu,
|
||||
['COMMAND'] = cmd
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
return data
|
||||
end
|
||||
|
||||
function process.setgroup(gid)
|
||||
return nixio.setgid(gid)
|
||||
end
|
||||
|
||||
function process.setuser(uid)
|
||||
return nixio.setuid(uid)
|
||||
end
|
||||
|
||||
process.signal = nixio.kill
|
||||
|
||||
local function xclose(fd)
|
||||
if fd and fd:fileno() > 2 then
|
||||
fd:close()
|
||||
end
|
||||
end
|
||||
|
||||
function process.exec(command, stdout, stderr, nowait)
|
||||
local out_r, out_w, err_r, err_w
|
||||
if stdout then out_r, out_w = nixio.pipe() end
|
||||
if stderr then err_r, err_w = nixio.pipe() end
|
||||
|
||||
local pid = nixio.fork()
|
||||
if pid == 0 then
|
||||
nixio.chdir("/")
|
||||
|
||||
local null = nixio.open("/dev/null", "w+")
|
||||
if null then
|
||||
nixio.dup(out_w or null, nixio.stdout)
|
||||
nixio.dup(err_w or null, nixio.stderr)
|
||||
nixio.dup(null, nixio.stdin)
|
||||
xclose(out_w)
|
||||
xclose(out_r)
|
||||
xclose(err_w)
|
||||
xclose(err_r)
|
||||
xclose(null)
|
||||
end
|
||||
|
||||
nixio.exec(unpack(command))
|
||||
os.exit(-1)
|
||||
end
|
||||
|
||||
local _, pfds, rv = nil, {}, { code = -1, pid = pid }
|
||||
|
||||
xclose(out_w)
|
||||
xclose(err_w)
|
||||
|
||||
if out_r then
|
||||
pfds[#pfds+1] = {
|
||||
fd = out_r,
|
||||
cb = type(stdout) == "function" and stdout,
|
||||
name = "stdout",
|
||||
events = nixio.poll_flags("in", "err", "hup")
|
||||
}
|
||||
end
|
||||
|
||||
if err_r then
|
||||
pfds[#pfds+1] = {
|
||||
fd = err_r,
|
||||
cb = type(stderr) == "function" and stderr,
|
||||
name = "stderr",
|
||||
events = nixio.poll_flags("in", "err", "hup")
|
||||
}
|
||||
end
|
||||
|
||||
while #pfds > 0 do
|
||||
local nfds, err = nixio.poll(pfds, -1)
|
||||
if not nfds and err ~= nixio.const.EINTR then
|
||||
break
|
||||
end
|
||||
|
||||
local i
|
||||
for i = #pfds, 1, -1 do
|
||||
local rfd = pfds[i]
|
||||
if rfd.revents > 0 then
|
||||
local chunk, err = rfd.fd:read(4096)
|
||||
if chunk and #chunk > 0 then
|
||||
if rfd.cb then
|
||||
rfd.cb(chunk)
|
||||
else
|
||||
rfd.buf = rfd.buf or {}
|
||||
rfd.buf[#rfd.buf + 1] = chunk
|
||||
end
|
||||
else
|
||||
table.remove(pfds, i)
|
||||
if rfd.buf then
|
||||
rv[rfd.name] = table.concat(rfd.buf, "")
|
||||
end
|
||||
rfd.fd:close()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if not nowait then
|
||||
_, _, rv.code = nixio.waitpid(pid)
|
||||
end
|
||||
|
||||
return rv
|
||||
end
|
||||
|
||||
|
||||
user = {}
|
||||
|
||||
-- { "uid", "gid", "name", "passwd", "dir", "shell", "gecos" }
|
||||
user.getuser = nixio.getpw
|
||||
|
||||
function user.getpasswd(username)
|
||||
local pwe = nixio.getsp and nixio.getsp(username) or nixio.getpw(username)
|
||||
local pwh = pwe and (pwe.pwdp or pwe.passwd)
|
||||
if not pwh or #pwh < 1 then
|
||||
return nil, pwe
|
||||
else
|
||||
return pwh, pwe
|
||||
end
|
||||
end
|
||||
|
||||
function user.checkpasswd(username, pass)
|
||||
local pwh, pwe = user.getpasswd(username)
|
||||
if pwe then
|
||||
return (pwh == nil or nixio.crypt(pass, pwh) == pwh)
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function user.setpasswd(username, password)
|
||||
return os.execute("(echo %s; sleep 1; echo %s) | passwd %s >/dev/null 2>&1" %{
|
||||
luci.util.shellquote(password),
|
||||
luci.util.shellquote(password),
|
||||
luci.util.shellquote(username)
|
||||
})
|
||||
end
|
||||
|
||||
|
||||
wifi = {}
|
||||
|
||||
function wifi.getiwinfo(ifname)
|
||||
local ntm = require "luci.model.network"
|
||||
|
||||
ntm.init()
|
||||
|
||||
local wnet = ntm:get_wifinet(ifname)
|
||||
if wnet and wnet.iwinfo then
|
||||
return wnet.iwinfo
|
||||
end
|
||||
|
||||
local wdev = ntm:get_wifidev(ifname)
|
||||
if wdev and wdev.iwinfo then
|
||||
return wdev.iwinfo
|
||||
end
|
||||
|
||||
return { ifname = ifname }
|
||||
end
|
||||
|
||||
|
||||
init = {}
|
||||
init.dir = "/etc/init.d/"
|
||||
|
||||
function init.names()
|
||||
local names = { }
|
||||
for name in fs.glob(init.dir.."*") do
|
||||
names[#names+1] = fs.basename(name)
|
||||
end
|
||||
return names
|
||||
end
|
||||
|
||||
function init.index(name)
|
||||
name = fs.basename(name)
|
||||
if fs.access(init.dir..name) then
|
||||
return call("env -i sh -c 'source %s%s enabled; exit ${START:-255}' >/dev/null"
|
||||
%{ init.dir, name })
|
||||
end
|
||||
end
|
||||
|
||||
local function init_action(action, name)
|
||||
name = fs.basename(name)
|
||||
if fs.access(init.dir..name) then
|
||||
return call("env -i %s%s %s >/dev/null" %{ init.dir, name, action })
|
||||
end
|
||||
end
|
||||
|
||||
function init.enabled(name)
|
||||
return (init_action("enabled", name) == 0)
|
||||
end
|
||||
|
||||
function init.enable(name)
|
||||
return (init_action("enable", name) == 0)
|
||||
end
|
||||
|
||||
function init.disable(name)
|
||||
return (init_action("disable", name) == 0)
|
||||
end
|
||||
|
||||
function init.start(name)
|
||||
return (init_action("start", name) == 0)
|
||||
end
|
||||
|
||||
function init.stop(name)
|
||||
return (init_action("stop", name) == 0)
|
||||
end
|
||||
|
||||
function init.restart(name)
|
||||
return (init_action("restart", name) == 0)
|
||||
end
|
||||
|
||||
function init.reload(name)
|
||||
return (init_action("reload", name) == 0)
|
||||
end
|
||||
@@ -0,0 +1,19 @@
|
||||
-- Licensed to the public under the Apache License 2.0.
|
||||
|
||||
local setmetatable, require, rawget, rawset = setmetatable, require, rawget, rawset
|
||||
|
||||
module "luci.sys.zoneinfo"
|
||||
|
||||
setmetatable(_M, {
|
||||
__index = function(t, k)
|
||||
if k == "TZ" and not rawget(t, k) then
|
||||
local m = require "luci.sys.zoneinfo.tzdata"
|
||||
rawset(t, k, rawget(m, k))
|
||||
elseif k == "OFFSET" and not rawget(t, k) then
|
||||
local m = require "luci.sys.zoneinfo.tzoffset"
|
||||
rawset(t, k, rawget(m, k))
|
||||
end
|
||||
|
||||
return rawget(t, k)
|
||||
end
|
||||
})
|
||||
@@ -0,0 +1,455 @@
|
||||
-- Licensed to the public under the Apache License 2.0.
|
||||
|
||||
module "luci.sys.zoneinfo.tzdata"
|
||||
|
||||
TZ = {
|
||||
{ 'Africa/Abidjan', 'GMT0' },
|
||||
{ 'Africa/Accra', 'GMT0' },
|
||||
{ 'Africa/Addis Ababa', 'EAT-3' },
|
||||
{ 'Africa/Algiers', 'CET-1' },
|
||||
{ 'Africa/Asmara', 'EAT-3' },
|
||||
{ 'Africa/Bamako', 'GMT0' },
|
||||
{ 'Africa/Bangui', 'WAT-1' },
|
||||
{ 'Africa/Banjul', 'GMT0' },
|
||||
{ 'Africa/Bissau', 'GMT0' },
|
||||
{ 'Africa/Blantyre', 'CAT-2' },
|
||||
{ 'Africa/Brazzaville', 'WAT-1' },
|
||||
{ 'Africa/Bujumbura', 'CAT-2' },
|
||||
{ 'Africa/Cairo', 'EET-2' },
|
||||
{ 'Africa/Casablanca', '<+01>-1' },
|
||||
{ 'Africa/Ceuta', 'CET-1CEST,M3.5.0,M10.5.0/3' },
|
||||
{ 'Africa/Conakry', 'GMT0' },
|
||||
{ 'Africa/Dakar', 'GMT0' },
|
||||
{ 'Africa/Dar es Salaam', 'EAT-3' },
|
||||
{ 'Africa/Djibouti', 'EAT-3' },
|
||||
{ 'Africa/Douala', 'WAT-1' },
|
||||
{ 'Africa/El Aaiun', '<+01>-1' },
|
||||
{ 'Africa/Freetown', 'GMT0' },
|
||||
{ 'Africa/Gaborone', 'CAT-2' },
|
||||
{ 'Africa/Harare', 'CAT-2' },
|
||||
{ 'Africa/Johannesburg', 'SAST-2' },
|
||||
{ 'Africa/Juba', 'CAT-2' },
|
||||
{ 'Africa/Kampala', 'EAT-3' },
|
||||
{ 'Africa/Khartoum', 'CAT-2' },
|
||||
{ 'Africa/Kigali', 'CAT-2' },
|
||||
{ 'Africa/Kinshasa', 'WAT-1' },
|
||||
{ 'Africa/Lagos', 'WAT-1' },
|
||||
{ 'Africa/Libreville', 'WAT-1' },
|
||||
{ 'Africa/Lome', 'GMT0' },
|
||||
{ 'Africa/Luanda', 'WAT-1' },
|
||||
{ 'Africa/Lubumbashi', 'CAT-2' },
|
||||
{ 'Africa/Lusaka', 'CAT-2' },
|
||||
{ 'Africa/Malabo', 'WAT-1' },
|
||||
{ 'Africa/Maputo', 'CAT-2' },
|
||||
{ 'Africa/Maseru', 'SAST-2' },
|
||||
{ 'Africa/Mbabane', 'SAST-2' },
|
||||
{ 'Africa/Mogadishu', 'EAT-3' },
|
||||
{ 'Africa/Monrovia', 'GMT0' },
|
||||
{ 'Africa/Nairobi', 'EAT-3' },
|
||||
{ 'Africa/Ndjamena', 'WAT-1' },
|
||||
{ 'Africa/Niamey', 'WAT-1' },
|
||||
{ 'Africa/Nouakchott', 'GMT0' },
|
||||
{ 'Africa/Ouagadougou', 'GMT0' },
|
||||
{ 'Africa/Porto-Novo', 'WAT-1' },
|
||||
{ 'Africa/Sao Tome', 'GMT0' },
|
||||
{ 'Africa/Tripoli', 'EET-2' },
|
||||
{ 'Africa/Tunis', 'CET-1' },
|
||||
{ 'Africa/Windhoek', 'CAT-2' },
|
||||
{ 'America/Adak', 'HST10HDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Anchorage', 'AKST9AKDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Anguilla', 'AST4' },
|
||||
{ 'America/Antigua', 'AST4' },
|
||||
{ 'America/Araguaina', '<-03>3' },
|
||||
{ 'America/Argentina/Buenos Aires', '<-03>3' },
|
||||
{ 'America/Argentina/Catamarca', '<-03>3' },
|
||||
{ 'America/Argentina/Cordoba', '<-03>3' },
|
||||
{ 'America/Argentina/Jujuy', '<-03>3' },
|
||||
{ 'America/Argentina/La Rioja', '<-03>3' },
|
||||
{ 'America/Argentina/Mendoza', '<-03>3' },
|
||||
{ 'America/Argentina/Rio Gallegos', '<-03>3' },
|
||||
{ 'America/Argentina/Salta', '<-03>3' },
|
||||
{ 'America/Argentina/San Juan', '<-03>3' },
|
||||
{ 'America/Argentina/San Luis', '<-03>3' },
|
||||
{ 'America/Argentina/Tucuman', '<-03>3' },
|
||||
{ 'America/Argentina/Ushuaia', '<-03>3' },
|
||||
{ 'America/Aruba', 'AST4' },
|
||||
{ 'America/Asuncion', '<-04>4<-03>,M10.1.0/0,M3.4.0/0' },
|
||||
{ 'America/Atikokan', 'EST5' },
|
||||
{ 'America/Bahia', '<-03>3' },
|
||||
{ 'America/Bahia Banderas', 'CST6CDT,M4.1.0,M10.5.0' },
|
||||
{ 'America/Barbados', 'AST4' },
|
||||
{ 'America/Belem', '<-03>3' },
|
||||
{ 'America/Belize', 'CST6' },
|
||||
{ 'America/Blanc-Sablon', 'AST4' },
|
||||
{ 'America/Boa Vista', '<-04>4' },
|
||||
{ 'America/Bogota', '<-05>5' },
|
||||
{ 'America/Boise', 'MST7MDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Cambridge Bay', 'MST7MDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Campo Grande', '<-04>4' },
|
||||
{ 'America/Cancun', 'EST5' },
|
||||
{ 'America/Caracas', '<-04>4' },
|
||||
{ 'America/Cayenne', '<-03>3' },
|
||||
{ 'America/Cayman', 'EST5' },
|
||||
{ 'America/Chicago', 'CST6CDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Chihuahua', 'MST7MDT,M4.1.0,M10.5.0' },
|
||||
{ 'America/Costa Rica', 'CST6' },
|
||||
{ 'America/Creston', 'MST7' },
|
||||
{ 'America/Cuiaba', '<-04>4' },
|
||||
{ 'America/Curacao', 'AST4' },
|
||||
{ 'America/Danmarkshavn', 'GMT0' },
|
||||
{ 'America/Dawson', 'MST7' },
|
||||
{ 'America/Dawson Creek', 'MST7' },
|
||||
{ 'America/Denver', 'MST7MDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Detroit', 'EST5EDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Dominica', 'AST4' },
|
||||
{ 'America/Edmonton', 'MST7MDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Eirunepe', '<-05>5' },
|
||||
{ 'America/El Salvador', 'CST6' },
|
||||
{ 'America/Fort Nelson', 'MST7' },
|
||||
{ 'America/Fortaleza', '<-03>3' },
|
||||
{ 'America/Glace Bay', 'AST4ADT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Goose Bay', 'AST4ADT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Grand Turk', 'EST5EDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Grenada', 'AST4' },
|
||||
{ 'America/Guadeloupe', 'AST4' },
|
||||
{ 'America/Guatemala', 'CST6' },
|
||||
{ 'America/Guayaquil', '<-05>5' },
|
||||
{ 'America/Guyana', '<-04>4' },
|
||||
{ 'America/Halifax', 'AST4ADT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Havana', 'CST5CDT,M3.2.0/0,M11.1.0/1' },
|
||||
{ 'America/Hermosillo', 'MST7' },
|
||||
{ 'America/Indiana/Indianapolis', 'EST5EDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Indiana/Knox', 'CST6CDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Indiana/Marengo', 'EST5EDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Indiana/Petersburg', 'EST5EDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Indiana/Tell City', 'CST6CDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Indiana/Vevay', 'EST5EDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Indiana/Vincennes', 'EST5EDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Indiana/Winamac', 'EST5EDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Inuvik', 'MST7MDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Iqaluit', 'EST5EDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Jamaica', 'EST5' },
|
||||
{ 'America/Juneau', 'AKST9AKDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Kentucky/Louisville', 'EST5EDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Kentucky/Monticello', 'EST5EDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Kralendijk', 'AST4' },
|
||||
{ 'America/La Paz', '<-04>4' },
|
||||
{ 'America/Lima', '<-05>5' },
|
||||
{ 'America/Los Angeles', 'PST8PDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Lower Princes', 'AST4' },
|
||||
{ 'America/Maceio', '<-03>3' },
|
||||
{ 'America/Managua', 'CST6' },
|
||||
{ 'America/Manaus', '<-04>4' },
|
||||
{ 'America/Marigot', 'AST4' },
|
||||
{ 'America/Martinique', 'AST4' },
|
||||
{ 'America/Matamoros', 'CST6CDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Mazatlan', 'MST7MDT,M4.1.0,M10.5.0' },
|
||||
{ 'America/Menominee', 'CST6CDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Merida', 'CST6CDT,M4.1.0,M10.5.0' },
|
||||
{ 'America/Metlakatla', 'AKST9AKDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Mexico City', 'CST6CDT,M4.1.0,M10.5.0' },
|
||||
{ 'America/Miquelon', '<-03>3<-02>,M3.2.0,M11.1.0' },
|
||||
{ 'America/Moncton', 'AST4ADT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Monterrey', 'CST6CDT,M4.1.0,M10.5.0' },
|
||||
{ 'America/Montevideo', '<-03>3' },
|
||||
{ 'America/Montserrat', 'AST4' },
|
||||
{ 'America/Nassau', 'EST5EDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/New York', 'EST5EDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Nipigon', 'EST5EDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Nome', 'AKST9AKDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Noronha', '<-02>2' },
|
||||
{ 'America/North Dakota/Beulah', 'CST6CDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/North Dakota/Center', 'CST6CDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/North Dakota/New Salem', 'CST6CDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Nuuk', '<-03>3<-02>,M3.5.0/-2,M10.5.0/-1' },
|
||||
{ 'America/Ojinaga', 'MST7MDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Panama', 'EST5' },
|
||||
{ 'America/Pangnirtung', 'EST5EDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Paramaribo', '<-03>3' },
|
||||
{ 'America/Phoenix', 'MST7' },
|
||||
{ 'America/Port of Spain', 'AST4' },
|
||||
{ 'America/Port-au-Prince', 'EST5EDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Porto Velho', '<-04>4' },
|
||||
{ 'America/Puerto Rico', 'AST4' },
|
||||
{ 'America/Punta Arenas', '<-03>3' },
|
||||
{ 'America/Rainy River', 'CST6CDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Rankin Inlet', 'CST6CDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Recife', '<-03>3' },
|
||||
{ 'America/Regina', 'CST6' },
|
||||
{ 'America/Resolute', 'CST6CDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Rio Branco', '<-05>5' },
|
||||
{ 'America/Santarem', '<-03>3' },
|
||||
{ 'America/Santiago', '<-04>4<-03>,M9.1.6/24,M4.1.6/24' },
|
||||
{ 'America/Santo Domingo', 'AST4' },
|
||||
{ 'America/Sao Paulo', '<-03>3' },
|
||||
{ 'America/Scoresbysund', '<-01>1<+00>,M3.5.0/0,M10.5.0/1' },
|
||||
{ 'America/Sitka', 'AKST9AKDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/St Barthelemy', 'AST4' },
|
||||
{ 'America/St Johns', 'NST3:30NDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/St Kitts', 'AST4' },
|
||||
{ 'America/St Lucia', 'AST4' },
|
||||
{ 'America/St Thomas', 'AST4' },
|
||||
{ 'America/St Vincent', 'AST4' },
|
||||
{ 'America/Swift Current', 'CST6' },
|
||||
{ 'America/Tegucigalpa', 'CST6' },
|
||||
{ 'America/Thule', 'AST4ADT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Thunder Bay', 'EST5EDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Tijuana', 'PST8PDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Toronto', 'EST5EDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Tortola', 'AST4' },
|
||||
{ 'America/Vancouver', 'PST8PDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Whitehorse', 'MST7' },
|
||||
{ 'America/Winnipeg', 'CST6CDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Yakutat', 'AKST9AKDT,M3.2.0,M11.1.0' },
|
||||
{ 'America/Yellowknife', 'MST7MDT,M3.2.0,M11.1.0' },
|
||||
{ 'Antarctica/Casey', '<+11>-11' },
|
||||
{ 'Antarctica/Davis', '<+07>-7' },
|
||||
{ 'Antarctica/DumontDUrville', '<+10>-10' },
|
||||
{ 'Antarctica/Macquarie', 'AEST-10AEDT,M10.1.0,M4.1.0/3' },
|
||||
{ 'Antarctica/Mawson', '<+05>-5' },
|
||||
{ 'Antarctica/McMurdo', 'NZST-12NZDT,M9.5.0,M4.1.0/3' },
|
||||
{ 'Antarctica/Palmer', '<-03>3' },
|
||||
{ 'Antarctica/Rothera', '<-03>3' },
|
||||
{ 'Antarctica/Syowa', '<+03>-3' },
|
||||
{ 'Antarctica/Troll', '<+00>0<+02>-2,M3.5.0/1,M10.5.0/3' },
|
||||
{ 'Antarctica/Vostok', '<+06>-6' },
|
||||
{ 'Arctic/Longyearbyen', 'CET-1CEST,M3.5.0,M10.5.0/3' },
|
||||
{ 'Asia/Aden', '<+03>-3' },
|
||||
{ 'Asia/Almaty', '<+06>-6' },
|
||||
{ 'Asia/Amman', '<+03>-3' },
|
||||
{ 'Asia/Anadyr', '<+12>-12' },
|
||||
{ 'Asia/Aqtau', '<+05>-5' },
|
||||
{ 'Asia/Aqtobe', '<+05>-5' },
|
||||
{ 'Asia/Ashgabat', '<+05>-5' },
|
||||
{ 'Asia/Atyrau', '<+05>-5' },
|
||||
{ 'Asia/Baghdad', '<+03>-3' },
|
||||
{ 'Asia/Bahrain', '<+03>-3' },
|
||||
{ 'Asia/Baku', '<+04>-4' },
|
||||
{ 'Asia/Bangkok', '<+07>-7' },
|
||||
{ 'Asia/Barnaul', '<+07>-7' },
|
||||
{ 'Asia/Beirut', 'EET-2EEST,M3.5.0/0,M10.5.0/0' },
|
||||
{ 'Asia/Bishkek', '<+06>-6' },
|
||||
{ 'Asia/Brunei', '<+08>-8' },
|
||||
{ 'Asia/Chita', '<+09>-9' },
|
||||
{ 'Asia/Choibalsan', '<+08>-8' },
|
||||
{ 'Asia/Colombo', '<+0530>-5:30' },
|
||||
{ 'Asia/Damascus', '<+03>-3' },
|
||||
{ 'Asia/Dhaka', '<+06>-6' },
|
||||
{ 'Asia/Dili', '<+09>-9' },
|
||||
{ 'Asia/Dubai', '<+04>-4' },
|
||||
{ 'Asia/Dushanbe', '<+05>-5' },
|
||||
{ 'Asia/Famagusta', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
|
||||
{ 'Asia/Gaza', 'EET-2EEST,M3.4.4/50,M10.4.4/50' },
|
||||
{ 'Asia/Hebron', 'EET-2EEST,M3.4.4/50,M10.4.4/50' },
|
||||
{ 'Asia/Ho Chi Minh', '<+07>-7' },
|
||||
{ 'Asia/Hong Kong', 'HKT-8' },
|
||||
{ 'Asia/Hovd', '<+07>-7' },
|
||||
{ 'Asia/Irkutsk', '<+08>-8' },
|
||||
{ 'Asia/Jakarta', 'WIB-7' },
|
||||
{ 'Asia/Jayapura', 'WIT-9' },
|
||||
{ 'Asia/Jerusalem', 'IST-2IDT,M3.4.4/26,M10.5.0' },
|
||||
{ 'Asia/Kabul', '<+0430>-4:30' },
|
||||
{ 'Asia/Kamchatka', '<+12>-12' },
|
||||
{ 'Asia/Karachi', 'PKT-5' },
|
||||
{ 'Asia/Kathmandu', '<+0545>-5:45' },
|
||||
{ 'Asia/Khandyga', '<+09>-9' },
|
||||
{ 'Asia/Kolkata', 'IST-5:30' },
|
||||
{ 'Asia/Krasnoyarsk', '<+07>-7' },
|
||||
{ 'Asia/Kuala Lumpur', '<+08>-8' },
|
||||
{ 'Asia/Kuching', '<+08>-8' },
|
||||
{ 'Asia/Kuwait', '<+03>-3' },
|
||||
{ 'Asia/Macau', 'CST-8' },
|
||||
{ 'Asia/Magadan', '<+11>-11' },
|
||||
{ 'Asia/Makassar', 'WITA-8' },
|
||||
{ 'Asia/Manila', 'PST-8' },
|
||||
{ 'Asia/Muscat', '<+04>-4' },
|
||||
{ 'Asia/Nicosia', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
|
||||
{ 'Asia/Novokuznetsk', '<+07>-7' },
|
||||
{ 'Asia/Novosibirsk', '<+07>-7' },
|
||||
{ 'Asia/Omsk', '<+06>-6' },
|
||||
{ 'Asia/Oral', '<+05>-5' },
|
||||
{ 'Asia/Phnom Penh', '<+07>-7' },
|
||||
{ 'Asia/Pontianak', 'WIB-7' },
|
||||
{ 'Asia/Pyongyang', 'KST-9' },
|
||||
{ 'Asia/Qatar', '<+03>-3' },
|
||||
{ 'Asia/Qostanay', '<+06>-6' },
|
||||
{ 'Asia/Qyzylorda', '<+05>-5' },
|
||||
{ 'Asia/Riyadh', '<+03>-3' },
|
||||
{ 'Asia/Sakhalin', '<+11>-11' },
|
||||
{ 'Asia/Samarkand', '<+05>-5' },
|
||||
{ 'Asia/Seoul', 'KST-9' },
|
||||
{ 'Asia/Shanghai', 'CST-8' },
|
||||
{ 'Asia/Singapore', '<+08>-8' },
|
||||
{ 'Asia/Srednekolymsk', '<+11>-11' },
|
||||
{ 'Asia/Taipei', 'CST-8' },
|
||||
{ 'Asia/Tashkent', '<+05>-5' },
|
||||
{ 'Asia/Tbilisi', '<+04>-4' },
|
||||
{ 'Asia/Tehran', '<+0330>-3:30' },
|
||||
{ 'Asia/Thimphu', '<+06>-6' },
|
||||
{ 'Asia/Tokyo', 'JST-9' },
|
||||
{ 'Asia/Tomsk', '<+07>-7' },
|
||||
{ 'Asia/Ulaanbaatar', '<+08>-8' },
|
||||
{ 'Asia/Urumqi', '<+06>-6' },
|
||||
{ 'Asia/Ust-Nera', '<+10>-10' },
|
||||
{ 'Asia/Vientiane', '<+07>-7' },
|
||||
{ 'Asia/Vladivostok', '<+10>-10' },
|
||||
{ 'Asia/Yakutsk', '<+09>-9' },
|
||||
{ 'Asia/Yangon', '<+0630>-6:30' },
|
||||
{ 'Asia/Yekaterinburg', '<+05>-5' },
|
||||
{ 'Asia/Yerevan', '<+04>-4' },
|
||||
{ 'Atlantic/Azores', '<-01>1<+00>,M3.5.0/0,M10.5.0/1' },
|
||||
{ 'Atlantic/Bermuda', 'AST4ADT,M3.2.0,M11.1.0' },
|
||||
{ 'Atlantic/Canary', 'WET0WEST,M3.5.0/1,M10.5.0' },
|
||||
{ 'Atlantic/Cape Verde', '<-01>1' },
|
||||
{ 'Atlantic/Faroe', 'WET0WEST,M3.5.0/1,M10.5.0' },
|
||||
{ 'Atlantic/Madeira', 'WET0WEST,M3.5.0/1,M10.5.0' },
|
||||
{ 'Atlantic/Reykjavik', 'GMT0' },
|
||||
{ 'Atlantic/South Georgia', '<-02>2' },
|
||||
{ 'Atlantic/St Helena', 'GMT0' },
|
||||
{ 'Atlantic/Stanley', '<-03>3' },
|
||||
{ 'Australia/Adelaide', 'ACST-9:30ACDT,M10.1.0,M4.1.0/3' },
|
||||
{ 'Australia/Brisbane', 'AEST-10' },
|
||||
{ 'Australia/Broken Hill', 'ACST-9:30ACDT,M10.1.0,M4.1.0/3' },
|
||||
{ 'Australia/Darwin', 'ACST-9:30' },
|
||||
{ 'Australia/Eucla', '<+0845>-8:45' },
|
||||
{ 'Australia/Hobart', 'AEST-10AEDT,M10.1.0,M4.1.0/3' },
|
||||
{ 'Australia/Lindeman', 'AEST-10' },
|
||||
{ 'Australia/Lord Howe', '<+1030>-10:30<+11>-11,M10.1.0,M4.1.0' },
|
||||
{ 'Australia/Melbourne', 'AEST-10AEDT,M10.1.0,M4.1.0/3' },
|
||||
{ 'Australia/Perth', 'AWST-8' },
|
||||
{ 'Australia/Sydney', 'AEST-10AEDT,M10.1.0,M4.1.0/3' },
|
||||
{ 'Etc/GMT', 'GMT0' },
|
||||
{ 'Etc/GMT+1', '<-01>1' },
|
||||
{ 'Etc/GMT+10', '<-10>10' },
|
||||
{ 'Etc/GMT+11', '<-11>11' },
|
||||
{ 'Etc/GMT+12', '<-12>12' },
|
||||
{ 'Etc/GMT+2', '<-02>2' },
|
||||
{ 'Etc/GMT+3', '<-03>3' },
|
||||
{ 'Etc/GMT+4', '<-04>4' },
|
||||
{ 'Etc/GMT+5', '<-05>5' },
|
||||
{ 'Etc/GMT+6', '<-06>6' },
|
||||
{ 'Etc/GMT+7', '<-07>7' },
|
||||
{ 'Etc/GMT+8', '<-08>8' },
|
||||
{ 'Etc/GMT+9', '<-09>9' },
|
||||
{ 'Etc/GMT-1', '<+01>-1' },
|
||||
{ 'Etc/GMT-10', '<+10>-10' },
|
||||
{ 'Etc/GMT-11', '<+11>-11' },
|
||||
{ 'Etc/GMT-12', '<+12>-12' },
|
||||
{ 'Etc/GMT-13', '<+13>-13' },
|
||||
{ 'Etc/GMT-14', '<+14>-14' },
|
||||
{ 'Etc/GMT-2', '<+02>-2' },
|
||||
{ 'Etc/GMT-3', '<+03>-3' },
|
||||
{ 'Etc/GMT-4', '<+04>-4' },
|
||||
{ 'Etc/GMT-5', '<+05>-5' },
|
||||
{ 'Etc/GMT-6', '<+06>-6' },
|
||||
{ 'Etc/GMT-7', '<+07>-7' },
|
||||
{ 'Etc/GMT-8', '<+08>-8' },
|
||||
{ 'Etc/GMT-9', '<+09>-9' },
|
||||
{ 'Europe/Amsterdam', 'CET-1CEST,M3.5.0,M10.5.0/3' },
|
||||
{ 'Europe/Andorra', 'CET-1CEST,M3.5.0,M10.5.0/3' },
|
||||
{ 'Europe/Astrakhan', '<+04>-4' },
|
||||
{ 'Europe/Athens', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
|
||||
{ 'Europe/Belgrade', 'CET-1CEST,M3.5.0,M10.5.0/3' },
|
||||
{ 'Europe/Berlin', 'CET-1CEST,M3.5.0,M10.5.0/3' },
|
||||
{ 'Europe/Bratislava', 'CET-1CEST,M3.5.0,M10.5.0/3' },
|
||||
{ 'Europe/Brussels', 'CET-1CEST,M3.5.0,M10.5.0/3' },
|
||||
{ 'Europe/Bucharest', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
|
||||
{ 'Europe/Budapest', 'CET-1CEST,M3.5.0,M10.5.0/3' },
|
||||
{ 'Europe/Busingen', 'CET-1CEST,M3.5.0,M10.5.0/3' },
|
||||
{ 'Europe/Chisinau', 'EET-2EEST,M3.5.0,M10.5.0/3' },
|
||||
{ 'Europe/Copenhagen', 'CET-1CEST,M3.5.0,M10.5.0/3' },
|
||||
{ 'Europe/Dublin', 'IST-1GMT0,M10.5.0,M3.5.0/1' },
|
||||
{ 'Europe/Gibraltar', 'CET-1CEST,M3.5.0,M10.5.0/3' },
|
||||
{ 'Europe/Guernsey', 'GMT0BST,M3.5.0/1,M10.5.0' },
|
||||
{ 'Europe/Helsinki', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
|
||||
{ 'Europe/Isle of Man', 'GMT0BST,M3.5.0/1,M10.5.0' },
|
||||
{ 'Europe/Istanbul', '<+03>-3' },
|
||||
{ 'Europe/Jersey', 'GMT0BST,M3.5.0/1,M10.5.0' },
|
||||
{ 'Europe/Kaliningrad', 'EET-2' },
|
||||
{ 'Europe/Kirov', '<+03>-3' },
|
||||
{ 'Europe/Kyiv', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
|
||||
{ 'Europe/Lisbon', 'WET0WEST,M3.5.0/1,M10.5.0' },
|
||||
{ 'Europe/Ljubljana', 'CET-1CEST,M3.5.0,M10.5.0/3' },
|
||||
{ 'Europe/London', 'GMT0BST,M3.5.0/1,M10.5.0' },
|
||||
{ 'Europe/Luxembourg', 'CET-1CEST,M3.5.0,M10.5.0/3' },
|
||||
{ 'Europe/Madrid', 'CET-1CEST,M3.5.0,M10.5.0/3' },
|
||||
{ 'Europe/Malta', 'CET-1CEST,M3.5.0,M10.5.0/3' },
|
||||
{ 'Europe/Mariehamn', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
|
||||
{ 'Europe/Minsk', '<+03>-3' },
|
||||
{ 'Europe/Monaco', 'CET-1CEST,M3.5.0,M10.5.0/3' },
|
||||
{ 'Europe/Moscow', 'MSK-3' },
|
||||
{ 'Europe/Oslo', 'CET-1CEST,M3.5.0,M10.5.0/3' },
|
||||
{ 'Europe/Paris', 'CET-1CEST,M3.5.0,M10.5.0/3' },
|
||||
{ 'Europe/Podgorica', 'CET-1CEST,M3.5.0,M10.5.0/3' },
|
||||
{ 'Europe/Prague', 'CET-1CEST,M3.5.0,M10.5.0/3' },
|
||||
{ 'Europe/Riga', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
|
||||
{ 'Europe/Rome', 'CET-1CEST,M3.5.0,M10.5.0/3' },
|
||||
{ 'Europe/Samara', '<+04>-4' },
|
||||
{ 'Europe/San Marino', 'CET-1CEST,M3.5.0,M10.5.0/3' },
|
||||
{ 'Europe/Sarajevo', 'CET-1CEST,M3.5.0,M10.5.0/3' },
|
||||
{ 'Europe/Saratov', '<+04>-4' },
|
||||
{ 'Europe/Simferopol', 'MSK-3' },
|
||||
{ 'Europe/Skopje', 'CET-1CEST,M3.5.0,M10.5.0/3' },
|
||||
{ 'Europe/Sofia', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
|
||||
{ 'Europe/Stockholm', 'CET-1CEST,M3.5.0,M10.5.0/3' },
|
||||
{ 'Europe/Tallinn', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
|
||||
{ 'Europe/Tirane', 'CET-1CEST,M3.5.0,M10.5.0/3' },
|
||||
{ 'Europe/Ulyanovsk', '<+04>-4' },
|
||||
{ 'Europe/Vaduz', 'CET-1CEST,M3.5.0,M10.5.0/3' },
|
||||
{ 'Europe/Vatican', 'CET-1CEST,M3.5.0,M10.5.0/3' },
|
||||
{ 'Europe/Vienna', 'CET-1CEST,M3.5.0,M10.5.0/3' },
|
||||
{ 'Europe/Vilnius', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
|
||||
{ 'Europe/Volgograd', '<+03>-3' },
|
||||
{ 'Europe/Warsaw', 'CET-1CEST,M3.5.0,M10.5.0/3' },
|
||||
{ 'Europe/Zagreb', 'CET-1CEST,M3.5.0,M10.5.0/3' },
|
||||
{ 'Europe/Zurich', 'CET-1CEST,M3.5.0,M10.5.0/3' },
|
||||
{ 'Indian/Antananarivo', 'EAT-3' },
|
||||
{ 'Indian/Chagos', '<+06>-6' },
|
||||
{ 'Indian/Christmas', '<+07>-7' },
|
||||
{ 'Indian/Cocos', '<+0630>-6:30' },
|
||||
{ 'Indian/Comoro', 'EAT-3' },
|
||||
{ 'Indian/Kerguelen', '<+05>-5' },
|
||||
{ 'Indian/Mahe', '<+04>-4' },
|
||||
{ 'Indian/Maldives', '<+05>-5' },
|
||||
{ 'Indian/Mauritius', '<+04>-4' },
|
||||
{ 'Indian/Mayotte', 'EAT-3' },
|
||||
{ 'Indian/Reunion', '<+04>-4' },
|
||||
{ 'Pacific/Apia', '<+13>-13' },
|
||||
{ 'Pacific/Auckland', 'NZST-12NZDT,M9.5.0,M4.1.0/3' },
|
||||
{ 'Pacific/Bougainville', '<+11>-11' },
|
||||
{ 'Pacific/Chatham', '<+1245>-12:45<+1345>,M9.5.0/2:45,M4.1.0/3:45' },
|
||||
{ 'Pacific/Chuuk', '<+10>-10' },
|
||||
{ 'Pacific/Easter', '<-06>6<-05>,M9.1.6/22,M4.1.6/22' },
|
||||
{ 'Pacific/Efate', '<+11>-11' },
|
||||
{ 'Pacific/Fakaofo', '<+13>-13' },
|
||||
{ 'Pacific/Fiji', '<+12>-12<+13>,M11.2.0,M1.2.3/99' },
|
||||
{ 'Pacific/Funafuti', '<+12>-12' },
|
||||
{ 'Pacific/Galapagos', '<-06>6' },
|
||||
{ 'Pacific/Gambier', '<-09>9' },
|
||||
{ 'Pacific/Guadalcanal', '<+11>-11' },
|
||||
{ 'Pacific/Guam', 'ChST-10' },
|
||||
{ 'Pacific/Honolulu', 'HST10' },
|
||||
{ 'Pacific/Kanton', '<+13>-13' },
|
||||
{ 'Pacific/Kiritimati', '<+14>-14' },
|
||||
{ 'Pacific/Kosrae', '<+11>-11' },
|
||||
{ 'Pacific/Kwajalein', '<+12>-12' },
|
||||
{ 'Pacific/Majuro', '<+12>-12' },
|
||||
{ 'Pacific/Marquesas', '<-0930>9:30' },
|
||||
{ 'Pacific/Midway', 'SST11' },
|
||||
{ 'Pacific/Nauru', '<+12>-12' },
|
||||
{ 'Pacific/Niue', '<-11>11' },
|
||||
{ 'Pacific/Norfolk', '<+11>-11<+12>,M10.1.0,M4.1.0/3' },
|
||||
{ 'Pacific/Noumea', '<+11>-11' },
|
||||
{ 'Pacific/Pago Pago', 'SST11' },
|
||||
{ 'Pacific/Palau', '<+09>-9' },
|
||||
{ 'Pacific/Pitcairn', '<-08>8' },
|
||||
{ 'Pacific/Pohnpei', '<+11>-11' },
|
||||
{ 'Pacific/Port Moresby', '<+10>-10' },
|
||||
{ 'Pacific/Rarotonga', '<-10>10' },
|
||||
{ 'Pacific/Saipan', 'ChST-10' },
|
||||
{ 'Pacific/Tahiti', '<-10>10' },
|
||||
{ 'Pacific/Tarawa', '<+12>-12' },
|
||||
{ 'Pacific/Tongatapu', '<+13>-13' },
|
||||
{ 'Pacific/Wake', '<+12>-12' },
|
||||
{ 'Pacific/Wallis', '<+12>-12' },
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
-- Licensed to the public under the Apache License 2.0.
|
||||
|
||||
module "luci.sys.zoneinfo.tzoffset"
|
||||
|
||||
OFFSET = {
|
||||
gmt = 0, -- GMT
|
||||
eat = 10800, -- EAT
|
||||
cet = 3600, -- CET
|
||||
wat = 3600, -- WAT
|
||||
cat = 7200, -- CAT
|
||||
eet = 7200, -- EET
|
||||
sast = 7200, -- SAST
|
||||
hst = -36000, -- HST
|
||||
hdt = -32400, -- HDT
|
||||
akst = -32400, -- AKST
|
||||
akdt = -28800, -- AKDT
|
||||
ast = -14400, -- AST
|
||||
est = -18000, -- EST
|
||||
cst = -21600, -- CST
|
||||
cdt = -18000, -- CDT
|
||||
mst = -25200, -- MST
|
||||
mdt = -21600, -- MDT
|
||||
pst = -28800, -- PST
|
||||
pdt = -25200, -- PDT
|
||||
nst = -12600, -- NST
|
||||
ndt = -9000, -- NDT
|
||||
aest = 36000, -- AEST
|
||||
aedt = 39600, -- AEDT
|
||||
nzst = 43200, -- NZST
|
||||
nzdt = 46800, -- NZDT
|
||||
hkt = 28800, -- HKT
|
||||
wib = 25200, -- WIB
|
||||
wit = 32400, -- WIT
|
||||
ist = 7200, -- IST
|
||||
idt = 10800, -- IDT
|
||||
pkt = 18000, -- PKT
|
||||
wita = 28800, -- WITA
|
||||
kst = 32400, -- KST
|
||||
jst = 32400, -- JST
|
||||
wet = 0, -- WET
|
||||
acst = 34200, -- ACST
|
||||
acdt = 37800, -- ACDT
|
||||
awst = 28800, -- AWST
|
||||
msk = 10800, -- MSK
|
||||
sst = -39600, -- SST
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
-- Copyright 2008 Steven Barth <steven@midlink.org>
|
||||
-- Licensed to the public under the Apache License 2.0.
|
||||
|
||||
local util = require "luci.util"
|
||||
local config = require "luci.config"
|
||||
local tparser = require "luci.template.parser"
|
||||
|
||||
local tostring, pairs, loadstring = tostring, pairs, loadstring
|
||||
local setmetatable, loadfile = setmetatable, loadfile
|
||||
local getfenv, setfenv, rawget = getfenv, setfenv, rawget
|
||||
local assert, type, error = assert, type, error
|
||||
local table, string, unpack = table, string, unpack
|
||||
|
||||
|
||||
---
|
||||
--- bootstrap
|
||||
---
|
||||
local _G = _G
|
||||
local L = _G.L
|
||||
|
||||
local http = _G.L.http
|
||||
|
||||
local disp = require "luci.dispatcher"
|
||||
local i18n = require "luci.i18n"
|
||||
local xml = require "luci.xml"
|
||||
local fs = require "nixio.fs"
|
||||
|
||||
|
||||
--- LuCI template library.
|
||||
module "luci.template"
|
||||
|
||||
config.template = config.template or {}
|
||||
viewdir = config.template.viewdir or util.libpath() .. "/view"
|
||||
|
||||
|
||||
-- Define the namespace for template modules
|
||||
context = {} --util.threadlocal()
|
||||
|
||||
--- Render a certain template.
|
||||
-- @param name Template name
|
||||
-- @param scope Scope to assign to template (optional)
|
||||
function render(name, scope)
|
||||
return Template(name):render(scope or getfenv(2))
|
||||
end
|
||||
|
||||
--- Render a template from a string.
|
||||
-- @param template Template string
|
||||
-- @param scope Scope to assign to template (optional)
|
||||
function render_string(template, scope)
|
||||
return Template(nil, template):render(scope or getfenv(2))
|
||||
end
|
||||
|
||||
|
||||
-- Template class
|
||||
Template = util.class()
|
||||
|
||||
-- Shared template cache to store templates in to avoid unnecessary reloading
|
||||
Template.cache = setmetatable({}, {__mode = "v"})
|
||||
|
||||
|
||||
|
||||
local function _ifattr(cond, key, val, noescape)
|
||||
if cond then
|
||||
local env = getfenv(3)
|
||||
local scope = (type(env.self) == "table") and env.self
|
||||
if type(val) == "table" then
|
||||
if not next(val) then
|
||||
return ''
|
||||
else
|
||||
val = util.serialize_json(val)
|
||||
end
|
||||
end
|
||||
|
||||
val = tostring(val or
|
||||
(type(env[key]) ~= "function" and env[key]) or
|
||||
(scope and type(scope[key]) ~= "function" and scope[key]) or "")
|
||||
|
||||
if noescape ~= true then
|
||||
val = xml.pcdata(val)
|
||||
end
|
||||
|
||||
return string.format(' %s="%s"', tostring(key), val)
|
||||
else
|
||||
return ''
|
||||
end
|
||||
end
|
||||
|
||||
context.viewns = setmetatable({
|
||||
include = function(name)
|
||||
if fs.access(viewdir .. "/" .. name .. ".htm") then
|
||||
Template(name):render(getfenv(2))
|
||||
else
|
||||
L.include(name, getfenv(2))
|
||||
end
|
||||
end;
|
||||
translate = i18n.translate;
|
||||
translatef = i18n.translatef;
|
||||
export = function(k, v) if context.viewns[k] == nil then context.viewns[k] = v end end;
|
||||
striptags = xml.striptags;
|
||||
pcdata = xml.pcdata;
|
||||
ifattr = function(...) return _ifattr(...) end;
|
||||
attr = function(...) return _ifattr(true, ...) end;
|
||||
url = disp.build_url;
|
||||
}, {__index=function(tbl, key)
|
||||
if key == "controller" then
|
||||
return disp.build_url()
|
||||
elseif key == "REQUEST_URI" then
|
||||
return disp.build_url(unpack(disp.context.requestpath))
|
||||
elseif key == "FULL_REQUEST_URI" then
|
||||
local url = { http:getenv("SCRIPT_NAME") or "", http:getenv("PATH_INFO") }
|
||||
local query = http:getenv("QUERY_STRING")
|
||||
if query and #query > 0 then
|
||||
url[#url+1] = "?"
|
||||
url[#url+1] = query
|
||||
end
|
||||
return table.concat(url, "")
|
||||
elseif key == "token" then
|
||||
return disp.context.authtoken
|
||||
elseif key == "theme" then
|
||||
return L.media and fs.basename(L.media) or tostring(L)
|
||||
elseif key == "resource" then
|
||||
return L.config.main.resourcebase
|
||||
else
|
||||
return rawget(tbl, key) or _G[key] or L[key]
|
||||
end
|
||||
end})
|
||||
|
||||
|
||||
-- Constructor - Reads and compiles the template on-demand
|
||||
function Template.__init__(self, name, template)
|
||||
if name then
|
||||
self.template = self.cache[name]
|
||||
self.name = name
|
||||
else
|
||||
self.name = "[string]"
|
||||
end
|
||||
|
||||
-- Create a new namespace for this template
|
||||
self.viewns = context.viewns
|
||||
|
||||
-- If we have a cached template, skip compiling and loading
|
||||
if not self.template then
|
||||
|
||||
-- Compile template
|
||||
local err
|
||||
local sourcefile
|
||||
|
||||
if name then
|
||||
sourcefile = viewdir .. "/" .. name .. ".htm"
|
||||
self.template, _, err = tparser.parse(sourcefile)
|
||||
else
|
||||
sourcefile = "[string]"
|
||||
self.template, _, err = tparser.parse_string(template)
|
||||
end
|
||||
|
||||
-- If we have no valid template throw error, otherwise cache the template
|
||||
if not self.template then
|
||||
error("Failed to load template '" .. self.name .. "'.\n" ..
|
||||
"Error while parsing template '" .. sourcefile .. "':\n" ..
|
||||
(err or "Unknown syntax error"))
|
||||
elseif name then
|
||||
self.cache[name] = self.template
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Renders a template
|
||||
function Template.render(self, scope)
|
||||
scope = scope or getfenv(2)
|
||||
|
||||
-- Put our predefined objects in the scope of the template
|
||||
setfenv(self.template, setmetatable({}, {__index =
|
||||
function(tbl, key)
|
||||
return rawget(tbl, key) or self.viewns[key] or scope[key]
|
||||
end}))
|
||||
|
||||
-- Now finally render the thing
|
||||
local stat, err = util.copcall(self.template)
|
||||
if not stat then
|
||||
error("Failed to execute template '" .. self.name .. "'.\n" ..
|
||||
"A runtime error occurred: " .. tostring(err or "(nil)"))
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,54 @@
|
||||
-- Copyright 2022 Jo-Philipp Wich <jo@mein.io>
|
||||
-- Licensed to the public under the Apache License 2.0.
|
||||
|
||||
local coroutine, assert, error, type, require = coroutine, assert, error, type, require
|
||||
local tmpl = require "luci.template"
|
||||
local util = require "luci.util"
|
||||
local http = require "luci.http"
|
||||
local sys = require "luci.sys"
|
||||
local ltn12 = require "luci.ltn12"
|
||||
|
||||
|
||||
--- LuCI ucode bridge library.
|
||||
module "luci.ucodebridge"
|
||||
|
||||
local function run(fn, ...)
|
||||
local co = coroutine.create(fn)
|
||||
local ok, ret
|
||||
|
||||
while coroutine.status(co) ~= "dead" do
|
||||
ok, ret = coroutine.resume(co, ...)
|
||||
|
||||
if not ok then
|
||||
error(ret)
|
||||
end
|
||||
end
|
||||
|
||||
return ret
|
||||
end
|
||||
|
||||
function compile(path)
|
||||
run(function(path)
|
||||
return tmpl.Template(path)
|
||||
end, path)
|
||||
end
|
||||
|
||||
function render(path, scope)
|
||||
run(tmpl.render, path, scope)
|
||||
end
|
||||
|
||||
function call(modname, method, ...)
|
||||
return run(function(module, method, ...)
|
||||
local mod = require(modname)
|
||||
local func = mod[method]
|
||||
|
||||
assert(func ~= nil,
|
||||
'Cannot resolve function "' .. method .. '". Is it misspelled or local?')
|
||||
|
||||
assert(type(func) == "function",
|
||||
'The symbol "' .. method .. '" does not refer to a function but data ' ..
|
||||
'of type "' .. type(func) .. '".')
|
||||
|
||||
return func(...)
|
||||
end, modname, method, ...)
|
||||
end
|
||||
@@ -0,0 +1,20 @@
|
||||
local pcall, dofile, _G = pcall, dofile, _G
|
||||
|
||||
module "luci.version"
|
||||
|
||||
if pcall(dofile, "/etc/openwrt_release") and _G.DISTRIB_DESCRIPTION then
|
||||
distname = ""
|
||||
distversion = _G.DISTRIB_DESCRIPTION
|
||||
if _G.DISTRIB_REVISION then
|
||||
distrevision = _G.DISTRIB_REVISION
|
||||
if not distversion:find(distrevision,1,true) then
|
||||
distversion = distversion .. " " .. distrevision
|
||||
end
|
||||
end
|
||||
else
|
||||
distname = "OpenWrt"
|
||||
distversion = "Development Snapshot"
|
||||
end
|
||||
|
||||
luciname = "LuCI openwrt-24.10 branch"
|
||||
luciversion = "25.034.70690~7b0663a"
|
||||
@@ -0,0 +1,18 @@
|
||||
<%-
|
||||
local util = require "luci.util"
|
||||
local fs = require "nixio.fs"
|
||||
|
||||
local incdir = util.libpath() .. "/view/admin_status/index/"
|
||||
if fs.access(incdir) then
|
||||
local _, inc
|
||||
local includes = {}
|
||||
for inc in fs.dir(incdir) do
|
||||
if inc:match("%.htm$") then
|
||||
includes[#includes + 1] = inc:gsub("%.htm$", "")
|
||||
end
|
||||
end
|
||||
for _, inc in luci.util.vspairs(includes) do
|
||||
include("admin_status/index/" .. inc)
|
||||
end
|
||||
end
|
||||
-%>
|
||||
@@ -0,0 +1,11 @@
|
||||
<%#
|
||||
Copyright 2010 Jo-Philipp Wich <jow@openwrt.org>
|
||||
Copyright 2018 Daniel F. Dickinson <cshored@thecshore.com>
|
||||
Licensed to the public under the Apache License 2.0.
|
||||
-%>
|
||||
|
||||
<%+header%>
|
||||
|
||||
<p>Component not present.</p>
|
||||
|
||||
<%+footer%>
|
||||
@@ -0,0 +1,7 @@
|
||||
<%#
|
||||
Copyright 2008 Steven Barth <steven@midlink.org>
|
||||
Copyright 2008 Jo-Philipp Wich <jow@openwrt.org>
|
||||
Licensed to the public under the Apache License 2.0.
|
||||
-%>
|
||||
|
||||
<% include("themes/" .. theme .. "/indexer") %>
|
||||
@@ -0,0 +1,26 @@
|
||||
-- Copyright 2008 Steven Barth <steven@midlink.org>
|
||||
-- Licensed to the public under the Apache License 2.0.
|
||||
|
||||
local tparser = require "luci.template.parser"
|
||||
local string = require "string"
|
||||
|
||||
local tostring = tostring
|
||||
|
||||
module "luci.xml"
|
||||
|
||||
--
|
||||
-- String and data manipulation routines
|
||||
--
|
||||
|
||||
function pcdata(value)
|
||||
return value and tparser.pcdata(tostring(value))
|
||||
end
|
||||
|
||||
function striptags(value)
|
||||
return value and tparser.striptags(tostring(value))
|
||||
end
|
||||
|
||||
|
||||
-- also register functions above in the central string class for convenience
|
||||
string.pcdata = pcdata
|
||||
string.striptags = striptags
|
||||
12
ipk-source/luci-theme-argon/CONTROL/control
Normal file
@@ -0,0 +1,12 @@
|
||||
Package: luci-theme-argon
|
||||
Version: 2.3.2-r20250207
|
||||
Depends: libc, curl, jsonfilter, luci-lua-runtime
|
||||
Source: feeds/base/downloads/luci-theme-argon
|
||||
SourceName: luci-theme-argon
|
||||
Section: luci
|
||||
SourceDateEpoch: 1739087731
|
||||
URL: https://github.com/openwrt/luci
|
||||
Maintainer: OpenWrt LuCI community
|
||||
Architecture: all
|
||||
Installed-Size: 768000
|
||||
Description: Argon Theme
|
||||
5
ipk-source/luci-theme-argon/CONTROL/postinst
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
[ "${IPKG_NO_SCRIPT}" = "1" ] && exit 0
|
||||
[ -s ${IPKG_INSTROOT}/lib/functions.sh ] || exit 0
|
||||
. ${IPKG_INSTROOT}/lib/functions.sh
|
||||
default_postinst $0 $@
|
||||
5
ipk-source/luci-theme-argon/CONTROL/postinst-pkg
Executable file
@@ -0,0 +1,5 @@
|
||||
[ -n "${IPKG_INSTROOT}" ] || { rm -f /tmp/luci-indexcache.*
|
||||
rm -rf /tmp/luci-modulecache/
|
||||
killall -HUP rpcd 2>/dev/null
|
||||
exit 0
|
||||
}
|
||||
4
ipk-source/luci-theme-argon/CONTROL/prerm
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
[ -s ${IPKG_INSTROOT}/lib/functions.sh ] || exit 0
|
||||
. ${IPKG_INSTROOT}/lib/functions.sh
|
||||
default_prerm $0 $@
|
||||
74
ipk-source/luci-theme-argon/build-ipk
Executable file
@@ -0,0 +1,74 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Script for building OpenWRT .ipk packages using tar by iamromulan
|
||||
# Works with SDXPPINN OpenWRT - iamromulan
|
||||
# This script accepts an optional path to the directory containing the `CONTROL` and `root` directories.
|
||||
# Usage: ./build-ipk.sh [path]
|
||||
# If no path is provided, the script will look in the current directory for `CONTROL` and `root` directories.
|
||||
# This will spit out an ipk in the current directory
|
||||
|
||||
# Check if the script is run as root. If not, rerun with sudo.
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo "Script is not running as root. Re-executing with sudo..."
|
||||
exec sudo "$0" "$@"
|
||||
fi
|
||||
|
||||
# Set the default build path to the current directory
|
||||
build_path="."
|
||||
|
||||
# Check if a path is provided as the first argument
|
||||
if [ "$1" ]; then
|
||||
build_path="$1"
|
||||
fi
|
||||
|
||||
# Check if the required directories are present in the specified path
|
||||
if [ ! -d "${build_path}/CONTROL" ] || [ ! -d "${build_path}/root" ]; then
|
||||
echo "Error: CONTROL and root directories must be present in the specified path (${build_path})."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Extract values from the CONTROL/control file in the specified path
|
||||
pkgname=$(grep -i '^Package:' "${build_path}/CONTROL/control" | awk '{print $2}')
|
||||
version=$(grep -i '^Version:' "${build_path}/CONTROL/control" | awk '{print $2}')
|
||||
architecture=$(grep -i '^Architecture:' "${build_path}/CONTROL/control" | awk '{print $2}')
|
||||
|
||||
# Check if values are extracted correctly
|
||||
if [ -z "$pkgname" ] || [ -z "$version" ] || [ -z "$architecture" ]; then
|
||||
echo "Error: Failed to extract Package, Version, or Architecture from ${build_path}/CONTROL/control."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Set the final IPK name based on the extracted values
|
||||
ipkname="${pkgname}_${version}_${architecture}.ipk"
|
||||
|
||||
# Ensure all CONTROL scripts are executable
|
||||
echo "Setting permissions for CONTROL scripts..."
|
||||
chmod +x "${build_path}/CONTROL"/*
|
||||
|
||||
# Set ownership for CONTROL and root files
|
||||
echo "Setting ownership for all package files..."
|
||||
chown -R root:root "${build_path}/CONTROL"/*
|
||||
chown -R root:root "${build_path}/root"/*
|
||||
|
||||
# Create control.tar.gz from the CONTROL directory
|
||||
echo "Creating control.tar.gz..."
|
||||
tar -czvf control.tar.gz -C "${build_path}/CONTROL" .
|
||||
|
||||
# Create data.tar.gz from the root directory
|
||||
echo "Creating data.tar.gz..."
|
||||
tar -czvf data.tar.gz -C "${build_path}/root" .
|
||||
|
||||
# Create debian-binary file (must contain exactly "2.0" without a newline)
|
||||
echo -n "2.0" > debian-binary
|
||||
chown -R root:root debian-binary
|
||||
|
||||
# Combine the components into the final .ipk file using tar
|
||||
echo "Packaging ${ipkname}..."
|
||||
tar -czvf "$ipkname" debian-binary control.tar.gz data.tar.gz
|
||||
|
||||
# Clean up intermediate files
|
||||
echo "Cleaning up temporary files..."
|
||||
rm -f control.tar.gz data.tar.gz debian-binary
|
||||
|
||||
echo "IPK package ${ipkname} created successfully using tar."
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ "$PKG_UPGRADE" != 1 ]; then
|
||||
uci get luci.themes.Argon >/dev/null 2>&1 || \
|
||||
uci batch <<-EOF
|
||||
set luci.themes.Argon=/luci-static/argon
|
||||
set luci.main.mediaurlbase=/luci-static/argon
|
||||
commit luci
|
||||
EOF
|
||||
fi
|
||||
|
||||
exit 0
|
||||
@@ -0,0 +1,46 @@
|
||||
<%#
|
||||
Argon is a clean HTML5 theme for LuCI. It is based on luci-theme-material Argon Template
|
||||
|
||||
luci-theme-argon
|
||||
Copyright 2020 Jerrykuku <jerrykuku@qq.com>
|
||||
|
||||
Have a bug? Please create an issue here on GitHub!
|
||||
https://github.com/jerrykuku/luci-theme-argon/issues
|
||||
|
||||
luci-theme-material:
|
||||
Copyright 2015 Lutty Yang <lutty@wcan.in>
|
||||
|
||||
Agron Theme
|
||||
https://demos.creative-tim.com/argon-dashboard/index.html
|
||||
|
||||
Licensed to the public under the Apache License 2.0
|
||||
-%>
|
||||
|
||||
<% local ver = require "luci.version" %>
|
||||
</div>
|
||||
<footer class="mobile-hide">
|
||||
<div>
|
||||
<a class="luci-link" href="https://github.com/openwrt/luci" target="_blank">Powered by <%= ver.luciname %> (<%= ver.luciversion %>)</a> /
|
||||
<a href="https://github.com/jerrykuku/luci-theme-argon" target="_blank">ArgonTheme v2.3.2</a> /
|
||||
<%= ver.distversion %>
|
||||
<ul class="breadcrumb pull-right" id="modemenu" style="display:none"></ul>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
// thanks for Jo-Philipp Wich <jow@openwrt.org>
|
||||
var luciLocation = <%= luci.http.write_json(luci.dispatcher.context.path) %>;
|
||||
var winHeight = $(window).height();
|
||||
$(window).resize(function () {
|
||||
var winWidth = $(window).width()
|
||||
if(winWidth < 600){
|
||||
var newHeight = $(this).height();
|
||||
var keyboradHeight = newHeight - winHeight;
|
||||
$(".ftc").css("bottom", keyboradHeight + 30);
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<script type="text/javascript">L.require('menu-argon')</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,44 @@
|
||||
<%#
|
||||
Argon is a clean HTML5 theme for LuCI. It is based on luci-theme-material Argon Template
|
||||
|
||||
luci-theme-argon
|
||||
Copyright 2020 Jerrykuku <jerrykuku@qq.com>
|
||||
|
||||
Have a bug? Please create an issue here on GitHub!
|
||||
https://github.com/jerrykuku/luci-theme-argon/issues
|
||||
|
||||
luci-theme-material:
|
||||
Copyright 2015 Lutty Yang <lutty@wcan.in>
|
||||
|
||||
Agron Theme
|
||||
https://demos.creative-tim.com/argon-dashboard/index.html
|
||||
|
||||
Licensed to the public under the Apache License 2.0
|
||||
-%>
|
||||
|
||||
<% local ver = require "luci.version" %>
|
||||
</div>
|
||||
<footer>
|
||||
<div>
|
||||
<a class="luci-link" href="https://github.com/openwrt/luci" target="_blank">Powered by <%= ver.luciname %> (<%= ver.luciversion %>)</a> /
|
||||
<a href="https://github.com/jerrykuku/luci-theme-argon" target="_blank">ArgonTheme v2.3.2</a> /
|
||||
<%= ver.distversion %>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
// thanks for Jo-Philipp Wich <jow@openwrt.org>
|
||||
var luciLocation = <%= luci.http.write_json(luci.dispatcher.context.path) %>;
|
||||
var winHeight = $(window).height();
|
||||
$(window).resize(function () {
|
||||
var winWidth = $(window).width()
|
||||
if(winWidth < 600){
|
||||
var newHeight = $(this).height();
|
||||
var keyboradHeight = newHeight - winHeight;
|
||||
$(".ftc").css("bottom", keyboradHeight + 30);
|
||||
}
|
||||
})
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,180 @@
|
||||
<%#
|
||||
Argon is a clean HTML5 theme for LuCI. It is based on luci-theme-material Argon Template
|
||||
|
||||
luci-theme-argon
|
||||
Copyright 2020 Jerrykuku <jerrykuku@qq.com>
|
||||
|
||||
Have a bug? Please create an issue here on GitHub!
|
||||
https://github.com/jerrykuku/luci-theme-argon/issues
|
||||
|
||||
luci-theme-material:
|
||||
Copyright 2015 Lutty Yang <lutty@wcan.in>
|
||||
|
||||
Argon Theme
|
||||
https://demos.creative-tim.com/argon-dashboard/index.html
|
||||
|
||||
Licensed to the public under the Apache License 2.0
|
||||
-%>
|
||||
|
||||
<%
|
||||
local sys = require "luci.sys"
|
||||
local util = require "luci.util"
|
||||
local http = require "luci.http"
|
||||
local disp = require "luci.dispatcher"
|
||||
local ver = require "luci.version"
|
||||
|
||||
local boardinfo = util.ubus("system", "board")
|
||||
|
||||
local node = disp.context.dispatched
|
||||
|
||||
local fs = require "nixio.fs"
|
||||
local nutil = require "nixio.util"
|
||||
local uci = require 'luci.model.uci'.cursor()
|
||||
|
||||
-- send as HTML5
|
||||
http.prepare_content("text/html")
|
||||
|
||||
math.randomseed(os.time())
|
||||
|
||||
-- Custom settings
|
||||
local mode = 'normal'
|
||||
local dark_css = fs.readfile('/www/luci-static/argon/css/dark.css')
|
||||
local bar_color = '#5e72e4'
|
||||
local primary, dark_primary, blur_radius, blur_radius_dark, blur_opacity
|
||||
if fs.access('/etc/config/argon') then
|
||||
primary = uci:get_first('argon', 'global', 'primary')
|
||||
dark_primary = uci:get_first('argon', 'global', 'dark_primary')
|
||||
blur_radius = uci:get_first('argon', 'global', 'blur')
|
||||
blur_radius_dark = uci:get_first('argon', 'global', 'blur_dark')
|
||||
blur_opacity = uci:get_first('argon', 'global', 'transparency')
|
||||
blur_opacity_dark = uci:get_first('argon', 'global', 'transparency_dark')
|
||||
mode = uci:get_first('argon', 'global', 'mode')
|
||||
bar_color = mode == 'dark' and dark_primary or primary
|
||||
end
|
||||
|
||||
-- Brand name
|
||||
local brand_name = boardinfo.hostname or "?"
|
||||
-%>
|
||||
<!DOCTYPE html>
|
||||
<html lang="<%=luci.i18n.context.lang%>">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>
|
||||
<%=striptags( (boardinfo.hostname or "?") .. ( (node and node.title) and ' - ' .. translate(node.title) or '')) %>
|
||||
- LuCI</title>
|
||||
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport" />
|
||||
<meta name="format-detection" content="telephone=no, email=no" />
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
<meta name="x5-fullscreen" content="true">
|
||||
<meta name="full-screen" content="yes">
|
||||
<meta name="x5-page-mode" content="app">
|
||||
<meta name="browsermode" content="application">
|
||||
<meta name="msapplication-tap-highlight" content="no">
|
||||
<meta name="msapplication-TileColor" content="<%=bar_color%>">
|
||||
<meta name="application-name" content="<%=striptags( (boardinfo.hostname or "?") ) %> - LuCI">
|
||||
<meta name="apple-mobile-web-app-title" content="<%=striptags( (boardinfo.hostname or "?") ) %> - LuCI">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="<%=media%>/icon/apple-icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="<%=media%>/icon/apple-icon-72x72.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="<%=media%>/icon/apple-icon-144x144.png">
|
||||
<link rel="icon" type="image/png" sizes="192x192" href="<%=media%>/icon/android-icon-192x192.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="<%=media%>/icon/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="96x96" href="<%=media%>/icon/favicon-96x96.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="<%=media%>/icon/favicon-16x16.png">
|
||||
<link rel="manifest" href="<%=media%>/icon/manifest.json" crossorigin="use-credentials">
|
||||
<meta name="msapplication-TileColor" content="<%=bar_color%>">
|
||||
<meta name="msapplication-TileImage" content="<%=media%>/icon/ms-icon-144x144.png">
|
||||
<meta name="theme-color" content="<%=bar_color%>">
|
||||
<link rel="stylesheet" href="<%=media%>/css/cascade.css?v=2.3.2">
|
||||
<style title="text/css">
|
||||
<% if mode == 'normal' then %>
|
||||
@media (prefers-color-scheme: dark) {
|
||||
<%=dark_css%>
|
||||
}
|
||||
<% elseif mode == 'dark' then %>
|
||||
<%=dark_css%>
|
||||
<% end -%>
|
||||
<% if fs.access('/etc/config/argon') then %>
|
||||
:root {
|
||||
--primary: <%=primary%>;
|
||||
--dark-primary: <%=dark_primary%>;
|
||||
--blur-radius:<%=blur_radius%>px;
|
||||
--blur-opacity:<%=blur_opacity%>;
|
||||
--blur-radius-dark:<%=blur_radius_dark%>px;
|
||||
--blur-opacity-dark:<%=blur_opacity_dark%>;
|
||||
}
|
||||
<% end -%>
|
||||
</style>
|
||||
<link rel="shortcut icon" href="<%=media%>/favicon.ico">
|
||||
<% if node and node.css then %>
|
||||
<link rel="stylesheet" href="<%=resource%>/<%=node.css%>">
|
||||
<% end -%>
|
||||
<% if css then %>
|
||||
<style title="text/css">
|
||||
<%=css %>
|
||||
</style>
|
||||
<% end -%>
|
||||
<script src="<%=media%>/js/polyfill.min.js?v=2.3.2"></script>
|
||||
<script src="<%=url('admin/translations', luci.i18n.context.lang)%>?v=<%=ver.luciversion%>"></script>
|
||||
<script src="<%=resource%>/cbi.js?v=<%=ver.luciversion%>"></script>
|
||||
<script src="<%=resource%>/luci.js?v=<%=ver.luciversion%>"></script>
|
||||
<script src="<%=media%>/js/jquery.min.js?v=3.5.1"></script>
|
||||
</head>
|
||||
|
||||
<body
|
||||
class="lang_<%=luci.i18n.context.lang%> <% if node then %><%= striptags( node.title ) %><% end %> <% if luci.dispatcher.context.authsession then %>logged-in<% end %>"
|
||||
data-page="<%= table.concat(disp.context.requestpath, "-") %>">
|
||||
|
||||
<div class="main">
|
||||
<div class="main-left" id="mainmenu" style="display:none">
|
||||
<div class="sidenav-header d-flex align-items-center">
|
||||
<a class="brand" href="#"><%=brand_name%></a>
|
||||
<div class="ml-auto">
|
||||
<!-- Sidenav toggler -->
|
||||
<div class="sidenav-toggler d-none d-xl-block active" data-action="sidenav-unpin"
|
||||
data-target="#sidenav-main">
|
||||
<div class="sidenav-toggler-inner">
|
||||
<i class="sidenav-toggler-line"></i>
|
||||
<i class="sidenav-toggler-line"></i>
|
||||
<i class="sidenav-toggler-line"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="main-right">
|
||||
<header class="bg-primary">
|
||||
<div class="fill">
|
||||
<div class="container">
|
||||
<div class="flex1">
|
||||
<a class="showSide"></a>
|
||||
<a class="brand" href="#"><%=brand_name%></a>
|
||||
</div>
|
||||
<div class="status" id="indicators"></div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="darkMask"></div>
|
||||
<div id="maincontent">
|
||||
<div class="container">
|
||||
<%- if luci.sys.process.info("uid") == 0 and luci.sys.user.getuser("root") and not luci.sys.user.getpasswd("root") then -%>
|
||||
<div class="alert-message error">
|
||||
<h4><%:No password set!%></h4>
|
||||
<p><%:There is no password set on this router. Please configure a root password to protect the web interface.%>
|
||||
</p>
|
||||
<% if disp.lookup("admin/system/admin") then %>
|
||||
<div class="right"><a class="btn"
|
||||
href="<%=url("admin/system/admin")%>"><%:Go to password configuration...%></a></div>
|
||||
<% end %>
|
||||
</div>
|
||||
<%- end -%>
|
||||
|
||||
<noscript>
|
||||
<div class="alert-message error">
|
||||
<h4><%:JavaScript required!%></h4>
|
||||
<p><%:You must enable JavaScript in your browser or LuCI will not work properly.%></p>
|
||||
</div>
|
||||
</noscript>
|
||||
|
||||
<div id="tabmenu" style="display:none"></div>
|
||||
@@ -0,0 +1,119 @@
|
||||
<%#
|
||||
Argon is a clean HTML5 theme for LuCI. It is based on luci-theme-material Argon Template
|
||||
|
||||
luci-theme-argon
|
||||
Copyright 2020 Jerrykuku <jerrykuku@qq.com>
|
||||
|
||||
Have a bug? Please create an issue here on GitHub!
|
||||
https://github.com/jerrykuku/luci-theme-argon/issues
|
||||
|
||||
luci-theme-material:
|
||||
Copyright 2015 Lutty Yang <lutty@wcan.in>
|
||||
|
||||
Argon Theme
|
||||
https://demos.creative-tim.com/argon-dashboard/index.html
|
||||
|
||||
Licensed to the public under the Apache License 2.0
|
||||
-%>
|
||||
|
||||
<%
|
||||
local sys = require "luci.sys"
|
||||
local util = require "luci.util"
|
||||
local http = require "luci.http"
|
||||
local disp = require "luci.dispatcher"
|
||||
local ver = require "luci.version"
|
||||
|
||||
local boardinfo = util.ubus("system", "board")
|
||||
|
||||
local node = disp.context.dispatched
|
||||
|
||||
local fs = require "nixio.fs"
|
||||
local nutil = require "nixio.util"
|
||||
local uci = require 'luci.model.uci'.cursor()
|
||||
|
||||
-- send as HTML5
|
||||
http.prepare_content("text/html")
|
||||
|
||||
math.randomseed(tonumber(tostring(os.time()):reverse():sub(1, 9)))
|
||||
|
||||
-- Custom settings
|
||||
local mode = 'normal'
|
||||
local dark_css = fs.readfile('/www/luci-static/argon/css/dark.css')
|
||||
local bar_color = '#5e72e4'
|
||||
local primary, dark_primary, blur_radius, blur_radius_dark, blur_opacity
|
||||
if fs.access('/etc/config/argon') then
|
||||
primary = uci:get_first('argon', 'global', 'primary')
|
||||
dark_primary = uci:get_first('argon', 'global', 'dark_primary')
|
||||
blur_radius = uci:get_first('argon', 'global', 'blur')
|
||||
blur_radius_dark = uci:get_first('argon', 'global', 'blur_dark')
|
||||
blur_opacity = uci:get_first('argon', 'global', 'transparency')
|
||||
blur_opacity_dark = uci:get_first('argon', 'global', 'transparency_dark')
|
||||
mode = uci:get_first('argon', 'global', 'mode')
|
||||
bar_color = mode == 'dark' and dark_primary or primary
|
||||
end
|
||||
-%>
|
||||
<!DOCTYPE html>
|
||||
<html lang="<%=luci.i18n.context.lang%>">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>
|
||||
<%=striptags( (boardinfo.hostname or "?") .. ( (node and node.title) and ' - ' .. translate(node.title) or '')) %>
|
||||
- LuCI</title>
|
||||
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport" />
|
||||
<meta name="format-detection" content="telephone=no, email=no" />
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
<meta name="x5-fullscreen" content="true">
|
||||
<meta name="full-screen" content="yes">
|
||||
<meta name="x5-page-mode" content="app">
|
||||
<meta name="browsermode" content="application">
|
||||
<meta name="msapplication-tap-highlight" content="no">
|
||||
<meta name="msapplication-TileColor" content="<%=bar_color%>">
|
||||
<meta name="application-name" content="<%=striptags( (boardinfo.hostname or "?") ) %> - LuCI">
|
||||
<meta name="apple-mobile-web-app-title" content="<%=striptags( (boardinfo.hostname or "?") ) %> - LuCI">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="<%=media%>/icon/apple-icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="<%=media%>/icon/apple-icon-72x72.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="<%=media%>/icon/apple-icon-144x144.png">
|
||||
<link rel="icon" type="image/png" sizes="192x192" href="<%=media%>/icon/android-icon-192x192.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="<%=media%>/icon/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="96x96" href="<%=media%>/icon/favicon-96x96.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="<%=media%>/icon/favicon-16x16.png">
|
||||
<link rel="manifest" href="<%=media%>/icon/manifest.json" crossorigin="use-credentials">
|
||||
<meta name="msapplication-TileColor" content="<%=bar_color%>">
|
||||
<meta name="msapplication-TileImage" content="<%=media%>/icon/ms-icon-144x144.png">
|
||||
<meta name="theme-color" content="<%=bar_color%>">
|
||||
<link rel="stylesheet" href="<%=media%>/css/cascade.css?v=2.3.2">
|
||||
<style title="text/css">
|
||||
<% if mode == 'normal' then %>
|
||||
@media (prefers-color-scheme: dark) {
|
||||
<%=dark_css%>
|
||||
}
|
||||
<% elseif mode == 'dark' then %>
|
||||
<%=dark_css%>
|
||||
<% end -%>
|
||||
<% if fs.access('/etc/config/argon') then %>
|
||||
:root {
|
||||
--primary: <%=primary%>;
|
||||
--dark-primary: <%=dark_primary%>;
|
||||
--blur-radius:<%=blur_radius%>px;
|
||||
--blur-opacity:<%=blur_opacity%>;
|
||||
--blur-radius-dark:<%=blur_radius_dark%>px;
|
||||
--blur-opacity-dark:<%=blur_opacity_dark%>;
|
||||
}
|
||||
<% end -%>
|
||||
</style>
|
||||
<link rel="shortcut icon" href="<%=media%>/favicon.ico">
|
||||
<% if node and node.css then %>
|
||||
<link rel="stylesheet" href="<%=resource%>/<%=node.css%>">
|
||||
<% end -%>
|
||||
<% if css then %>
|
||||
<style title="text/css">
|
||||
<%=css %>
|
||||
</style>
|
||||
<% end -%>
|
||||
<script src="<%=media%>/js/jquery.min.js?v=3.5.1"></script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@@ -0,0 +1,14 @@
|
||||
<%#
|
||||
Copyright 2008 Steven Barth <steven@midlink.org>
|
||||
Copyright 2008-2019 Jo-Philipp Wich <jo@mein.io>
|
||||
Licensed to the public under the Apache License 2.0.
|
||||
-%>
|
||||
|
||||
<%
|
||||
local ver = require "luci.version"
|
||||
|
||||
if not luci.dispatcher.context.template_header_sent then
|
||||
include("themes/" .. theme .. "/header_login")
|
||||
luci.dispatcher.context.template_header_sent = true
|
||||
end
|
||||
%>
|
||||
@@ -0,0 +1,163 @@
|
||||
<%#
|
||||
Argon is a clean HTML5 theme for LuCI. It is based on luci-theme-bootstrap and MUI and Argon Template
|
||||
|
||||
luci-theme-argon
|
||||
Copyright 2020 Jerryk <jerrykuku@gmail.com>
|
||||
|
||||
Have a bug? Please create an issue here on GitHub!
|
||||
https://github.com/jerrykuku/luci-theme-argon/issues
|
||||
|
||||
luci-theme-bootstrap:
|
||||
Copyright 2008 Steven Barth <steven@midlink.org>
|
||||
Copyright 2008-2016 Jo-Philipp Wich <jow@openwrt.org>
|
||||
Copyright 2012 David Menting <david@nut-bolt.nl>
|
||||
|
||||
MUI:
|
||||
https://github.com/muicss/mui
|
||||
|
||||
Argon Theme
|
||||
https://demos.creative-tim.com/argon-dashboard/index.html
|
||||
|
||||
Licensed to the public under the Apache License 2.0
|
||||
-%>
|
||||
|
||||
<%+themes/argon/out_header_login%>
|
||||
<%
|
||||
local util = require "luci.util"
|
||||
local fs = require "nixio.fs"
|
||||
local nutil = require "nixio.util"
|
||||
local json = require "luci.jsonc"
|
||||
local sys = require "luci.sys"
|
||||
local uci = require 'luci.model.uci'.cursor()
|
||||
|
||||
-- Fetch Local Background Media
|
||||
|
||||
local function glob(...)
|
||||
local iter, code, msg = fs.glob(...)
|
||||
if iter then
|
||||
return nutil.consume(iter)
|
||||
else
|
||||
return nil, code, msg
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local imageTypes = " jpg png gif webp "
|
||||
local videoTypes = " mp4 webm "
|
||||
local allTypes = imageTypes .. videoTypes
|
||||
local function fetchMedia(path, themeDir)
|
||||
local backgroundTable = {}
|
||||
local backgroundCount = 0
|
||||
for i, f in ipairs(glob(path)) do
|
||||
attr = fs.stat(f)
|
||||
if attr then
|
||||
local ext = fs.basename(f):match(".+%.(%w+)$")
|
||||
if ext ~= nil then
|
||||
ext = ext:lower()
|
||||
end
|
||||
if ext ~= nil and string.match(allTypes, " "..ext.." ") ~= nil then
|
||||
local bg = {}
|
||||
bg.type = ext
|
||||
bg.url = themeDir .. fs.basename(f)
|
||||
table.insert(backgroundTable, bg)
|
||||
backgroundCount = backgroundCount + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
return backgroundTable, backgroundCount
|
||||
end
|
||||
local function selectBackground(themeDir)
|
||||
local bgUrl = media .. "/img/bg1.jpg"
|
||||
local backgroundType = "Image"
|
||||
local mimeType = ""
|
||||
|
||||
if fs.access("/etc/config/argon") then
|
||||
local online_wallpaper = uci:get_first('argon', 'global', 'online_wallpaper') or (uci:get_first('argon', 'global', 'bing_background') == '1' and 'bing')
|
||||
if (online_wallpaper and online_wallpaper ~= "none") then
|
||||
local picurl = sys.exec("/usr/libexec/argon/online_wallpaper")
|
||||
if (picurl and picurl ~= '') then
|
||||
return picurl, "Image", ""
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local backgroundTable, backgroundCount = fetchMedia("/www" .. themeDir .. "*", themeDir)
|
||||
if ( backgroundCount > 0 ) then
|
||||
local currentBg = backgroundTable[math.random(1, backgroundCount)]
|
||||
bgUrl = currentBg.url
|
||||
if (string.match(videoTypes, " "..currentBg.type.." ") ~= nil) then
|
||||
backgroundType = "Video"
|
||||
mimeType = "video/" .. currentBg.type
|
||||
end
|
||||
end
|
||||
|
||||
return bgUrl, backgroundType, mimeType
|
||||
end
|
||||
|
||||
local boardinfo = util.ubus("system", "board")
|
||||
local themeDir = media .. "/background/"
|
||||
local bgUrl, backgroundType, mimeType = selectBackground(themeDir)
|
||||
%>
|
||||
<!-- Login Page Start -->
|
||||
<div class="login-page">
|
||||
<% if ( backgroundType == "Video" ) then %>
|
||||
<!-- Video Player Start -->
|
||||
<div class="video">
|
||||
<video autoplay loop muted id="video">
|
||||
<source src="<%=bgUrl%>" type="<%=mimeType%>">
|
||||
</video>
|
||||
</div>
|
||||
<div class="volume-control mute"></div>
|
||||
<script>
|
||||
$(".volume-control").click(function(){
|
||||
if($(this).hasClass("mute")){
|
||||
$(this).removeClass("mute")
|
||||
$("#video").prop('muted', false);
|
||||
}else{
|
||||
$(this).addClass("mute")
|
||||
$("#video").prop('muted', true);
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<!-- Video Player End -->
|
||||
<% else %>
|
||||
<!-- Image Background Start -->
|
||||
<div class="main-bg" id="main-bg" style="background-image:url(<%=bgUrl%>)"></div>
|
||||
<!-- Image Background End -->
|
||||
<% end %>
|
||||
<!-- Login Container Start -->
|
||||
<div class="login-container">
|
||||
<div class="login-form">
|
||||
<!-- Logo Start -->
|
||||
<a class="brand" href="/"><img src="<%=media%>/img/argon.svg" class="icon">
|
||||
<span class="brand-text"><%=striptags( (boardinfo.hostname or "?") ) %></span>
|
||||
</a>
|
||||
<!-- Logo End -->
|
||||
<!-- Login Form Start -->
|
||||
<form class="form-login" method="post" action="<%=pcdata(luci.http.getenv("REQUEST_URI"))%>">
|
||||
|
||||
<%- if fuser then %>
|
||||
<div class="errorbox"><%:Invalid username and/or password! Please try again.%></div>
|
||||
<% end -%>
|
||||
|
||||
<div class="input-container">
|
||||
<div class="input-group user-icon">
|
||||
<input class="cbi-input-user" id="cbi-input-user" type="text" name="luci_username" value="<%=duser%>" />
|
||||
<label class="border" for="cbi-input-user"></label>
|
||||
</div>
|
||||
<div class="input-group pass-icon">
|
||||
<input class="cbi-input-password" id="cbi-input-password" type="password" name="luci_password" />
|
||||
<label class="border" for="cbi-input-password"></label>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<input type="submit" value="<%:Log in%>" class="cbi-button cbi-button-apply" />
|
||||
</div>
|
||||
</form>
|
||||
<!-- Login Form End -->
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
var input = document.getElementsByName('luci_password')[0];
|
||||
if (input)
|
||||
input.focus();
|
||||
//]]></script>
|
||||
<%+themes/argon/footer_login%>
|
||||
105
ipk-source/luci-theme-argon/root/usr/libexec/argon/online_wallpaper
Executable file
@@ -0,0 +1,105 @@
|
||||
#!/bin/sh
|
||||
# author jjm2473
|
||||
|
||||
# the script will be excuted when `argon.@global[0].bing_background == '1'`
|
||||
# defaults to 'bing' to be compatible with old config
|
||||
WEB_PIC_SRC=$(uci -q get argon.@global[0].online_wallpaper || echo 'bing')
|
||||
# For now, the next two variables are used for wallhaven.cc with specified Tag ID
|
||||
# API_KEY if user has an account with wallhaven and want to use their apikey to allow for more images
|
||||
# EXACT_RESO is used for exact resolution by default, if not use 'atleast' instead of 'resolutions'
|
||||
API_KEY=$(uci -q get argon.@global[0].use_api_key)
|
||||
EXACT_RESO=$(uci -q get argon.@global[0].use_exact_resolution || echo '1')
|
||||
CACHE=/var/run/argon_${WEB_PIC_SRC}.url
|
||||
WRLOCK=/var/lock/argon_${WEB_PIC_SRC}.lock
|
||||
|
||||
fetch_pic_url() {
|
||||
case $WEB_PIC_SRC in
|
||||
bing)
|
||||
local picpath=$(curl -fks --max-time 3 \
|
||||
"https://www.bing.com/HPImageArchive.aspx?format=js&n=1" |
|
||||
jsonfilter -qe '@.images[0].url')
|
||||
[ -n "${picpath}" ] && echo "//www.bing.com${picpath}"
|
||||
;;
|
||||
unsplash)
|
||||
if [ -z "$API_KEY" ]; then
|
||||
curl -fks --max-time 3 \
|
||||
"https://source.unsplash.com/1920x1080/daily?wallpapers" |
|
||||
sed -E 's#^.*href="([^?]+)\?.*$#\1?fm=jpg\&fit=crop\&w=1920\&h=1080#'
|
||||
else
|
||||
curl -fks --max-time 3 \
|
||||
"https://api.unsplash.com/photos/random?client_id=${API_KEY}" |
|
||||
jsonfilter -qe '@["urls"]["regular"]'
|
||||
fi
|
||||
;;
|
||||
unsplash_*)
|
||||
local collection_id=${WEB_PIC_SRC#unsplash_}
|
||||
if [ -z "$API_KEY" ]; then
|
||||
curl -fks --max-time 3 \
|
||||
"https://source.unsplash.com/collection/${collection_id}/1920x1080" |
|
||||
sed -E 's#^.*href="([^?]+)\?.*$#\1?fm=jpg\&fit=crop\&w=1920\&h=1080#'
|
||||
else
|
||||
curl -fks --max-time 3 \
|
||||
"https://api.unsplash.com/photos/random?client_id=${API_KEY}&collections=${collection_id}" |
|
||||
jsonfilter -qe '@["urls"]["regular"]'
|
||||
fi
|
||||
;;
|
||||
wallhaven)
|
||||
curl -fks --max-time 3 \
|
||||
"https://wallhaven.cc/api/v1/search?resolutions=1920x1080&sorting=random" |
|
||||
jsonfilter -qe '@.data[0].path'
|
||||
;;
|
||||
wallhaven_*)
|
||||
local tag_id=${WEB_PIC_SRC#wallhaven_}
|
||||
local has_api_key=""
|
||||
[ -n "$API_KEY" ] && has_api_key="apikey=$API_KEY&" || has_api_key=""
|
||||
local use_reso="resolutions"
|
||||
[ "$EXACT_RESO" -eq "1" ] && use_reso='resolutions' || use_reso='atleast'
|
||||
curl -fks --max-time 3 \
|
||||
"https://wallhaven.cc/api/v1/search?${has_api_key}q=id%3A${tag_id}&${use_reso}=1920x1080&sorting=random" |
|
||||
jsonfilter -qe '@.data[0].path'
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
try_update() {
|
||||
local lock="$WRLOCK"
|
||||
exec 200>$lock
|
||||
|
||||
if flock -n 200 >/dev/null 2>&1; then
|
||||
local picurl=$(fetch_pic_url)
|
||||
if [[ "$WEB_PIC_SRC" == wallhave* ]] ; then
|
||||
curl -fks --max-time 3 --url "${picurl}" > /dev/null
|
||||
fi
|
||||
if [ -n "$picurl" ]; then
|
||||
echo "${picurl}" | tee "$CACHE"
|
||||
else
|
||||
if [ -s "$CACHE" ]; then
|
||||
cat "$CACHE"
|
||||
else
|
||||
touch "$CACHE"
|
||||
fi
|
||||
fi
|
||||
flock -u 200 >/dev/null 2>&1
|
||||
elif [ -s "$CACHE" ]; then
|
||||
cat "$CACHE"
|
||||
fi
|
||||
}
|
||||
|
||||
get_url() {
|
||||
if [ -f "$CACHE" ]; then
|
||||
local idle_t=$(($(date '+%s') - $(date -r "$CACHE" '+%s' 2>/dev/null || echo '0')))
|
||||
if [ -s "$CACHE" ]; then
|
||||
if [ $idle_t -le 43200 ]; then
|
||||
cat "$CACHE"
|
||||
return
|
||||
fi
|
||||
else
|
||||
if [ $idle_t -le 120 ]; then
|
||||
return
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
try_update
|
||||
}
|
||||
|
||||
get_url
|
||||
@@ -0,0 +1,2 @@
|
||||
Drop background here!
|
||||
accept jpg png gif mp4 webm
|
||||
|
After Width: | Height: | Size: 9.4 KiB |
|
After Width: | Height: | Size: 69 KiB |
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<metadata>Generated by IcoMoon</metadata>
|
||||
<defs>
|
||||
<font id="argon" horiz-adv-x="1024">
|
||||
<font-face units-per-em="1024" ascent="960" descent="-64" />
|
||||
<missing-glyph horiz-adv-x="1024" />
|
||||
<glyph unicode=" " horiz-adv-x="512" d="" />
|
||||
<glyph unicode="" glyph-name="expand_more" d="M708 572.667l60-60-256-256-256 256 60 60 196-196z" />
|
||||
<glyph unicode="" glyph-name="menu" d="M128 682.667h768v-86h-768v86zM128 384.667v84h768v-84h-768zM128 170.667v86h768v-86h-768z" />
|
||||
<glyph unicode="" glyph-name="favorite" d="M512 28.667l-62 56q-106 96-154 142t-107 114-81 123-22 113q0 98 67 166t167 68q116 0 192-90 76 90 192 90 100 0 167-68t67-166q0-78-52-162t-113-146-199-186z" />
|
||||
<glyph unicode="" glyph-name="spinner" d="M512 960c-278.748 0-505.458-222.762-511.848-499.974 5.92 241.864 189.832 435.974 415.848 435.974 229.75 0 416-200.576 416-448 0-53.020 42.98-96 96-96s96 42.98 96 96c0 282.77-229.23 512-512 512zM512-64c278.748 0 505.458 222.762 511.848 499.974-5.92-241.864-189.832-435.974-415.848-435.974-229.75 0-416 200.576-416 448 0 53.020-42.98 96-96 96s-96-42.98-96-96c0-282.77 229.23-512 512-512z" />
|
||||
<glyph unicode="" glyph-name="delete" d="M125.458 707.971l32.017-640.746c0-72.474 59.964-131.225 133.93-131.225h442.45c73.965 0 133.936 58.75 133.936 131.225l30.8 640.746h-773.133zM936.022 753.424c0.132 27.023 0.212 28.82 0.212 30.63 0 70.468-41.716 109.142-97.69 109.142l-155.797-0.164c0 36.987-36.126 66.968-73.112 66.968h-193.946c-36.979 0-74.274-29.981-74.274-66.968l-155.958 0.164c-61.826 0-97.69-47.127-97.69-109.142 0-1.817 0.072-3.608 0.212-30.63h848.046zM646.026 539.594c0 20.428 16.556 36.986 36.979 36.986 20.428 0 36.986-16.558 36.986-36.986v-423.683c0-20.43-16.558-36.987-36.986-36.987-20.423 0-36.979 16.558-36.979 36.987v423.683zM475.011 539.594c0 20.428 16.563 36.986 36.987 36.986 20.428 0 36.986-16.558 36.986-36.986v-423.683c0-20.43-16.558-36.987-36.986-36.987-20.423 0-36.987 16.558-36.987 36.987v423.683zM304.113 539.594c0 20.428 16.558 36.986 36.987 36.986 20.422 0 36.986-16.558 36.986-36.986v-423.683c0-20.43-16.563-36.987-36.986-36.987-20.43 0-36.987 16.558-36.987 36.987v423.683z" />
|
||||
<glyph unicode="" glyph-name="edit" d="M272.359 84.325c-6.319-1.194-12.678-1.728-18.975-1.728-27.681 0-54.578 10.908-74.5 30.859-24.491 24.471-35.378 59.415-29.143 93.476 61.33 335.066 88.166 361.923 109.776 383.553l285.612 285.592-65.898 65.898h-416.008c-34.925 0-63.223-28.298-63.223-63.222v-878.107c0-34.946 28.299-63.223 63.223-63.223h634.405c34.927 0 63.225 28.276 63.225 63.223v298.383l-104.98-104.98c-21.589-21.568-48.445-48.404-383.512-109.723zM1005.077 783.632l-156.041 156.040c-25.211 25.211-66.104 25.211-91.313-0.021l-423.707-423.685c-25.212-25.232-80.633-328.009-80.633-328.009s302.777 55.423 328.009 80.633l423.685 423.707c25.232 25.212 25.232 66.104 0 91.336zM441.878 297.937l-47.643-16.134c-1.338-0.455-2.779-0.659-4.219-0.681-0.267 0-0.536 0.084-0.803 0.103-1.544 0.063-3.087 0.351-4.549 0.845-0.433 0.144-0.885 0.289-1.296 0.472-1.626 0.701-3.149 1.544-4.281 2.697l-28.462 28.463c-3.539 3.539-5.145 10.042-3.416 15.105l16.155 47.645c1.008 2.984 2.305 5.699 3.684 8.251 0.33 0.639 0.68 1.256 1.050 1.854 1.42 2.386 2.944 4.609 4.59 6.421 0.144 0.164 0.287 0.267 0.432 0.411 1.565 1.646 3.19 2.945 4.817 3.973 0.433 0.268 0.864 0.535 1.275 0.741 1.791 0.907 3.561 1.523 5.29 1.544 0.782 0 1.502-0.207 2.244-0.392 0.473-0.103 0.946-0.103 1.399-0.289 1.194-0.495 2.325-1.235 3.396-2.305l70.569-70.57c8.787-8.788-2.655-22.186-20.231-28.155zM888.078 726.727l-42.845-42.847c-8.233-8.232-21.569-8.232-29.802 0l-66.124 66.124c-8.231 8.233-8.231 21.568 0 29.801l42.849 42.847c8.231 8.232 21.567 8.232 29.8 0l66.122-66.124c8.233-8.233 8.233-21.568 0-29.801z" />
|
||||
<glyph unicode="" glyph-name="use" d="M0 426.667l384-384 640 640-170.667 170.667-469.333-469.333-213.333 213.333z" />
|
||||
<glyph unicode="" glyph-name="loading" d="M870.623 198.711c0-3.451 2.797-6.248 6.248-6.248s6.248 2.797 6.248 6.248c0 0 0 0.001 0 0.001 0 3.45-2.797 6.247-6.247 6.247 0 0-0.001 0-0.001 0v0c0 0-0.001 0-0.001 0-3.45 0-6.247-2.797-6.247-6.247 0 0 0-0.001 0-0.001v0zM732.694 56.388c0-6.863 5.563-12.427 12.427-12.427s12.427 5.563 12.427 12.427-5.563 12.427-12.427 12.427-12.427-5.563-12.427-12.427zM546.774-16.868c0-10.313 8.361-18.674 18.674-18.674s18.674 8.361 18.674 18.674-8.361 18.674-18.674 18.674-18.674-8.361-18.674-18.674zM346.643-7.050c0-13.726 11.128-24.853 24.853-24.853s24.853 11.128 24.853 24.853-11.128 24.853-24.853 24.853-24.853-11.128-24.853-24.853zM169.099 84.056c0-17.177 13.924-31.101 31.101-31.101s31.101 13.924 31.101 31.101-13.924 31.101-31.101 31.101-31.101-13.924-31.101-31.101zM46.137 238.943c0-20.627 16.722-37.349 37.349-37.349s37.349 16.722 37.349 37.349-16.722 37.349-37.349 37.349-37.349-16.722-37.349-37.349zM0 429.12c0-24.040 19.487-43.528 43.528-43.528s43.528 19.487 43.528 43.528-19.487 43.528-43.528 43.528-43.528-19.487-43.528-43.528zM37.967 618.060c0-27.49 22.285-49.775 49.775-49.775s49.775 22.285 49.775 49.775c0 27.49-22.285 49.775-49.775 49.775s-49.775-22.285-49.775-49.775zM151.866 770.407c0-30.941 25.082-56.023 56.023-56.023s56.023 25.082 56.023 56.023c0 30.941-25.082 56.023-56.023 56.023s-56.023-25.082-56.023-56.023zM319.112 857.669c0-34.354 27.848-62.202 62.202-62.202s62.202 27.848 62.202 62.202-27.848 62.202-62.202 62.202-62.202-27.848-62.202-62.202zM506.954 863.092c0-37.804 30.646-68.45 68.45-68.45s68.45 30.646 68.45 68.45c0 37.804-30.646 68.45-68.45 68.45s-68.45-30.646-68.45-68.45zM678.936 785.717c0-41.216 33.413-74.629 74.629-74.629s74.629 33.413 74.629 74.629-33.413 74.629-74.629 74.629-74.629-33.413-74.629-74.629zM801.144 640.373c0-44.667 36.209-80.876 80.876-80.876s80.876 36.209 80.876 80.876-36.209 80.876-80.876 80.876-80.876-36.209-80.876-80.876zM849.752 452.119c0-48.117 39.007-87.124 87.124-87.124s87.124 39.007 87.124 87.124c0 48.117-39.007 87.124-87.124 87.124s-87.124-39.007-87.124-87.124z" />
|
||||
<glyph unicode="" glyph-name="switch" d="M275.2 486.4v-512h121.6v947.2l-396.8-435.2zM748.8 409.6v512h-121.6v-947.2l396.8 435.2z" />
|
||||
<glyph unicode="" glyph-name="error" d="M0.001 886.857l73.143 73.143 950.855-950.855-73.142-73.143-950.857 950.855zM73.146-63.998l-73.142 73.143 950.855 950.855 73.142-73.142-950.855-950.857z" />
|
||||
<glyph unicode="" glyph-name="dashboard" d="M567.979 960h456.021v-341.333h-456.021v341.333zM567.979-64v567.979h456.021v-567.979h-456.021zM0-64v341.333h456.021v-341.333h-456.021zM0 392.021v567.979h456.021v-567.979h-456.021z" />
|
||||
<glyph unicode="" glyph-name="logout" d="M764.839 182.518v164.346h-353.976v202.272h353.976v164.346l265.482-265.482-265.482-265.482zM562.568 953.68c55.624 0 101.136-45.511 101.136-101.136v-202.272h-101.136v202.272h-455.112v-809.088h455.112v202.272h101.136v-202.272c0-55.624-45.511-101.136-101.136-101.136h-455.112c-55.624 0-101.136 45.511-101.136 101.136v809.088c0 55.624 45.511 101.136 101.136 101.136h455.112z" />
|
||||
<glyph unicode="" glyph-name="Network" d="M384 192h256v-256h-256zM384 959.999h256v-256h-256zM768 192h256v-256h-256zM0.001 192h256v-256h-256zM480.001 640h64v-160h-64zM480.001 448h64v-192h-64zM928 256h-64v160h-704v-160h-64v224h832z" />
|
||||
<glyph unicode="" glyph-name="services" d="M548.901 208.144c2.306 9.225 2.306 20.757 2.306 32.289s0 20.757-2.306 32.289l64.576 46.126c6.919 4.613 9.225 13.838 4.613 20.757l-62.27 106.090c-4.613 6.919-11.532 9.225-18.451 6.919l-71.495-34.595c-16.144 13.838-34.595 23.063-55.351 32.289l-6.919 78.414c0 6.919-6.919 13.838-13.838 13.838h-122.235c-6.919 0-13.838-6.919-13.838-13.838l-9.225-80.721c-20.757-6.919-36.901-18.451-55.351-32.289l-71.495 32.289c-6.919 2.306-16.144 0-18.451-6.919l-62.27-106.090c-4.613-6.919-2.306-16.144 4.613-20.757l64.576-46.126c-2.306-9.225-2.306-20.757-2.306-32.289s0-20.757 2.306-32.289l-64.576-46.126c-6.919-4.613-9.225-13.838-4.613-20.757l62.27-106.090c4.613-6.919 11.532-9.225 18.451-6.919l71.495 32.289c16.144-13.838 34.595-23.063 55.351-32.289l6.919-78.414c0-6.919 6.919-13.838 13.838-13.838h122.235c6.919 0 13.838 6.919 13.838 13.838l6.919 78.414c20.757 6.919 36.901 18.451 55.351 32.289l71.495-32.289c6.919-2.306 16.144 0 18.451 6.919l62.27 106.090c4.613 6.919 2.306 16.144-4.613 20.757l-62.27 50.738zM327.495 125.117c-64.576 0-115.316 50.738-115.316 115.316s50.738 115.316 115.316 115.316 115.316-50.738 115.316-115.316-50.738-115.316-115.316-115.316zM924.829 648.649c2.306 11.532 2.306 20.757 2.306 29.982s0 18.451-2.306 29.982l57.657 41.514c6.919 4.613 6.919 11.532 4.613 18.451l-57.657 99.171c-4.613 6.919-11.532 9.225-18.451 4.613l-66.883-29.982c-16.144 11.532-32.289 20.757-50.738 29.982l-6.919 71.495c2.306 6.919-2.306 11.532-9.225 11.532h-113.009c-6.919 0-13.838-4.613-13.838-11.532l-6.919-71.495c-18.451-6.919-34.595-16.144-50.738-29.982l-66.883 29.982c-6.919 2.306-13.838 0-18.451-4.613l-57.657-99.171c-4.613-6.919-2.306-13.838 4.613-18.451l57.657-41.514v-29.982c0-9.225 0-18.451 2.306-29.982l-57.657-41.514c-6.919-4.613-6.919-11.532-4.613-18.451l57.657-99.171c4.613-6.919 11.532-9.225 18.451-4.613l66.883 29.982c16.144-11.532 32.289-20.757 50.738-29.982l6.919-71.495c0-6.919 6.919-11.532 13.838-11.532h113.009c6.919 0 13.838 4.613 13.838 11.532l6.919 71.495c18.451 6.919 34.595 16.144 50.738 29.982l66.883-29.982c6.919-2.306 13.838 0 18.451 4.613l57.657 99.171c4.613 6.919 2.306 13.838-4.613 18.451l-64.576 41.514zM719.568 563.316c-64.576 0-115.316 50.738-115.316 115.316s50.738 115.316 115.316 115.316 115.316-50.738 115.316-115.316-50.738-115.316-115.316-115.316z" />
|
||||
<glyph unicode="" glyph-name="system" d="M512 191.089c-142.121 0-255.089 112.968-255.089 255.089s112.968 255.089 255.089 255.089 255.089-112.968 255.089-255.089-112.968-255.089-255.089-255.089zM1022.178 362.363v167.63c-32.797 7.288-69.238 14.577-109.324 18.221-10.932 40.085-25.509 76.527-43.73 109.324 25.509 32.797 47.374 61.95 65.594 91.103l-120.256 120.256c-29.153-18.221-58.306-40.085-91.103-61.95-32.797 18.221-69.238 36.441-109.324 43.73-3.644 40.085-10.932 76.527-18.221 109.324h-167.63c-7.288-32.797-14.577-69.238-18.221-109.324-40.085-10.932-76.527-25.509-109.324-43.73-32.797 18.221-61.95 40.085-91.103 58.306l-116.612-116.612c18.221-29.153 40.085-58.306 61.95-91.103-18.221-32.797-36.441-69.238-43.73-109.324-40.085-3.644-76.527-10.932-109.324-18.221v-167.63c32.797-7.288 69.238-14.577 109.324-18.221 10.932-40.085 25.509-76.527 43.73-109.324-25.509-32.797-47.374-61.95-61.95-91.103l120.256-120.256c29.153 18.221 58.306 40.085 91.103 65.594 32.797-18.221 69.238-36.441 109.324-43.73 3.644-40.085 10.932-76.527 18.221-109.324h167.63c7.288 32.797 14.577 69.238 18.221 109.324 40.085 10.932 76.527 25.509 109.324 43.73 32.797-25.509 61.95-47.374 91.103-65.594l120.256 120.256c-18.221 29.153-40.085 58.306-65.594 91.103 18.221 32.797 36.441 69.238 43.73 109.324 36.441 3.644 72.883 10.932 105.68 18.221z" />
|
||||
<glyph unicode="" glyph-name="vpn" d="M977.454 820.363v23.272c0 65.163-51.2 116.364-116.364 116.364s-116.364-51.2-116.364-116.364v-23.272c-27.927 0-46.546-18.619-46.546-46.546v-186.182c0-27.927 18.619-46.546 46.546-46.546h232.727c27.927 0 46.546 18.619 46.546 46.546v186.182c0 27.927-18.619 46.546-46.546 46.546zM940.217 820.363h-158.255v23.272c0 41.891 37.236 79.127 79.127 79.127s79.127-37.236 79.127-79.127v-23.272zM833.163 448c0-13.964 4.655-32.582 4.655-46.546 0-97.745-37.236-186.182-97.745-251.345-13.964 37.236-46.546 65.163-88.437 65.163h-46.546v139.636c0 27.927-18.619 46.546-46.546 46.546h-279.272v93.090h93.090c27.927 0 46.546 18.619 46.546 46.546v93.090h93.090c51.2 0 93.090 41.891 93.090 93.090v116.364c-41.891 13.964-93.090 23.272-139.636 23.272-256 0-465.454-209.454-465.454-465.454s209.454-465.454 465.454-465.454 465.454 209.454 465.454 465.454c0 13.964 0 32.582-4.655 46.546h-93.090zM418.91 33.746c-181.527 23.272-325.818 181.527-325.818 367.709 0 27.927 4.655 55.854 9.309 83.782l223.418-223.418v-46.546c0-51.2 41.891-93.090 93.090-93.090v-88.437z" />
|
||||
<glyph unicode="" glyph-name="storage" d="M512 521.152c90.304 0 174.656 8.192 253.12 24.576s140.416 40.576 185.728 72.576v-97.152c0-26.304-19.648-50.688-58.88-73.152s-92.544-40.32-160-53.44c-67.392-13.12-140.736-19.712-219.968-19.712s-152.576 6.592-220.032 19.712c-67.392 13.184-120.704 30.976-160 53.44-39.232 22.464-58.88 46.848-58.88 73.152v97.152c45.312-32 107.264-56.192 185.728-72.576 78.528-16.384 162.88-24.576 253.184-24.576v0 0zM512 82.304c90.304 0 174.656 8.192 253.12 24.576s140.416 40.576 185.728 72.576v-97.152c0-26.304-19.648-50.688-58.88-73.152s-92.544-40.32-160-53.44c-67.392-13.12-140.736-19.712-219.968-19.712s-152.576 6.592-220.032 19.712c-67.456 13.12-120.768 30.976-160 53.44s-58.88 46.848-58.88 73.152v97.152c45.312-32 107.264-56.192 185.728-72.576 78.528-16.384 162.88-24.576 253.184-24.576v0 0zM512 301.696c90.304 0 174.656 8.192 253.12 24.576s140.416 40.576 185.728 72.576v-97.152c0-26.304-19.648-50.688-58.88-73.152s-92.544-40.256-160-53.44c-67.392-13.12-140.736-19.648-219.968-19.648s-152.576 6.592-220.032 19.712c-67.456 13.12-120.768 30.976-160 53.44s-58.88 46.848-58.88 73.152v97.088c45.312-32 107.264-56.192 185.728-72.576 78.528-16.384 162.88-24.576 253.184-24.576v0 0zM512 960c79.232 0 152.576-6.592 220.032-19.712s120.768-30.976 160-53.44c39.232-22.464 58.88-46.848 58.88-73.152v-73.152c0-26.304-19.648-50.688-58.88-73.152s-92.544-40.256-160-53.44c-67.456-13.12-140.8-19.648-220.032-19.648s-152.576 6.592-220.032 19.712c-67.456 13.12-120.768 30.976-160 53.44s-58.88 46.848-58.88 73.152v73.088c0 26.304 19.648 50.688 58.88 73.152s92.544 40.32 160 53.44c67.456 13.12 140.8 19.712 220.032 19.712v0 0z" />
|
||||
<glyph unicode="" glyph-name="statistics" d="M933.842 916.59h-845.911c-48.973 0-89.044-40.069-89.044-89.044v-623.301c0-48.973 40.069-89.044 89.044-89.044h378.434v-66.783h-175.861c-22.261 0-42.296-15.583-46.748-37.844-4.452-28.939 17.808-51.2 44.521-51.2h442.991c22.261 0 42.296 15.583 46.748 37.844 4.452 28.939-17.808 51.2-44.521 51.2h-178.086v66.783h378.434c48.973 0 89.044 40.069 89.044 89.044v623.301c0 48.973-40.069 89.044-89.044 89.044zM800.277 471.374h-146.921l-51.2-151.373c-4.452-13.356-22.261-15.583-31.165-4.452l-160.278 222.61-20.035-51.2c-2.227-8.904-11.131-13.356-20.035-13.356h-169.182c-22.261 0-42.296 15.583-46.748 37.844-4.452 28.939 17.808 51.2 44.521 51.2h124.661l51.2 129.113c4.452 13.356 22.261 15.583 31.165 4.452l155.826-213.705 22.261 66.783c2.227 8.904 11.131 15.583 20.035 15.583h191.443c22.261 0 42.296-15.583 46.748-37.844 6.679-33.392-13.356-55.652-42.296-55.652z" />
|
||||
<glyph unicode="" glyph-name="hello-world" d="M490 960c14.6 0 29.4 0 44 0 4.2-0.8 8.2-2 12.4-2.6 23-3 46.4-4.4 69-9.2 105-22 194.8-71.8 268.2-149.8 77.6-82.6 123.2-180.4 135.8-293.2 1.4-11.8 3-23.4 4.6-35.2 0-14.6 0-29.4 0-44-0.8-4.2-2-8.2-2.6-12.4-3-23-4.4-46.4-9.2-69-22-105-71.8-194.8-149.8-268.2-82.6-77.6-180.4-123.2-293.2-135.8-11.8-1.4-23.4-3-35.2-4.6-14.6 0-29.4 0-44 0-4.2 0.8-8.2 2-12.4 2.6-23 3-46.4 4.4-69 9.2-105 22-194.8 71.8-268.2 149.8-77.6 82.6-123.2 180.4-135.8 293.2-1.4 11.8-3 23.4-4.6 35.2 0 14.6 0 29.4 0 44 0.8 4.2 2 8.2 2.6 12.4 3 23 4.4 46.4 9.2 69 22 105 71.8 194.8 149.8 268.2 82.6 77.6 180.4 123.2 293.2 135.8 11.8 1.4 23.4 3 35.2 4.6zM337.6 321c6.6-22.4 12.2-41.8 18.2-61.2 3.6-12 11.6-18.4 22-18.4 9.8 0 19 7 23 17.8 2 5.6 3.6 11.4 5.4 17.2 11.2 35.8 22.6 71.6 33.6 107.6 5 16.4-6.4 30.8-21.6 27.8-9.6-2-15.8-7.6-18.6-17.4-6.4-23-13.2-45.8-20.6-71-6.4 22.4-12.2 42.4-18 62.6-3.6 12.6-11.4 19.8-21.8 20.2-10.8 0.4-20.2-7.4-24-20.2-2-6.6-3.8-13.4-5.8-20.2-4.4-15.4-8.6-30.6-13.6-48-7.2 23.8-13.6 45-20.4 66.2-4 13-14 18.4-26 14.8-11.6-3.4-18.2-15.4-14.6-27.6 2.8-9.2 5.8-18.4 8.8-27.6 9.8-30 19.6-60 29.6-90 4-12 11-17.8 21.2-18.2 10.4-0.4 20 6.8 24 17.8 1.2 3.2 1.8 6.4 2.8 9.6 4.8 18.6 10.2 37 16.4 58.2zM880.8 395.6c0 28.4 0 56.6 0 85 0 13-7.8 21.4-19.8 21.4s-21.8-9.2-22-21.2c-0.2-11-0.2-22 0-33 0.2-6.8-1-9-9-7.8-44.6 6.8-80.6-23.6-79.2-66.2 0.4-15.4 0.2-30.6 0.2-46 0.2-25.2 18.2-47.4 42.6-52.4 25.8-5.2 50.2 1.2 73.6 11.6 9.2 4 13.6 12 13.6 22.6 0 28.6 0 57.2 0 86zM184.8 586.4c0 10.2 0 22.4 0 34.6 0 13.2-7.6 21.4-19.6 21.6-11.8 0-22.2-9.4-22.2-21 0-61.6 0-123.4 0-185 0-8.8 4.4-14.4 12.4-17.4 14.2-5.4 29.2 4.8 29.4 20 0.2 29.6 0.4 59.4-0.2 89-0.2 9.8 3.8 14.6 12.2 17.8 21.8 8.4 35 0.2 36.2-23.2 0.2-2.4 0-4.6 0-7 0-23.6 0-47.4 0-71 0-13 7.2-20.8 19-20.6s20.6 8.8 20.6 21c0.2 30.4 0.2 60.6 0 91-0.2 23.2-17.4 46-40 49.8-14.8 2.8-30.4 0.6-47.8 0.4zM330 493.4c7.6 0.6 14.6 1.2 21.4 1.8 15.2 1.4 30.4 2.2 45.6 4.2 10.2 1.4 18 8.2 19 18 1.4 12.8 1.8 26.2-1 38.6-6.6 29.6-28.2 43.6-62.8 42.8-36.2-0.8-65-29.8-65.2-65.8 0-15.6-0.2-31.2 0-47 0.2-25.4 18.8-47.6 43.4-52.8 24.4-5.2 46.8 1 68.2 11.8 11.2 5.6 15.2 18 10 27.8s-15.8 12.4-27.6 7.6c-8-3.2-16-6.4-24.4-8.4-16-4.2-24.8 2.8-26.6 21.4zM687.8 538.8c-0.4 0-0.6 0-1 0 0 8 0.2 16 0 24-1 20.4-9.8 36.6-27.2 47.2-39.2 23.6-95.8 1.4-105.8-43.2-4.2-18.8-2.4-39-2.4-58.6 0-20 9-36 25.8-47 38.4-25 96.2-3.2 107.4 41 2.8 11.8 2.2 24.4 3.2 36.6zM579.8 339.6c-0.6 0-1.2 0-1.8 0 0 11 1.8 22.2-0.4 32.8-6.2 30.6-29.6 46.8-64 46.2-39-0.6-68-29.4-68.4-68.2-0.2-14.6-0.2-29.4 0-44 0.2-14.2 5-26.8 15-37 18.8-19.2 42-21.8 66.4-15.8 25.6 6.4 43.2 22.4 49.6 48.2 3.2 12.4 2.6 25.2 3.6 37.8zM693.2 379c0-30.2 0-60.6 0-90.8 0-14 6.6-21.2 19.2-21.4 13.6-0.2 22.6 8.4 22.6 22.2 0 60.6 0 121.2 0 181.8 0 10.4-5.8 18-14.6 19.8-14 3-27-7.2-27-21.6-0.4-30-0.2-60-0.2-90zM433.2 550c0-30 0-60 0-90 0-12.6 6.8-20.4 17.8-20.8 11.8-0.6 21.8 8 21.8 19.8 0.2 62.4 0.2 124.6 0 187 0 8.8-4.8 14.2-13 16.8-13.4 4.2-26.6-5.6-26.6-19.8-0.2-31 0-62 0-93zM495.2 556c0-30.4 0-60.6 0-91 0-12.8 7.2-21.2 18.4-21.6 11.4-0.4 21.2 9.4 21.2 21.8 0 61.4 0.2 122.6-0.2 184 0 4.8-2.6 10.4-5.8 14-5.6 6.2-13.4 7-21 3.4-7.8-3.6-12.6-9.4-12.6-18.6 0-30.6 0-61.4 0-92zM595.2 329.8c0-17.4-0.6-34.6 0.4-51.8 0.4-5.4 4-13 8.4-15.2 5.4-2.8 13.6-2.6 19.6-0.8 7.8 2.4 11.4 9.6 11.4 18.2-0.2 27.6 0 55.2 0 82.8 0 25.8 0 25.8 25.6 24.4 12-0.6 21.8 7.2 23.4 18.6 1.6 10.4-5.2 19.6-17.4 21.6-7.8 1.4-16 1.4-23.8 0.8-27.6-2-47.6-24.2-47.6-51.8 0-15.6 0-31.2 0-46.8zM839.2 356.2c0 10.6 0.2 21.2-0.2 32 0 2.8-0.6 6.8-2.4 8-8.6 6.4-18.8 6.4-28.6 3.8-8.6-2.4-15-8.2-15.4-17.6-0.6-17.6-1-35 0-52.6 0.8-12.2 9-18 21.2-17 6.2 0.6 12.6 1.4 18.4 3.6 3 1.2 6.2 5.6 6.6 8.8 0.8 10.4 0.4 20.8 0.4 31zM647.8 537.4c-0.8 7.4-1 14.8-2.2 22-2.2 13.8-9.8 20-23.8 20-14.8-0.2-25.6-8.2-27-21.2-1.2-12.8-2-25.8-1.6-38.8 0.4-8.6-0.4-19 9-24 16.6-8.8 42.2-2.6 43.4 19.4 0.4 7.6 1.4 15 2.2 22.6zM539.8 337.6c-0.6 7.2-1 14.6-2 21.8-2.2 13.8-9.8 20.2-23.8 20-14.8-0.2-26.2-8.2-27-21.2-1-16.8-0.8-33.8 0.2-50.6 0.2-4.6 4.8-11 9-13 18.8-8.6 41.4 0.4 41.8 21 0 7.4 1 14.6 1.8 22zM839.2 356.2c0-10.4 0.6-20.6-0.4-31-0.2-3.2-3.6-7.6-6.6-8.8-5.8-2.2-12.2-3.2-18.4-3.6-12.2-1-20.4 4.8-21.2 17-1 17.4-0.6 35 0 52.6 0.4 9.4 6.8 15.2 15.4 17.6 9.8 2.6 20 2.6 28.6-3.8 1.8-1.4 2.4-5.4 2.4-8 0.2-10.6 0.2-21.2 0.2-32zM330.4 533c1 19.4 10.2 27.6 28.2 26.2 8.6-0.8 16.6-8.6 16.2-17.2-0.2-2-3.8-5.2-6-5.4-12.6-1.6-25.2-2.4-38.4-3.6zM647.8 537.4c-0.6-7.6-1.6-15-2-22.6-1.2-22-26.8-28.4-43.4-19.4-9.4 5-8.8 15.4-9 24-0.4 12.8 0.4 25.8 1.6 38.8s12.2 21 27 21.2c14 0.2 21.6-6 23.8-20 1-7.2 1.2-14.6 2-22zM539.8 337.6c-0.6-7.4-1.8-14.6-1.8-21.8-0.4-20.6-23-29.6-41.8-21-4.2 2-8.6 8.4-9 13-1 16.8-1.2 33.8-0.2 50.6 0.8 13 12.2 21 27 21.2 14 0.2 21.6-6.2 23.8-20 1-7.6 1.2-14.8 2-22z" />
|
||||
<glyph unicode="" glyph-name="angle-right" d="M704.6 414l-272-272c-18.8-18.8-49.2-18.8-67.8 0l-45.2 45.2c-18.8 18.8-18.8 49.2 0 67.8l192.8 192.8-192.8 192.8c-18.8 18.8-18.8 49.2 0 67.8l45 45.6c18.8 18.8 49.2 18.8 67.8 0l272-272c19-18.8 19-49.2 0.2-68z" />
|
||||
<glyph unicode="" glyph-name="password" d="M196.923 603.569v0zM827.077 507.077h-512v92.554c0 104.369 78.769 196.923 183.138 202.831 96.492 5.908 177.231-55.138 202.831-141.785 1.969-7.877 9.846-15.754 19.692-15.754h80.738c11.815 0 21.662 11.815 19.692 23.631-31.508 149.662-165.415 259.938-324.923 252.062-167.385-7.877-295.385-151.631-299.323-317.046v-96.492c-43.323 0-78.769-35.446-78.769-78.769v-374.154c0-43.323 35.446-78.769 78.769-78.769h630.154c43.323 0 78.769 35.446 78.769 78.769v374.154c0 43.323-35.446 78.769-78.769 78.769zM602.585 119.138c3.938-11.815-5.908-25.6-19.692-25.6h-143.754c-13.785 0-23.631 11.815-19.692 25.6l35.446 118.154c-29.538 19.692-47.262 55.138-39.385 94.523 7.877 37.415 37.415 66.954 76.8 74.831 63.015 11.815 118.154-33.477 118.154-92.554 0-31.508-15.754-61.046-41.354-76.8l33.477-118.154z" />
|
||||
<glyph unicode="" glyph-name="docker" d="M537 896l87 2 14-14 1-89-14-13-87-2-14 13-1 90 14 13zM270 756l87 2 14-13 1-90-14-13-87-2-13 14-1 89 13 13zM404 758l88 1 13-14 1-88-13-14-88-1-13 13-1 90 13 13zM538 760l87 1 14-14v-88l-12-14-87-1-14 13-1 89 13 14zM874 675q44-14 102-108 84 2 134-53v-6q-68-104-159-105-199-323-519-327l-74-1q-235-3-311 269l-7 69-1 53 13 15 744 9q34 0 40 21l-1 75q13 89 39 89zM138 618l87 2 14-15v-88l-13-13-87-2-14 13-1 89 14 14zM272 620l86 1 15-14 1-88-14-14-87-1-13 13-1 89 13 14zM405 622l88 1 13-14 1-89-13-13-87-1-13 13-1 89 12 14zM540 624l87 1 13-14 1-89-13-13-87-1-14 13-1 88 14 15zM674 625l86 2 15-14 1-89-14-14-87-1-13 14-1 88 13 14z" />
|
||||
<glyph unicode="" glyph-name="control" d="M1024.001-23.040v942.081c0 22.656-18.304 40.96-40.96 40.96h-942.081c-22.656 0-40.96-18.304-40.96-40.96v-942.081c0-22.656 18.304-40.96 40.96-40.96h942.081c22.656 0 40.96 18.304 40.96 40.96zM293.119 586.241h-98.56c-5.632 0-10.24 4.608-10.24 10.24v61.44c0 5.632 4.608 10.24 10.24 10.24h98.56c17.408 53.376 67.584 92.16 126.72 92.16s109.44-38.785 126.72-92.16h282.88c5.632 0 10.24-4.608 10.24-10.24v-61.44c0-5.632-4.608-10.24-10.24-10.24h-282.88c-17.408-53.376-67.584-92.16-126.72-92.16s-109.44 38.785-126.72 92.16zM477.312 228.352c0-0.256 0.128-0.384 0.128-0.512h-282.88c-5.632 0-10.24 4.608-10.24 10.24v61.44c0 5.632 4.608 10.24 10.24 10.24h282.88c0-0.256-0.128-0.384-0.128-0.512 17.152 53.76 67.457 92.672 126.848 92.672s109.696-38.912 126.848-92.672c0 0.256-0.128 0.384-0.128 0.512h98.56c5.632 0 10.24-4.608 10.24-10.24v-61.44c0-5.632-4.608-10.24-10.24-10.24h-98.56c0 0.256 0.128 0.384 0.128 0.512-17.152-53.76-67.457-92.672-126.848-92.672s-109.696 38.912-126.848 92.672zM604.16 314.88c-25.45 0-46.080-20.63-46.080-46.080s20.63-46.080 46.080-46.080v0c25.45 0 46.080 20.63 46.080 46.080s-20.63 46.080-46.080 46.080v0zM442.24 587.008l3.072 1.92c0.128 0 0.128 0.128 0.256 0.128l1.536 1.152c0.128 0.128 0.256 0.256 0.384 0.256 1.664 1.28 3.2 2.56 4.608 4.096l0.256 0.256c0.512 0.512 1.024 1.024 1.408 1.536 1.024 1.024 1.92 2.176 2.688 3.328v0.128l1.152 1.536c0.128 0.128 0.256 0.384 0.384 0.512 1.024 1.536 2.048 3.2 2.816 4.992 0.128 0.256 0.256 0.64 0.512 0.896 0.256 0.512 0.384 0.896 0.64 1.408 0.128 0.384 0.384 0.896 0.512 1.28 0.256 0.64 0.512 1.28 0.64 1.92 0.128 0.512 0.384 1.152 0.512 1.664l0.384 1.152 0.384 1.792c0.128 0.256 0.128 0.64 0.256 0.896 0.128 0.896 0.384 1.792 0.512 2.688 0 0.256 0 0.512 0.128 0.768 0.128 0.768 0.128 1.408 0.256 2.176 0 0.256 0 0.512 0.128 0.896 0 1.024 0.128 1.92 0.128 2.944s0 1.92-0.128 2.944c0 0.256 0 0.512-0.128 0.896 0 0.768-0.128 1.536-0.256 2.176 0 0.256 0 0.512-0.128 0.768-0.128 0.896-0.256 1.792-0.512 2.688-0.128 0.256-0.128 0.64-0.256 0.896l-0.384 1.792-0.384 1.152c-0.128 0.512-0.384 1.152-0.512 1.664-0.256 0.64-0.512 1.28-0.64 1.92-0.128 0.384-0.384 0.896-0.512 1.28-0.256 0.512-0.384 0.896-0.64 1.408-0.128 0.256-0.256 0.64-0.512 0.896-0.896 1.664-1.792 3.328-2.816 4.992-0.128 0.128-0.256 0.384-0.384 0.512l-1.152 1.536v0.128c-0.896 1.152-1.792 2.304-2.688 3.328-0.512 0.512-0.896 1.024-1.408 1.536l-0.256 0.256c-1.425 1.384-2.925 2.724-4.483 3.997l-0.125 0.1c-0.128 0.128-0.256 0.256-0.384 0.256l-1.536 1.152c-0.128 0-0.128 0.128-0.256 0.128l-3.072 1.92c-0.256 0.128-0.384 0.256-0.64 0.384-6.528 3.456-13.952 5.504-21.76 5.504s-15.36-2.048-21.76-5.504c-0.256-0.128-0.384-0.256-0.64-0.384l-3.072-1.92c-0.128 0-0.128-0.128-0.256-0.128l-1.536-1.152c-0.128-0.128-0.256-0.256-0.384-0.256-1.664-1.28-3.2-2.56-4.608-4.096l-0.256-0.256c-0.512-0.512-1.024-1.024-1.408-1.536-1.024-1.024-1.92-2.176-2.688-3.328v-0.128l-1.152-1.536c-0.128-0.128-0.256-0.384-0.384-0.512-1.024-1.536-2.048-3.2-2.816-4.992-0.128-0.256-0.256-0.64-0.512-0.896-0.256-0.512-0.384-0.896-0.64-1.408-0.128-0.384-0.384-0.896-0.512-1.28-0.256-0.64-0.512-1.28-0.64-1.92-0.128-0.512-0.384-1.152-0.512-1.664l-0.384-1.152-0.384-1.792c-0.128-0.256-0.128-0.64-0.256-0.896-0.128-0.896-0.384-1.792-0.512-2.688 0-0.256 0-0.512-0.128-0.768-0.128-0.768-0.128-1.408-0.256-2.176 0-0.256 0-0.512-0.128-0.896 0-1.024-0.128-1.92-0.128-2.944s0-1.92 0.128-2.944c0-0.256 0-0.512 0.128-0.896 0-0.768 0.128-1.536 0.256-2.176 0-0.256 0-0.512 0.128-0.768 0.128-0.896 0.256-1.792 0.512-2.688 0.128-0.256 0.128-0.64 0.256-0.896l0.384-1.792 0.384-1.152c0.128-0.512 0.384-1.152 0.512-1.664 0.256-0.64 0.512-1.28 0.64-1.92 0.128-0.384 0.384-0.896 0.512-1.28 0.256-0.512 0.384-0.896 0.64-1.408 0.128-0.256 0.256-0.64 0.512-0.896 0.896-1.664 1.792-3.328 2.816-4.992 0.128-0.128 0.256-0.384 0.384-0.512l1.152-1.536v-0.128c0.896-1.152 1.792-2.304 2.688-3.328 0.512-0.512 0.896-1.024 1.408-1.536l0.256-0.256c1.408-1.408 3.072-2.816 4.608-4.096 0.128-0.128 0.256-0.256 0.384-0.256l1.536-1.152c0.128 0 0.128-0.128 0.256-0.128l3.072-1.92c0.256-0.128 0.384-0.256 0.64-0.384 6.528-3.456 13.952-5.504 21.76-5.504s15.36 2.048 21.76 5.504c0.256 0.128 0.512 0.256 0.64 0.384z" />
|
||||
<glyph unicode="" glyph-name="statistics1" d="M242.692 27.226v606.954c0 24.204-18.621 42.82-40.959 42.82h-122.884c-22.336 0-40.959-20.476-40.959-42.82v-606.954h204.8zM503.346 27.226v867.607c0 24.206-18.617 44.687-40.96 44.687h-122.884c-22.336 0-40.959-20.482-40.959-44.687v-867.607h204.802zM763.999 27.226v383.538c0 24.204-18.615 44.681-40.959 44.681h-122.877c-22.343 0-40.967-20.476-40.967-44.681v-383.538h204.802zM1024.653 27.226v606.954c0 24.204-18.615 42.82-40.959 42.82h-122.877c-22.343 0-40.959-20.476-40.959-42.82v-606.954h204.793z" />
|
||||
<glyph unicode="" glyph-name="asterisk" d="M956.42 291.814l-284.42 156.186 284.42 156.186c23.59 12.954 31.922 42.768 18.464 66.074l-38.96 67.482c-13.456 23.306-43.44 30.998-66.454 17.046l-277.47-168.224 6.95 324.408c0.576 26.906-21.076 49.028-47.99 49.028h-77.92c-26.912 0-48.566-22.122-47.988-49.028l6.948-324.408-277.47 168.222c-23.012 13.952-52.998 6.26-66.454-17.046l-38.96-67.482c-13.456-23.306-5.124-53.12 18.466-66.074l284.418-156.184-284.42-156.186c-23.59-12.954-31.922-42.768-18.464-66.074l38.96-67.482c13.456-23.306 43.442-30.998 66.454-17.046l277.47 168.224-6.95-324.408c-0.576-26.906 21.078-49.028 47.99-49.028h77.922c26.912 0 48.566 22.122 47.99 49.028l-6.952 324.408 277.47-168.222c23.012-13.952 52.998-6.26 66.454 17.046l38.96 67.482c13.456 23.306 5.126 53.118-18.464 66.072z" />
|
||||
<glyph unicode="" glyph-name="app" d="M417.786-56.315c28.674-16.897 51.203-5.633 51.203 28.674v398.871c0 34.306-23.041 68.612-51.203 85.509l-330.259 205.324c-28.674 11.264-51.203 0-51.203-28.674v-398.871c0-34.306 23.041-68.612 51.203-85.509l330.259-205.324zM138.731 787.511c-28.674-16.897-28.674-39.938 0-56.835l325.139-205.324c28.674-16.897 68.612-16.897 96.774-5.633l325.139 165.386c28.674 16.897 28.674 39.938 0 56.835l-342.547 205.324c-23.041 16.897-68.612 16.897-96.774 0l-307.73-159.753zM560.643-27.642c0-34.306 23.041-45.571 51.203-28.674l325.139 165.386c28.674 16.897 51.203 51.203 51.203 85.509v399.383c0 34.306-23.041 45.571-51.203 28.674l-325.139-165.386c-28.674-16.897-51.203-51.203-51.203-85.509v-399.383z" />
|
||||
<glyph unicode="" glyph-name="user" d="M576 253.388v52.78c70.498 39.728 128 138.772 128 237.832 0 159.058 0 288-192 288s-192-128.942-192-288c0-99.060 57.502-198.104 128-237.832v-52.78c-217.102-17.748-384-124.42-384-253.388h896c0 128.968-166.898 235.64-384 253.388z" />
|
||||
<glyph unicode="" glyph-name="question" horiz-adv-x="878" d="M512 164.571v109.714q0 8-5.143 13.143t-13.143 5.143h-109.714q-8 0-13.143-5.143t-5.143-13.143v-109.714q0-8 5.143-13.143t13.143-5.143h109.714q8 0 13.143 5.143t5.143 13.143zM658.286 548.571q0 50.286-31.714 93.143t-79.143 66.286-97.143 23.429q-138.857 0-212-121.714-8.571-13.714 4.571-24l75.429-57.143q4-3.429 10.857-3.429 9.143 0 14.286 6.857 30.286 38.857 49.143 52.571 19.429 13.714 49.143 13.714 27.429 0 48.857-14.857t21.429-33.714q0-21.714-11.429-34.857t-38.857-25.714q-36-16-66-49.429t-30-71.714v-20.571q0-8 5.143-13.143t13.143-5.143h109.714q8 0 13.143 5.143t5.143 13.143q0 10.857 12.286 28.286t31.143 28.286q18.286 10.286 28 16.286t26.286 20 25.429 27.429 16 34.571 7.143 46.286zM877.714 438.857q0-119.429-58.857-220.286t-159.714-159.714-220.286-58.857-220.286 58.857-159.714 159.714-58.857 220.286 58.857 220.286 159.714 159.714 220.286 58.857 220.286-58.857 159.714-159.714 58.857-220.286z" />
|
||||
</font></defs></svg>
|
||||
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 8.1 KiB |
|
After Width: | Height: | Size: 6.4 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<path fill="#adaeaf" d="m8,10.033663l-6.898535,-6.013274l-1.060688,0.972974l7.959223,6.986249l7.959223,-6.986249l-1.060688,-0.972974l-6.898535,6.013274z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 225 B |
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<browserconfig><msapplication><tile><square70x70logo src="/ms-icon-70x70.png"/><square150x150logo src="/ms-icon-150x150.png"/><square310x310logo src="/ms-icon-310x310.png"/><TileColor>#ffffff</TileColor></tile></msapplication></browserconfig>
|
||||
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 4.7 KiB |
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"name": "Openwrt",
|
||||
"icons": [
|
||||
{
|
||||
"src": "\/android-icon-36x36.png",
|
||||
"sizes": "36x36",
|
||||
"type": "image\/png",
|
||||
"density": "0.75"
|
||||
},
|
||||
{
|
||||
"src": "\/android-icon-48x48.png",
|
||||
"sizes": "48x48",
|
||||
"type": "image\/png",
|
||||
"density": "1.0"
|
||||
},
|
||||
{
|
||||
"src": "\/android-icon-72x72.png",
|
||||
"sizes": "72x72",
|
||||
"type": "image\/png",
|
||||
"density": "1.5"
|
||||
},
|
||||
{
|
||||
"src": "\/android-icon-96x96.png",
|
||||
"sizes": "96x96",
|
||||
"type": "image\/png",
|
||||
"density": "2.0"
|
||||
},
|
||||
{
|
||||
"src": "\/android-icon-144x144.png",
|
||||
"sizes": "144x144",
|
||||
"type": "image\/png",
|
||||
"density": "3.0"
|
||||
},
|
||||
{
|
||||
"src": "\/android-icon-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image\/png",
|
||||
"density": "4.0"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
After Width: | Height: | Size: 6.4 KiB |
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<path fill="#888" d="M8,0c-4.355,0-7.898,3.481-7.998,7.812,0.092-3.779,2.966-6.812,6.498-6.812,3.59,0,6.5,3.134,6.5,7,0,0.828,0.672,1.5,1.5,1.5s1.5-0.672,1.5-1.5c0-4.418-3.582-8-8-8zM8,16c4.355,0,7.898-3.481,7.998-7.812-0.092,3.779-2.966,6.812-6.498,6.812-3.59,0-6.5-3.134-6.5-7,0-0.828-0.672-1.5-1.5-1.5s-1.5,0.672-1.5,1.5c0,4.418,3.582,8,8,8z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 417 B |
@@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 27.5.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="图层_1" xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 256 256"
|
||||
style="enable-background:new 0 0 256 256;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill-rule:evenodd;clip-rule:evenodd;fill:url(#svg_2_00000009581766544743910510000007087157279682564742_);}
|
||||
.st1{fill-rule:evenodd;clip-rule:evenodd;fill:url(#svg_3_00000013155245276689480680000010334395393893521599_);}
|
||||
.st2{fill:#FFFFFF;}
|
||||
</style>
|
||||
<g>
|
||||
<g id="svg_1">
|
||||
|
||||
<linearGradient id="svg_2_00000043442590260727270070000016472210641679865270_" gradientUnits="userSpaceOnUse" x1="11.1563" y1="247.3437" x2="245.4437" y2="13.0563" gradientTransform="matrix(1 0 0 -1 0 258)">
|
||||
<stop offset="0" style="stop-color:#5E72E4"/>
|
||||
<stop offset="1" style="stop-color:#778AFF"/>
|
||||
</linearGradient>
|
||||
|
||||
<path id="svg_2" style="fill-rule:evenodd;clip-rule:evenodd;fill:url(#svg_2_00000043442590260727270070000016472210641679865270_);" d="
|
||||
M36.4,0.2h183.8c19.7,0,35.7,16,35.7,35.7v183.8c0,19.7-16,35.7-35.7,35.7H36.4c-19.7,0-35.7-16-35.7-35.7V35.9
|
||||
C0.7,16.2,16.7,0.2,36.4,0.2z"/>
|
||||
|
||||
<linearGradient id="svg_3_00000010280352489557108120000000938545297310085033_" gradientUnits="userSpaceOnUse" x1="0.7" y1="257.8" x2="0.7" y2="257.8" gradientTransform="matrix(1 0 0 -1 0 258)">
|
||||
<stop offset="0" style="stop-color:#5E72E4"/>
|
||||
<stop offset="1" style="stop-color:#778AFF"/>
|
||||
</linearGradient>
|
||||
|
||||
<path id="svg_3" style="fill-rule:evenodd;clip-rule:evenodd;fill:url(#svg_3_00000010280352489557108120000000938545297310085033_);" d="
|
||||
M0.7,0.2"/>
|
||||
</g>
|
||||
<path id="svg_4" class="st2" d="M128.3,45.4c-46.7,0-84.4,37.8-84.4,84.4c0,32.2,18.1,60.2,44.6,74.4c6.8,3.7,15.3-0.2,17.2-7.7
|
||||
l4.3-17.6c1.5-6.2-1-12.6-6.1-16.4c-10-7.4-16.4-19.3-16.4-32.7c0-22.5,18.3-40.7,40.7-40.7c22.5,0,40.7,18.3,40.7,40.7
|
||||
c0,13.4-6.4,25.2-16.4,32.7c-5.1,3.8-7.6,10.2-6.1,16.5l4.4,17.6c1.9,7.5,10.3,11.4,17.2,7.7c26.6-14.2,44.6-42.2,44.6-74.5
|
||||
C212.8,83.3,174.9,45.4,128.3,45.4L128.3,45.4z"/>
|
||||
</g>
|
||||
<circle class="st2" cx="128.3" cy="131.6" r="18.3"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 156 KiB |
|
After Width: | Height: | Size: 938 B |
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1024 1024">
|
||||
<path fill="#fff" d="M484.430769 51.2 236.307692 354.461538H118.153846c-43.323077 0-78.769231 35.446154-78.769231 78.769231v157.538462c0 43.323077 35.446154 78.769231 78.769231 78.769231h118.153846L484.430769 972.8c25.6 25.6 66.953846 7.876923 66.953846-27.569231V78.769231c0-35.446154-43.323077-53.169231-66.953846-27.569231zm354.461539 120.123077c-7.876923-7.876923-19.692308-7.876923-27.569231 0l-27.569231 27.569231c-7.876923 7.876923-7.876923 21.661538 0 27.56923C858.584615 299.323077 905.846154 399.753846 905.846154 512c0 112.246154-47.261538 212.676923-122.092308 285.538462-7.876923 7.876923-7.876923 19.692308 0 27.56923l27.569231 27.569231c7.876923 7.876923 19.692308 7.876923 27.569231 0C927.507692 768 984.615385 645.907692 984.615385 512s-55.138462-256-145.723077-340.676923zM714.830769 297.353846c-7.876923-7.876923-19.692308-7.876923-27.569231 0l-27.56923 27.569231c-7.876923 7.876923-7.876923 19.692308 0 27.569231C703.015385 391.876923 728.615385 448.984616 728.615385 512c0 63.015385-27.569231 120.123077-70.892308 159.507692-7.876923 7.876923-7.876923 19.692308 0 27.569231l27.569231 27.569231c7.876923 7.876923 19.692308 7.876923 27.56923 0 57.107692-53.169231 94.523077-129.969231 94.523077-216.615385 0-82.707692-35.446154-159.507692-92.553846-212.676923z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1024 1024">
|
||||
<path fill="#fff" d="M484.430769 51.2 236.307692 354.461538H118.153846c-43.323077 0-78.769231 35.446154-78.769231 78.769231v157.538462c0 43.323077 35.446154 78.769231 78.769231 78.769231h118.153846L484.430769 972.8c25.6 25.6 66.953846 7.876923 66.953846-27.569231V78.769231c0-35.446154-43.323077-53.169231-66.953846-27.569231zM882.215385 512l96.492307-96.492308c7.876923-7.876923 7.876923-19.692308 0-27.56923l-27.56923-27.569231c-7.876923-7.876923-19.692308-7.876923-27.569231 0l-96.492308 96.492307-96.492308-96.492307c-7.876923-7.876923-19.692308-7.876923-27.56923 0l-27.569231 27.569231c-7.876923 7.876923-7.876923 19.692308 0 27.56923L771.938462 512l-96.492308 96.492308c-7.876923 7.876923-7.876923 19.692308 0 27.56923l27.569231 27.569231c7.876923 7.876923 19.692308 7.876923 27.56923 0l96.492308-96.492307 96.492308 96.492307c7.876923 7.876923 19.692308 7.876923 27.569231 0l27.56923-27.569231c7.876923-7.876923 7.876923-19.692308 0-27.56923L882.215385 512z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
2
ipk-source/luci-theme-argon/root/www/luci-static/argon/js/jquery.min.js
vendored
Normal file
3
ipk-source/luci-theme-argon/root/www/luci-static/argon/js/polyfill.min.js
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
/* Disable minification (remove `.min` from URL path) for more info */
|
||||
|
||||
(function(undefined) {}).call('object' === typeof window && window || 'object' === typeof self && self || 'object' === typeof global && global || {});
|
||||
@@ -0,0 +1,158 @@
|
||||
'use strict';
|
||||
'require baseclass';
|
||||
'require ui';
|
||||
|
||||
return baseclass.extend({
|
||||
__init__: function () {
|
||||
ui.menu.load().then(L.bind(this.render, this));
|
||||
},
|
||||
|
||||
render: function (tree) {
|
||||
var node = tree,
|
||||
url = '',
|
||||
children = ui.menu.getChildren(tree);
|
||||
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var isActive = (L.env.requestpath.length ? children[i].name == L.env.requestpath[0] : i == 0);
|
||||
|
||||
if (isActive)
|
||||
this.renderMainMenu(children[i], children[i].name);
|
||||
}
|
||||
|
||||
if (L.env.dispatchpath.length >= 3) {
|
||||
for (var i = 0; i < 3 && node; i++) {
|
||||
node = node.children[L.env.dispatchpath[i]];
|
||||
url = url + (url ? '/' : '') + L.env.dispatchpath[i];
|
||||
}
|
||||
|
||||
if (node)
|
||||
this.renderTabMenu(node, url);
|
||||
}
|
||||
|
||||
document.querySelector('a.showSide')
|
||||
.addEventListener('click', ui.createHandlerFn(this, 'handleSidebarToggle'));
|
||||
document.querySelector('.darkMask')
|
||||
.addEventListener('click', ui.createHandlerFn(this, 'handleSidebarToggle'));
|
||||
},
|
||||
|
||||
handleMenuExpand: function (ev) {
|
||||
var a = ev.target, slide = a.parentNode, slide_menu = a.nextElementSibling;
|
||||
var collapse = false;
|
||||
|
||||
document.querySelectorAll('.main .main-left .nav > li >ul.active').forEach(function (ul) {
|
||||
$(ul).stop(true).slideUp("fast", function () {
|
||||
ul.classList.remove('active');
|
||||
ul.previousElementSibling.classList.remove('active');
|
||||
});
|
||||
if (!collapse && ul === slide_menu) {
|
||||
collapse = true;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
if (!slide_menu)
|
||||
return;
|
||||
|
||||
|
||||
if (!collapse) {
|
||||
$(slide).find(".slide-menu").slideDown("fast",function(){
|
||||
slide_menu.classList.add('active');
|
||||
a.classList.add('active');
|
||||
});
|
||||
a.blur();
|
||||
}
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
},
|
||||
|
||||
renderMainMenu: function (tree, url, level) {
|
||||
var l = (level || 0) + 1,
|
||||
ul = E('ul', { 'class': level ? 'slide-menu' : 'nav' }),
|
||||
children = ui.menu.getChildren(tree);
|
||||
|
||||
if (children.length == 0 || l > 2)
|
||||
return E([]);
|
||||
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var isActive = ((L.env.dispatchpath[l] == children[i].name) && (L.env.dispatchpath[l - 1] == tree.name)),
|
||||
submenu = this.renderMainMenu(children[i], url + '/' + children[i].name, l),
|
||||
hasChildren = submenu.children.length,
|
||||
slideClass = hasChildren ? 'slide' : null,
|
||||
menuClass = hasChildren ? 'menu' : 'food';
|
||||
if (isActive) {
|
||||
ul.classList.add('active');
|
||||
slideClass += " active";
|
||||
menuClass += " active";
|
||||
}
|
||||
|
||||
ul.appendChild(E('li', { 'class': slideClass }, [
|
||||
E('a', {
|
||||
'href': L.url(url, children[i].name),
|
||||
'click': (l == 1) ? ui.createHandlerFn(this, 'handleMenuExpand') : null,
|
||||
'class': menuClass,
|
||||
'data-title': hasChildren ? children[i].title.replace(" ", "_") : children[i].title.replace(" ", "_"),
|
||||
}, [_(children[i].title)]),
|
||||
submenu
|
||||
]));
|
||||
}
|
||||
|
||||
if (l == 1) {
|
||||
document.querySelector('#mainmenu').appendChild(ul);
|
||||
document.querySelector('#mainmenu').style.display = '';
|
||||
|
||||
}
|
||||
return ul;
|
||||
},
|
||||
|
||||
renderTabMenu: function (tree, url, level) {
|
||||
var container = document.querySelector('#tabmenu'),
|
||||
l = (level || 0) + 1,
|
||||
ul = E('ul', { 'class': 'tabs' }),
|
||||
children = ui.menu.getChildren(tree),
|
||||
activeNode = null;
|
||||
|
||||
if (children.length == 0)
|
||||
return E([]);
|
||||
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var isActive = (L.env.dispatchpath[l + 2] == children[i].name),
|
||||
activeClass = isActive ? ' active' : '',
|
||||
className = 'tabmenu-item-%s %s'.format(children[i].name, activeClass);
|
||||
|
||||
ul.appendChild(E('li', { 'class': className }, [
|
||||
E('a', { 'href': L.url(url, children[i].name) }, [_(children[i].title)])
|
||||
]));
|
||||
|
||||
if (isActive)
|
||||
activeNode = children[i];
|
||||
}
|
||||
|
||||
container.appendChild(ul);
|
||||
container.style.display = '';
|
||||
|
||||
if (activeNode)
|
||||
container.appendChild(this.renderTabMenu(activeNode, url + '/' + activeNode.name, l));
|
||||
|
||||
return ul;
|
||||
},
|
||||
|
||||
handleSidebarToggle: function (ev) {
|
||||
var showside = document.querySelector('a.showSide'),
|
||||
sidebar = document.querySelector('#mainmenu'),
|
||||
darkmask = document.querySelector('.darkMask'),
|
||||
scrollbar = document.querySelector('.main-right');
|
||||
|
||||
if (showside.classList.contains('active')) {
|
||||
showside.classList.remove('active');
|
||||
sidebar.classList.remove('active');
|
||||
scrollbar.classList.remove('active');
|
||||
darkmask.classList.remove('active');
|
||||
}
|
||||
else {
|
||||
showside.classList.add('active');
|
||||
sidebar.classList.add('active');
|
||||
scrollbar.classList.add('active');
|
||||
darkmask.classList.add('active');
|
||||
}
|
||||
}
|
||||
});
|
||||
12
ipk-source/ucode-mod-lua_aarch64_cortex-a53/CONTROL/control
Normal file
@@ -0,0 +1,12 @@
|
||||
Package: ucode-mod-lua
|
||||
Version: 1
|
||||
Depends: libc, libucode20230711, liblua5.1.5
|
||||
Source: feeds/luci/contrib/package/ucode-mod-lua
|
||||
SourceName: ucode-mod-lua
|
||||
License: ISC
|
||||
Section: utils
|
||||
SourceDateEpoch: 1738611490
|
||||
Maintainer: Jo-Philipp Wich <jo@mein.io>
|
||||
Architecture: aarch64_cortex-a53
|
||||
Installed-Size: 71680
|
||||
Description: ucode to Lua bridge library
|
||||
5
ipk-source/ucode-mod-lua_aarch64_cortex-a53/CONTROL/postinst
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
[ "${IPKG_NO_SCRIPT}" = "1" ] && exit 0
|
||||
[ -s ${IPKG_INSTROOT}/lib/functions.sh ] || exit 0
|
||||
. ${IPKG_INSTROOT}/lib/functions.sh
|
||||
default_postinst $0 $@
|
||||
4
ipk-source/ucode-mod-lua_aarch64_cortex-a53/CONTROL/prerm
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
[ -s ${IPKG_INSTROOT}/lib/functions.sh ] || exit 0
|
||||
. ${IPKG_INSTROOT}/lib/functions.sh
|
||||
default_prerm $0 $@
|
||||
74
ipk-source/ucode-mod-lua_aarch64_cortex-a53/build-ipk
Executable file
@@ -0,0 +1,74 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Script for building OpenWRT .ipk packages using tar by iamromulan
|
||||
# Works with SDXPPINN OpenWRT - iamromulan
|
||||
# This script accepts an optional path to the directory containing the `CONTROL` and `root` directories.
|
||||
# Usage: ./build-ipk.sh [path]
|
||||
# If no path is provided, the script will look in the current directory for `CONTROL` and `root` directories.
|
||||
# This will spit out an ipk in the current directory
|
||||
|
||||
# Check if the script is run as root. If not, rerun with sudo.
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo "Script is not running as root. Re-executing with sudo..."
|
||||
exec sudo "$0" "$@"
|
||||
fi
|
||||
|
||||
# Set the default build path to the current directory
|
||||
build_path="."
|
||||
|
||||
# Check if a path is provided as the first argument
|
||||
if [ "$1" ]; then
|
||||
build_path="$1"
|
||||
fi
|
||||
|
||||
# Check if the required directories are present in the specified path
|
||||
if [ ! -d "${build_path}/CONTROL" ] || [ ! -d "${build_path}/root" ]; then
|
||||
echo "Error: CONTROL and root directories must be present in the specified path (${build_path})."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Extract values from the CONTROL/control file in the specified path
|
||||
pkgname=$(grep -i '^Package:' "${build_path}/CONTROL/control" | awk '{print $2}')
|
||||
version=$(grep -i '^Version:' "${build_path}/CONTROL/control" | awk '{print $2}')
|
||||
architecture=$(grep -i '^Architecture:' "${build_path}/CONTROL/control" | awk '{print $2}')
|
||||
|
||||
# Check if values are extracted correctly
|
||||
if [ -z "$pkgname" ] || [ -z "$version" ] || [ -z "$architecture" ]; then
|
||||
echo "Error: Failed to extract Package, Version, or Architecture from ${build_path}/CONTROL/control."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Set the final IPK name based on the extracted values
|
||||
ipkname="${pkgname}_${version}_${architecture}.ipk"
|
||||
|
||||
# Ensure all CONTROL scripts are executable
|
||||
echo "Setting permissions for CONTROL scripts..."
|
||||
chmod +x "${build_path}/CONTROL"/*
|
||||
|
||||
# Set ownership for CONTROL and root files
|
||||
echo "Setting ownership for all package files..."
|
||||
chown -R root:root "${build_path}/CONTROL"/*
|
||||
chown -R root:root "${build_path}/root"/*
|
||||
|
||||
# Create control.tar.gz from the CONTROL directory
|
||||
echo "Creating control.tar.gz..."
|
||||
tar -czvf control.tar.gz -C "${build_path}/CONTROL" .
|
||||
|
||||
# Create data.tar.gz from the root directory
|
||||
echo "Creating data.tar.gz..."
|
||||
tar -czvf data.tar.gz -C "${build_path}/root" .
|
||||
|
||||
# Create debian-binary file (must contain exactly "2.0" without a newline)
|
||||
echo -n "2.0" > debian-binary
|
||||
chown -R root:root debian-binary
|
||||
|
||||
# Combine the components into the final .ipk file using tar
|
||||
echo "Packaging ${ipkname}..."
|
||||
tar -czvf "$ipkname" debian-binary control.tar.gz data.tar.gz
|
||||
|
||||
# Clean up intermediate files
|
||||
echo "Cleaning up temporary files..."
|
||||
rm -f control.tar.gz data.tar.gz debian-binary
|
||||
|
||||
echo "IPK package ${ipkname} created successfully using tar."
|
||||
|
||||