From 8836ce80c2bf34d67c21f29a7a5529055862276e Mon Sep 17 00:00:00 2001 From: suyuan <175338101@qq.com> Date: Fri, 23 Jun 2023 02:14:05 +0800 Subject: [PATCH] update app --- 6in4/Makefile | 5 +- 6in4/files/6in4.sh | 32 +- cryptodev-linux/Makefile | 0 https-dns-proxy/Makefile | 24 +- https-dns-proxy/files/README.md | 0 https-dns-proxy/files/https-dns-proxy.config | 9 +- .../files/https-dns-proxy.defaults | 3 + .../files/https-dns-proxy.hotplug.iface | 0 https-dns-proxy/files/https-dns-proxy.init | 419 ++-- ...tch => 010-cmakelists-remove-cflags.patch} | 8 +- .../020-src-options.c-add-version.patch | 11 + https-dns-proxy/test.sh | 2 +- luci-app-adguardhome/Makefile | 57 - .../luasrc/controller/AdGuardHome.lua | 130 -- .../luasrc/model/cbi/AdGuardHome/base.lua | 304 --- .../luasrc/model/cbi/AdGuardHome/log.lua | 16 - .../luasrc/model/cbi/AdGuardHome/manual.lua | 97 - .../view/AdGuardHome/AdGuardHome_check.htm | 78 - .../view/AdGuardHome/AdGuardHome_chpass.htm | 49 - .../view/AdGuardHome/AdGuardHome_status.htm | 27 - .../luasrc/view/AdGuardHome/log.htm | 111 - .../luasrc/view/AdGuardHome/yamleditor.htm | 39 - luci-app-adguardhome/po/zh-cn | 1 - .../po/zh_Hans/adguardhome.po | 408 ---- .../root/etc/config/AdGuardHome | 11 - .../root/etc/init.d/AdGuardHome | 642 ------ .../root/etc/uci-defaults/40_luci-AdGuardHome | 15 - .../AdGuardHome/AdGuardHome_template.yaml | 131 -- .../root/usr/share/AdGuardHome/addhost.sh | 35 - .../root/usr/share/AdGuardHome/firewall.start | 8 - .../root/usr/share/AdGuardHome/getsyslog.sh | 20 - .../root/usr/share/AdGuardHome/gfw2adg.sh | 89 - .../root/usr/share/AdGuardHome/links.txt | 3 - .../root/usr/share/AdGuardHome/tailto.sh | 5 - .../root/usr/share/AdGuardHome/update_core.sh | 236 -- .../root/usr/share/AdGuardHome/waitnet.sh | 35 - .../root/usr/share/AdGuardHome/watchconfig.sh | 13 - .../rpcd/acl.d/luci-app-adguardhome.json | 11 - .../codemirror/addon/fold/foldcode.js | 1 - .../codemirror/addon/fold/foldgutter.css | 1 - .../codemirror/addon/fold/foldgutter.js | 1 - .../codemirror/addon/fold/indent-fold.js | 1 - .../resources/codemirror/lib/codemirror.css | 1 - .../resources/codemirror/lib/codemirror.js | 1 - .../resources/codemirror/mode/yaml/yaml.js | 1 - .../resources/codemirror/theme/dracula.css | 1 - .../luci-static/resources/twin-bcrypt.min.js | 7 - luci-app-diskman/Makefile | 51 - .../luasrc/controller/diskman.lua | 155 -- .../luasrc/model/cbi/diskman/btrfs.lua | 210 -- .../luasrc/model/cbi/diskman/disks.lua | 327 --- .../luasrc/model/cbi/diskman/partition.lua | 366 --- luci-app-diskman/luasrc/model/diskman.lua | 738 ------ .../view/diskman/cbi/disabled_button.htm | 7 - .../luasrc/view/diskman/cbi/format_button.htm | 7 - .../luasrc/view/diskman/cbi/inlinebutton.htm | 7 - .../luasrc/view/diskman/cbi/xnullsection.htm | 37 - .../luasrc/view/diskman/cbi/xsimpleform.htm | 88 - .../luasrc/view/diskman/disk_info.htm | 108 - .../luasrc/view/diskman/partition_info.htm | 129 -- .../luasrc/view/diskman/smart_detail.htm | 79 - luci-app-diskman/po/zh-cn/diskman.po | 239 -- luci-app-diskman/po/zh_Hans | 1 - luci-app-dockerman/Makefile | 21 - luci-app-dockerman/depends.lst | 1 - .../resources/dockerman/containers.svg | 7 - .../resources/dockerman/file-icon.png | Bin 1098 -> 0 bytes .../resources/dockerman/file-manager.css | 91 - .../resources/dockerman/folder-icon.png | Bin 1292 -> 0 bytes .../resources/dockerman/images.svg | 9 - .../resources/dockerman/link-icon.png | Bin 1622 -> 0 bytes .../resources/dockerman/networks.svg | 12 - .../resources/dockerman/tar.min.js | 185 -- .../resources/dockerman/volumes.svg | 6 - .../luasrc/controller/dockerman.lua | 614 ----- .../model/cbi/dockerman/configuration.lua | 152 -- .../luasrc/model/cbi/dockerman/container.lua | 810 ------- .../luasrc/model/cbi/dockerman/containers.lua | 284 --- .../luasrc/model/cbi/dockerman/images.lua | 284 --- .../luasrc/model/cbi/dockerman/networks.lua | 159 -- .../model/cbi/dockerman/newcontainer.lua | 923 -------- .../luasrc/model/cbi/dockerman/newnetwork.lua | 258 --- .../luasrc/model/cbi/dockerman/overview.lua | 151 -- .../luasrc/model/cbi/dockerman/volumes.lua | 142 -- luci-app-dockerman/luasrc/model/docker.lua | 507 ----- .../luasrc/view/dockerman/apply_widget.htm | 147 -- .../view/dockerman/cbi/inlinebutton.htm | 7 - .../luasrc/view/dockerman/cbi/inlinevalue.htm | 33 - .../view/dockerman/cbi/namedsection.htm | 9 - .../luasrc/view/dockerman/cbi/xfvalue.htm | 10 - .../luasrc/view/dockerman/container.htm | 28 - .../view/dockerman/container_console.htm | 6 - .../view/dockerman/container_file_manager.htm | 332 --- .../luasrc/view/dockerman/container_stats.htm | 81 - .../dockerman/containers_running_stats.htm | 91 - .../luasrc/view/dockerman/images_import.htm | 104 - .../luasrc/view/dockerman/images_load.htm | 40 - .../luasrc/view/dockerman/logs.htm | 13 - .../view/dockerman/newcontainer_resolve.htm | 102 - .../luasrc/view/dockerman/overview.htm | 197 -- .../luasrc/view/dockerman/volume_size.htm | 21 - luci-app-dockerman/po/templates/dockerman.pot | 1002 -------- luci-app-dockerman/po/zh-cn/dockerman.po | 1094 --------- luci-app-dockerman/po/zh_Hans | 1 - luci-app-dockerman/postinst | 14 - luci-app-dockerman/root/etc/init.d/dockerman | 131 -- .../root/etc/uci-defaults/luci-app-dockerman | 36 - .../share/rpcd/acl.d/luci-app-dockerman.json | 11 - luci-app-snmpd/Makefile | 18 +- .../luci-static/resources/view/snmpd/snmpd.js | 64 + luci-app-snmpd/luasrc/controller/snmpd.lua | 8 - luci-app-snmpd/luasrc/model/cbi/snmpd.lua | 141 -- luci-app-snmpd/luasrc/view/snmpd.htm | 132 -- luci-app-snmpd/po/de/snmpd.po | 184 -- luci-app-snmpd/po/fr/snmpd.po | 184 -- luci-app-snmpd/po/it/snmpd.po | 184 -- luci-app-snmpd/po/oc/snmpd.po | 184 -- luci-app-snmpd/po/templates/snmpd.pot | 176 +- luci-app-snmpd/po/zh_Hans/snmpd.po | 184 -- luci-app-snmpd/root/etc/config/snmpd | 91 - luci-app-snmpd/root/etc/init.d/snmpd | 349 --- .../root/etc/uci-defaults/4400-snmpd | 19 - .../usr/share/luci/menu.d/luci-app-snmpd.json | 12 +- .../usr/share/rpcd/acl.d/luci-app-snmpd.json | 18 +- luci-mod-dashboard/Makefile | 3 - .../resources/view/dashboard/css/custom.css | 31 +- .../view/dashboard/icons/devices.svg | 0 .../view/dashboard/icons/internet.svg | 0 .../view/dashboard/icons/not-internet.svg | 0 .../resources/view/dashboard/icons/router.svg | 0 .../view/dashboard/icons/wireless.svg | 0 .../view/dashboard/include/10_router.js | 222 +- .../view/dashboard/include/20_lan.js | 12 +- .../view/dashboard/include/30_wifi.js | 38 +- .../resources/view/dashboard/index.js | 0 luci-mod-dashboard/po/ar/dashboard.po | 215 ++ luci-mod-dashboard/po/bg/dashboard.po | 222 ++ luci-mod-dashboard/po/bn_BD/dashboard.po | 219 ++ luci-mod-dashboard/po/ca/dashboard.po | 219 ++ luci-mod-dashboard/po/cs/dashboard.po | 222 ++ luci-mod-dashboard/po/da/dashboard.po | 220 ++ luci-mod-dashboard/po/de/dashboard.po | 222 ++ luci-mod-dashboard/po/el/dashboard.po | 222 ++ luci-mod-dashboard/po/en/dashboard.po | 222 ++ luci-mod-dashboard/po/es/dashboard.po | 223 ++ luci-mod-dashboard/po/fi/dashboard.po | 222 ++ luci-mod-dashboard/po/fr/dashboard.po | 197 +- luci-mod-dashboard/po/he/dashboard.po | 216 ++ luci-mod-dashboard/po/hi/dashboard.po | 215 ++ luci-mod-dashboard/po/hu/dashboard.po | 223 ++ luci-mod-dashboard/po/id/dashboard.po | 220 ++ luci-mod-dashboard/po/it/dashboard.po | 222 ++ luci-mod-dashboard/po/ja/dashboard.po | 222 ++ luci-mod-dashboard/po/ko/dashboard.po | 219 ++ luci-mod-dashboard/po/mr/dashboard.po | 215 ++ luci-mod-dashboard/po/ms/dashboard.po | 215 ++ luci-mod-dashboard/po/nb_NO/dashboard.po | 230 ++ luci-mod-dashboard/po/nl/dashboard.po | 219 ++ luci-mod-dashboard/po/pl/dashboard.po | 223 ++ luci-mod-dashboard/po/pt/dashboard.po | 222 ++ luci-mod-dashboard/po/pt_BR/dashboard.po | 222 ++ luci-mod-dashboard/po/ro/dashboard.po | 223 ++ luci-mod-dashboard/po/ru/dashboard.po | 225 +- luci-mod-dashboard/po/sk/dashboard.po | 219 ++ luci-mod-dashboard/po/sv/dashboard.po | 222 ++ luci-mod-dashboard/po/templates/dashboard.pot | 156 +- luci-mod-dashboard/po/tr/dashboard.po | 222 ++ luci-mod-dashboard/po/uk/dashboard.po | 223 ++ luci-mod-dashboard/po/vi/dashboard.po | 219 ++ luci-mod-dashboard/po/zh_Hans/dashboard.po | 215 +- luci-mod-dashboard/po/zh_Hant/dashboard.po | 220 ++ .../share/luci/menu.d/luci-mod-dashboard.json | 0 .../share/rpcd/acl.d/luci-mod-dashboard.json | 0 luci-mod-network/Makefile | 4 +- .../luci-static/resources/tools/network.js | 202 +- .../resources/view/network/dhcp.js | 773 +++++-- .../resources/view/network/diagnostics.js | 64 +- .../resources/view/network/hosts.js | 50 - .../resources/view/network/interfaces.js | 128 +- .../resources/view/network/routes.js | 228 +- .../resources/view/network/switch.js | 26 +- .../resources/view/network/wireless.js | 199 +- .../share/luci/menu.d/luci-mod-network.json | 46 +- .../share/rpcd/acl.d/luci-mod-network.json | 7 +- luci-proto-mbim/Makefile | 0 .../luci-static/resources/protocol/mbim.js | 80 +- luci-theme-ezengreen/Makefile | 16 - .../luci-static/ezengreen/1omr-logo-apple.png | Bin 8175 -> 0 bytes .../htdocs/luci-static/ezengreen/cascade.css | 2027 ----------------- .../htdocs/luci-static/ezengreen/favicon.png | Bin 8175 -> 0 bytes .../htdocs/luci-static/ezengreen/html5.js | 3 - .../htdocs/luci-static/ezengreen/mobile.css | 61 - .../resources/ezengreen/images/cascade.css | 2027 ----------------- .../resources/ezengreen/images/ezenlink.png | Bin 553 -> 0 bytes .../resources/ezengreen/images/favicon.ico | Bin 4286 -> 0 bytes .../resources/ezengreen/images/footer.png | Bin 836 -> 0 bytes .../resources/ezengreen/images/mobile.css | 61 - .../resources/ezengreen/images/omr-logo.png | Bin 19149 -> 0 bytes .../ezengreen/images/outdoorrouter.png | Bin 3815 -> 0 bytes .../luci-static/resources/menu-ezengreen.js | 118 - .../luasrc/view/themes/ezengreen/footer.htm | 19 - .../luasrc/view/themes/ezengreen/header.htm | 90 - .../etc/uci-defaults/luci-theme-ezengreen | 10 - luci-theme-openwrt-2020/Makefile | 8 + .../GalanoGrotesqueW00-Regular.woff2 | Bin .../luci-static/openwrt2020/cascade.css | 200 +- .../luci-static/openwrt2020/favicon.png | Bin 535 -> 0 bytes .../htdocs/luci-static/openwrt2020/logo.png | Bin 0 -> 3896 bytes .../htdocs/luci-static/openwrt2020/logo.svg | 7 + .../luci-static/openwrt2020/omr-logo.png | Bin 50790 -> 0 bytes .../luci-static/openwrt2020/spinner.svg | 0 .../luci-static/resources/menu-openwrt2020.js | 0 .../luasrc/view/themes/openwrt2020/header.htm | 63 - .../uci-defaults/30_luci-theme-openwrt-2020 | 1 + .../template/themes/openwrt2020/footer.ut} | 7 +- .../template/themes/openwrt2020/header.ut | 72 + msmtp/Makefile | 9 +- net-tools/Makefile | 14 +- net-tools/patches/mptcp-support.patch | 338 --- netifd/Makefile | 13 +- netifd/files/etc/hotplug.d/iface/00-netstate | 0 netifd/files/etc/init.d/packet_steering | 18 + .../etc/uci-defaults/14_migrate-dhcp-release | 0 netifd/files/etc/udhcpc.user | 0 netifd/files/lib/netifd/dhcp.script | 4 +- netifd/files/lib/netifd/proto/dhcp.sh | 9 +- .../libexec/network/packet-steering.sh} | 7 +- netmaker-openwrt/LICENSE | 8 - netmaker-openwrt/README.md | 111 - netmaker-openwrt/netmaker/Makefile | 93 - .../netmaker/root/etc/init.d/netclient | 42 - netmaker-openwrt/scripts/build_ipk.sh | 177 -- nginx/Config.in | 247 -- nginx/Config_ssl.in | 239 -- nginx/Makefile | 532 ----- .../files-luci-support/60_nginx-luci-support | 28 - .../70_nginx-luci-support-ssl | 48 - nginx/files-luci-support/luci_nginx.conf | 51 - nginx/files-luci-support/luci_nginx_ssl.conf | 66 - nginx/files-luci-support/luci_uwsgi.conf | 20 - nginx/files/nginx.init | 17 - .../100-no_by_lua_block.patch | 195 -- nginx/patches/101-feature_test_fix.patch | 116 - nginx/patches/102-sizeof_test_fix.patch | 27 - nginx/patches/103-sys_nerr.patch | 12 - nginx/patches/200-config.patch | 18 - .../patches/201-ignore-invalid-options.patch | 12 - nginx/patches/300-max-processes.patch | 11 - protobuf/Makefile | 8 +- protobuf/patches/010-rpath.patch | 24 + serdisplib/Makefile | 83 +- .../patches/002-allow-1bpp-framebuffer.patch | 21 + serdisplib/patches/010-cross-compile.patch | 101 + speedtestcpp/Makefile | 72 +- upx/Makefile | 66 - 255 files changed, 9752 insertions(+), 23582 deletions(-) mode change 100755 => 100644 6in4/Makefile mode change 100755 => 100644 cryptodev-linux/Makefile mode change 100755 => 100644 https-dns-proxy/Makefile mode change 100755 => 100644 https-dns-proxy/files/README.md mode change 100755 => 100644 https-dns-proxy/files/https-dns-proxy.config create mode 100644 https-dns-proxy/files/https-dns-proxy.defaults mode change 100755 => 100644 https-dns-proxy/files/https-dns-proxy.hotplug.iface rename https-dns-proxy/patches/{010-fix-cmakelists.patch => 010-cmakelists-remove-cflags.patch} (56%) mode change 100755 => 100644 create mode 100644 https-dns-proxy/patches/020-src-options.c-add-version.patch mode change 100755 => 100644 https-dns-proxy/test.sh delete mode 100755 luci-app-adguardhome/Makefile delete mode 100755 luci-app-adguardhome/luasrc/controller/AdGuardHome.lua delete mode 100755 luci-app-adguardhome/luasrc/model/cbi/AdGuardHome/base.lua delete mode 100755 luci-app-adguardhome/luasrc/model/cbi/AdGuardHome/log.lua delete mode 100755 luci-app-adguardhome/luasrc/model/cbi/AdGuardHome/manual.lua delete mode 100755 luci-app-adguardhome/luasrc/view/AdGuardHome/AdGuardHome_check.htm delete mode 100755 luci-app-adguardhome/luasrc/view/AdGuardHome/AdGuardHome_chpass.htm delete mode 100755 luci-app-adguardhome/luasrc/view/AdGuardHome/AdGuardHome_status.htm delete mode 100755 luci-app-adguardhome/luasrc/view/AdGuardHome/log.htm delete mode 100755 luci-app-adguardhome/luasrc/view/AdGuardHome/yamleditor.htm delete mode 100755 luci-app-adguardhome/po/zh-cn delete mode 100755 luci-app-adguardhome/po/zh_Hans/adguardhome.po delete mode 100755 luci-app-adguardhome/root/etc/config/AdGuardHome delete mode 100755 luci-app-adguardhome/root/etc/init.d/AdGuardHome delete mode 100755 luci-app-adguardhome/root/etc/uci-defaults/40_luci-AdGuardHome delete mode 100755 luci-app-adguardhome/root/usr/share/AdGuardHome/AdGuardHome_template.yaml delete mode 100755 luci-app-adguardhome/root/usr/share/AdGuardHome/addhost.sh delete mode 100755 luci-app-adguardhome/root/usr/share/AdGuardHome/firewall.start delete mode 100755 luci-app-adguardhome/root/usr/share/AdGuardHome/getsyslog.sh delete mode 100755 luci-app-adguardhome/root/usr/share/AdGuardHome/gfw2adg.sh delete mode 100755 luci-app-adguardhome/root/usr/share/AdGuardHome/links.txt delete mode 100755 luci-app-adguardhome/root/usr/share/AdGuardHome/tailto.sh delete mode 100755 luci-app-adguardhome/root/usr/share/AdGuardHome/update_core.sh delete mode 100755 luci-app-adguardhome/root/usr/share/AdGuardHome/waitnet.sh delete mode 100755 luci-app-adguardhome/root/usr/share/AdGuardHome/watchconfig.sh delete mode 100755 luci-app-adguardhome/root/usr/share/rpcd/acl.d/luci-app-adguardhome.json delete mode 100755 luci-app-adguardhome/root/www/luci-static/resources/codemirror/addon/fold/foldcode.js delete mode 100755 luci-app-adguardhome/root/www/luci-static/resources/codemirror/addon/fold/foldgutter.css delete mode 100755 luci-app-adguardhome/root/www/luci-static/resources/codemirror/addon/fold/foldgutter.js delete mode 100755 luci-app-adguardhome/root/www/luci-static/resources/codemirror/addon/fold/indent-fold.js delete mode 100755 luci-app-adguardhome/root/www/luci-static/resources/codemirror/lib/codemirror.css delete mode 100755 luci-app-adguardhome/root/www/luci-static/resources/codemirror/lib/codemirror.js delete mode 100755 luci-app-adguardhome/root/www/luci-static/resources/codemirror/mode/yaml/yaml.js delete mode 100755 luci-app-adguardhome/root/www/luci-static/resources/codemirror/theme/dracula.css delete mode 100755 luci-app-adguardhome/root/www/luci-static/resources/twin-bcrypt.min.js delete mode 100755 luci-app-diskman/Makefile delete mode 100755 luci-app-diskman/luasrc/controller/diskman.lua delete mode 100755 luci-app-diskman/luasrc/model/cbi/diskman/btrfs.lua delete mode 100755 luci-app-diskman/luasrc/model/cbi/diskman/disks.lua delete mode 100755 luci-app-diskman/luasrc/model/cbi/diskman/partition.lua delete mode 100755 luci-app-diskman/luasrc/model/diskman.lua delete mode 100755 luci-app-diskman/luasrc/view/diskman/cbi/disabled_button.htm delete mode 100755 luci-app-diskman/luasrc/view/diskman/cbi/format_button.htm delete mode 100755 luci-app-diskman/luasrc/view/diskman/cbi/inlinebutton.htm delete mode 100755 luci-app-diskman/luasrc/view/diskman/cbi/xnullsection.htm delete mode 100755 luci-app-diskman/luasrc/view/diskman/cbi/xsimpleform.htm delete mode 100755 luci-app-diskman/luasrc/view/diskman/disk_info.htm delete mode 100755 luci-app-diskman/luasrc/view/diskman/partition_info.htm delete mode 100755 luci-app-diskman/luasrc/view/diskman/smart_detail.htm delete mode 100755 luci-app-diskman/po/zh-cn/diskman.po delete mode 100755 luci-app-diskman/po/zh_Hans delete mode 100755 luci-app-dockerman/Makefile delete mode 100755 luci-app-dockerman/depends.lst delete mode 100755 luci-app-dockerman/htdocs/luci-static/resources/dockerman/containers.svg delete mode 100755 luci-app-dockerman/htdocs/luci-static/resources/dockerman/file-icon.png delete mode 100755 luci-app-dockerman/htdocs/luci-static/resources/dockerman/file-manager.css delete mode 100755 luci-app-dockerman/htdocs/luci-static/resources/dockerman/folder-icon.png delete mode 100755 luci-app-dockerman/htdocs/luci-static/resources/dockerman/images.svg delete mode 100755 luci-app-dockerman/htdocs/luci-static/resources/dockerman/link-icon.png delete mode 100755 luci-app-dockerman/htdocs/luci-static/resources/dockerman/networks.svg delete mode 100755 luci-app-dockerman/htdocs/luci-static/resources/dockerman/tar.min.js delete mode 100755 luci-app-dockerman/htdocs/luci-static/resources/dockerman/volumes.svg delete mode 100755 luci-app-dockerman/luasrc/controller/dockerman.lua delete mode 100755 luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua delete mode 100755 luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua delete mode 100755 luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua delete mode 100755 luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua delete mode 100755 luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua delete mode 100755 luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua delete mode 100755 luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua delete mode 100755 luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua delete mode 100755 luci-app-dockerman/luasrc/model/cbi/dockerman/volumes.lua delete mode 100755 luci-app-dockerman/luasrc/model/docker.lua delete mode 100755 luci-app-dockerman/luasrc/view/dockerman/apply_widget.htm delete mode 100755 luci-app-dockerman/luasrc/view/dockerman/cbi/inlinebutton.htm delete mode 100755 luci-app-dockerman/luasrc/view/dockerman/cbi/inlinevalue.htm delete mode 100755 luci-app-dockerman/luasrc/view/dockerman/cbi/namedsection.htm delete mode 100755 luci-app-dockerman/luasrc/view/dockerman/cbi/xfvalue.htm delete mode 100755 luci-app-dockerman/luasrc/view/dockerman/container.htm delete mode 100755 luci-app-dockerman/luasrc/view/dockerman/container_console.htm delete mode 100755 luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm delete mode 100755 luci-app-dockerman/luasrc/view/dockerman/container_stats.htm delete mode 100755 luci-app-dockerman/luasrc/view/dockerman/containers_running_stats.htm delete mode 100755 luci-app-dockerman/luasrc/view/dockerman/images_import.htm delete mode 100755 luci-app-dockerman/luasrc/view/dockerman/images_load.htm delete mode 100755 luci-app-dockerman/luasrc/view/dockerman/logs.htm delete mode 100755 luci-app-dockerman/luasrc/view/dockerman/newcontainer_resolve.htm delete mode 100755 luci-app-dockerman/luasrc/view/dockerman/overview.htm delete mode 100755 luci-app-dockerman/luasrc/view/dockerman/volume_size.htm delete mode 100755 luci-app-dockerman/po/templates/dockerman.pot delete mode 100755 luci-app-dockerman/po/zh-cn/dockerman.po delete mode 100755 luci-app-dockerman/po/zh_Hans delete mode 100755 luci-app-dockerman/postinst delete mode 100755 luci-app-dockerman/root/etc/init.d/dockerman delete mode 100755 luci-app-dockerman/root/etc/uci-defaults/luci-app-dockerman delete mode 100755 luci-app-dockerman/root/usr/share/rpcd/acl.d/luci-app-dockerman.json mode change 100755 => 100644 luci-app-snmpd/Makefile create mode 100644 luci-app-snmpd/htdocs/luci-static/resources/view/snmpd/snmpd.js delete mode 100755 luci-app-snmpd/luasrc/controller/snmpd.lua delete mode 100755 luci-app-snmpd/luasrc/model/cbi/snmpd.lua delete mode 100755 luci-app-snmpd/luasrc/view/snmpd.htm delete mode 100755 luci-app-snmpd/po/de/snmpd.po delete mode 100755 luci-app-snmpd/po/fr/snmpd.po delete mode 100755 luci-app-snmpd/po/it/snmpd.po delete mode 100755 luci-app-snmpd/po/oc/snmpd.po mode change 100755 => 100644 luci-app-snmpd/po/templates/snmpd.pot delete mode 100755 luci-app-snmpd/po/zh_Hans/snmpd.po delete mode 100755 luci-app-snmpd/root/etc/config/snmpd delete mode 100755 luci-app-snmpd/root/etc/init.d/snmpd delete mode 100755 luci-app-snmpd/root/etc/uci-defaults/4400-snmpd mode change 100755 => 100644 luci-app-snmpd/root/usr/share/luci/menu.d/luci-app-snmpd.json mode change 100755 => 100644 luci-app-snmpd/root/usr/share/rpcd/acl.d/luci-app-snmpd.json mode change 100755 => 100644 luci-mod-dashboard/Makefile mode change 100755 => 100644 luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/css/custom.css mode change 100755 => 100644 luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/icons/devices.svg mode change 100755 => 100644 luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/icons/internet.svg mode change 100755 => 100644 luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/icons/not-internet.svg mode change 100755 => 100644 luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/icons/router.svg mode change 100755 => 100644 luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/icons/wireless.svg mode change 100755 => 100644 luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js mode change 100755 => 100644 luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js mode change 100755 => 100644 luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js mode change 100755 => 100644 luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/index.js create mode 100644 luci-mod-dashboard/po/ar/dashboard.po create mode 100644 luci-mod-dashboard/po/bg/dashboard.po create mode 100644 luci-mod-dashboard/po/bn_BD/dashboard.po create mode 100644 luci-mod-dashboard/po/ca/dashboard.po create mode 100644 luci-mod-dashboard/po/cs/dashboard.po create mode 100644 luci-mod-dashboard/po/da/dashboard.po create mode 100644 luci-mod-dashboard/po/de/dashboard.po create mode 100644 luci-mod-dashboard/po/el/dashboard.po create mode 100644 luci-mod-dashboard/po/en/dashboard.po create mode 100644 luci-mod-dashboard/po/es/dashboard.po create mode 100644 luci-mod-dashboard/po/fi/dashboard.po mode change 100755 => 100644 luci-mod-dashboard/po/fr/dashboard.po create mode 100644 luci-mod-dashboard/po/he/dashboard.po create mode 100644 luci-mod-dashboard/po/hi/dashboard.po create mode 100644 luci-mod-dashboard/po/hu/dashboard.po create mode 100644 luci-mod-dashboard/po/id/dashboard.po create mode 100644 luci-mod-dashboard/po/it/dashboard.po create mode 100644 luci-mod-dashboard/po/ja/dashboard.po create mode 100644 luci-mod-dashboard/po/ko/dashboard.po create mode 100644 luci-mod-dashboard/po/mr/dashboard.po create mode 100644 luci-mod-dashboard/po/ms/dashboard.po create mode 100644 luci-mod-dashboard/po/nb_NO/dashboard.po create mode 100644 luci-mod-dashboard/po/nl/dashboard.po create mode 100644 luci-mod-dashboard/po/pl/dashboard.po create mode 100644 luci-mod-dashboard/po/pt/dashboard.po create mode 100644 luci-mod-dashboard/po/pt_BR/dashboard.po create mode 100644 luci-mod-dashboard/po/ro/dashboard.po mode change 100755 => 100644 luci-mod-dashboard/po/ru/dashboard.po create mode 100644 luci-mod-dashboard/po/sk/dashboard.po create mode 100644 luci-mod-dashboard/po/sv/dashboard.po mode change 100755 => 100644 luci-mod-dashboard/po/templates/dashboard.pot create mode 100644 luci-mod-dashboard/po/tr/dashboard.po create mode 100644 luci-mod-dashboard/po/uk/dashboard.po create mode 100644 luci-mod-dashboard/po/vi/dashboard.po mode change 100755 => 100644 luci-mod-dashboard/po/zh_Hans/dashboard.po create mode 100644 luci-mod-dashboard/po/zh_Hant/dashboard.po mode change 100755 => 100644 luci-mod-dashboard/root/usr/share/luci/menu.d/luci-mod-dashboard.json mode change 100755 => 100644 luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json mode change 100755 => 100644 luci-mod-network/Makefile mode change 100755 => 100644 luci-mod-network/htdocs/luci-static/resources/tools/network.js mode change 100755 => 100644 luci-mod-network/htdocs/luci-static/resources/view/network/dhcp.js mode change 100755 => 100644 luci-mod-network/htdocs/luci-static/resources/view/network/diagnostics.js delete mode 100755 luci-mod-network/htdocs/luci-static/resources/view/network/hosts.js mode change 100755 => 100644 luci-mod-network/htdocs/luci-static/resources/view/network/interfaces.js mode change 100755 => 100644 luci-mod-network/htdocs/luci-static/resources/view/network/routes.js mode change 100755 => 100644 luci-mod-network/htdocs/luci-static/resources/view/network/switch.js mode change 100755 => 100644 luci-mod-network/htdocs/luci-static/resources/view/network/wireless.js mode change 100755 => 100644 luci-mod-network/root/usr/share/luci/menu.d/luci-mod-network.json mode change 100755 => 100644 luci-mod-network/root/usr/share/rpcd/acl.d/luci-mod-network.json mode change 100755 => 100644 luci-proto-mbim/Makefile mode change 100755 => 100644 luci-proto-mbim/htdocs/luci-static/resources/protocol/mbim.js delete mode 100755 luci-theme-ezengreen/Makefile delete mode 100755 luci-theme-ezengreen/htdocs/luci-static/ezengreen/1omr-logo-apple.png delete mode 100755 luci-theme-ezengreen/htdocs/luci-static/ezengreen/cascade.css delete mode 100755 luci-theme-ezengreen/htdocs/luci-static/ezengreen/favicon.png delete mode 100755 luci-theme-ezengreen/htdocs/luci-static/ezengreen/html5.js delete mode 100755 luci-theme-ezengreen/htdocs/luci-static/ezengreen/mobile.css delete mode 100755 luci-theme-ezengreen/htdocs/luci-static/resources/ezengreen/images/cascade.css delete mode 100755 luci-theme-ezengreen/htdocs/luci-static/resources/ezengreen/images/ezenlink.png delete mode 100755 luci-theme-ezengreen/htdocs/luci-static/resources/ezengreen/images/favicon.ico delete mode 100755 luci-theme-ezengreen/htdocs/luci-static/resources/ezengreen/images/footer.png delete mode 100755 luci-theme-ezengreen/htdocs/luci-static/resources/ezengreen/images/mobile.css delete mode 100755 luci-theme-ezengreen/htdocs/luci-static/resources/ezengreen/images/omr-logo.png delete mode 100755 luci-theme-ezengreen/htdocs/luci-static/resources/ezengreen/images/outdoorrouter.png delete mode 100755 luci-theme-ezengreen/htdocs/luci-static/resources/menu-ezengreen.js delete mode 100755 luci-theme-ezengreen/luasrc/view/themes/ezengreen/footer.htm delete mode 100755 luci-theme-ezengreen/luasrc/view/themes/ezengreen/header.htm delete mode 100755 luci-theme-ezengreen/root/etc/uci-defaults/luci-theme-ezengreen mode change 100755 => 100644 luci-theme-openwrt-2020/Makefile mode change 100755 => 100644 luci-theme-openwrt-2020/htdocs/luci-static/openwrt2020/GalanoGrotesqueW00-Regular.woff2 mode change 100755 => 100644 luci-theme-openwrt-2020/htdocs/luci-static/openwrt2020/cascade.css delete mode 100755 luci-theme-openwrt-2020/htdocs/luci-static/openwrt2020/favicon.png create mode 100644 luci-theme-openwrt-2020/htdocs/luci-static/openwrt2020/logo.png create mode 100644 luci-theme-openwrt-2020/htdocs/luci-static/openwrt2020/logo.svg delete mode 100755 luci-theme-openwrt-2020/htdocs/luci-static/openwrt2020/omr-logo.png mode change 100755 => 100644 luci-theme-openwrt-2020/htdocs/luci-static/openwrt2020/spinner.svg mode change 100755 => 100644 luci-theme-openwrt-2020/htdocs/luci-static/resources/menu-openwrt2020.js delete mode 100755 luci-theme-openwrt-2020/luasrc/view/themes/openwrt2020/header.htm rename luci-theme-openwrt-2020/{luasrc/view/themes/openwrt2020/footer.htm => ucode/template/themes/openwrt2020/footer.ut} (67%) mode change 100755 => 100644 create mode 100644 luci-theme-openwrt-2020/ucode/template/themes/openwrt2020/header.ut mode change 100755 => 100644 msmtp/Makefile mode change 100755 => 100644 net-tools/Makefile delete mode 100755 net-tools/patches/mptcp-support.patch mode change 100755 => 100644 netifd/Makefile mode change 100755 => 100644 netifd/files/etc/hotplug.d/iface/00-netstate create mode 100755 netifd/files/etc/init.d/packet_steering mode change 100755 => 100644 netifd/files/etc/uci-defaults/14_migrate-dhcp-release mode change 100755 => 100644 netifd/files/etc/udhcpc.user rename netifd/files/{etc/hotplug.d/net/20-smp-packet-steering => usr/libexec/network/packet-steering.sh} (92%) delete mode 100755 netmaker-openwrt/LICENSE delete mode 100755 netmaker-openwrt/README.md delete mode 100755 netmaker-openwrt/netmaker/Makefile delete mode 100755 netmaker-openwrt/netmaker/root/etc/init.d/netclient delete mode 100755 netmaker-openwrt/scripts/build_ipk.sh delete mode 100755 nginx/Config.in delete mode 100755 nginx/Config_ssl.in delete mode 100755 nginx/Makefile delete mode 100755 nginx/files-luci-support/60_nginx-luci-support delete mode 100755 nginx/files-luci-support/70_nginx-luci-support-ssl delete mode 100755 nginx/files-luci-support/luci_nginx.conf delete mode 100755 nginx/files-luci-support/luci_nginx_ssl.conf delete mode 100755 nginx/files-luci-support/luci_uwsgi.conf delete mode 100755 nginx/files/nginx.init delete mode 100755 nginx/patches-lua-nginx/100-no_by_lua_block.patch delete mode 100755 nginx/patches/101-feature_test_fix.patch delete mode 100755 nginx/patches/102-sizeof_test_fix.patch delete mode 100755 nginx/patches/103-sys_nerr.patch delete mode 100755 nginx/patches/200-config.patch delete mode 100755 nginx/patches/201-ignore-invalid-options.patch delete mode 100755 nginx/patches/300-max-processes.patch mode change 100755 => 100644 protobuf/Makefile create mode 100644 protobuf/patches/010-rpath.patch mode change 100755 => 100644 serdisplib/Makefile create mode 100644 serdisplib/patches/002-allow-1bpp-framebuffer.patch create mode 100644 serdisplib/patches/010-cross-compile.patch mode change 100755 => 100644 speedtestcpp/Makefile delete mode 100755 upx/Makefile diff --git a/6in4/Makefile b/6in4/Makefile old mode 100755 new mode 100644 index d0f2ad30c..edbb7d71a --- a/6in4/Makefile +++ b/6in4/Makefile @@ -1,7 +1,5 @@ # # Copyright (C) 2010-2015 OpenWrt.org -# Copyright (C) 2018-2019 Ycarus (Yannick Chabanois) -# - Added gateway setting # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. @@ -10,8 +8,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=6in4 -PKG_VERSION:=270 -PKG_RELEASE:=2 +PKG_RELEASE:=28 PKG_LICENSE:=GPL-2.0 include $(INCLUDE_DIR)/package.mk diff --git a/6in4/files/6in4.sh b/6in4/files/6in4.sh index cf17c86d8..5b5c7b36a 100755 --- a/6in4/files/6in4.sh +++ b/6in4/files/6in4.sh @@ -9,6 +9,20 @@ init_proto "$@" } +# Function taken from 6to4 package (6to4.sh), flipped returns +test_6in4_rfc1918() +{ + local oIFS="$IFS"; IFS="."; set -- $1; IFS="$oIFS" + [ $1 -eq 10 ] && return 1 + [ $1 -eq 192 ] && [ $2 -eq 168 ] && return 1 + [ $1 -eq 172 ] && [ $2 -ge 16 ] && [ $2 -le 31 ] && return 1 + + # RFC 6598 + [ $1 -eq 100 ] && [ $2 -ge 64 ] && [ $2 -le 127 ] && return 1 + + return 0 +} + proto_6in4_update() { sh -c ' timeout=5 @@ -31,8 +45,8 @@ proto_6in4_setup() { local iface="$2" local link="6in4-$cfg" - local mtu ttl tos ipaddr peeraddr ip6addr ip6prefix ip6prefixes tunlink tunnelid username password updatekey gateway - json_get_vars mtu ttl tos ipaddr peeraddr ip6addr tunlink tunnelid username password updatekey gateway + local mtu ttl tos ipaddr peeraddr ip6addr ip6prefix ip6prefixes tunlink tunnelid username password updatekey + json_get_vars mtu ttl tos ipaddr peeraddr ip6addr tunlink tunnelid username password updatekey json_for_each_item proto_6in4_add_prefix ip6prefix ip6prefixes [ -z "$peeraddr" ] && { @@ -41,7 +55,7 @@ proto_6in4_setup() { return } - [ -n "$tunlink" ] && ( proto_add_host_dependency "$cfg" "$peeraddr" "$tunlink" ) + ( proto_add_host_dependency "$cfg" "$peeraddr" "$tunlink" ) [ -z "$ipaddr" ] && { local wanif="$tunlink" @@ -61,15 +75,11 @@ proto_6in4_setup() { [ -n "$ip6addr" ] && { local local6="${ip6addr%%/*}" local mask6="${ip6addr##*/}" - [[ "$local6" = "$mask6" ]] && mask6= + [ "$local6" = "$mask6" ] && mask6= proto_add_ipv6_address "$local6" "$mask6" proto_add_ipv6_route "::" 0 "" "" "" "$local6/$mask6" } - [ -n "$gateway" ] && { - proto_add_ipv6_route "::" 0 "$gateway" - } - for ip6prefix in $ip6prefixes; do proto_add_ipv6_prefix "$ip6prefix" proto_add_ipv6_route "::" 0 "" "" "" "$ip6prefix" @@ -101,6 +111,11 @@ proto_6in4_setup() { } local url="$http://ipv4.tunnelbroker.net/nic/update?hostname=$tunnelid" + + test_6in4_rfc1918 "$ipaddr" && { + local url="${url}&myip=${ipaddr}" + } + local try=0 local max=3 @@ -138,7 +153,6 @@ proto_6in4_init_config() { proto_config_add_string "username" proto_config_add_string "password" proto_config_add_string "updatekey" - proto_config_add_string "gateway" proto_config_add_int "mtu" proto_config_add_int "ttl" proto_config_add_string "tos" diff --git a/cryptodev-linux/Makefile b/cryptodev-linux/Makefile old mode 100755 new mode 100644 diff --git a/https-dns-proxy/Makefile b/https-dns-proxy/Makefile old mode 100755 new mode 100644 index abfb4be7a..ce7d70eeb --- a/https-dns-proxy/Makefile +++ b/https-dns-proxy/Makefile @@ -1,14 +1,14 @@ include $(TOPDIR)/rules.mk PKG_NAME:=https-dns-proxy -PKG_VERSION:=2021-11-22 -PKG_RELEASE:=3 +PKG_VERSION:=2023-05-25 +PKG_RELEASE:=2 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=https://github.com/aarond10/https_dns_proxy/ -PKG_SOURCE_DATE:=2021-11-22 -PKG_SOURCE_VERSION:=9336fd6272d67e8bb6e304fa54f3139a3d26f08f -PKG_MIRROR_HASH:=60b1ddabaf1db3a9ee19f3294a1df714364d580cef5e3c2161363c371a557456 +PKG_SOURCE_DATE:=$(PKG_VERSION) +PKG_SOURCE_VERSION:=d03e11572562f008f68df217a7378628f1bb7b79 +PKG_MIRROR_HASH:=5af3683c48bc9e493ca2761a6f7ee756431692a695d6008f61b8b92431036dca PKG_MAINTAINER:=Stan Grishin PKG_LICENSE:=MIT PKG_LICENSE_FILES:=LICENSE @@ -16,20 +16,20 @@ PKG_LICENSE_FILES:=LICENSE include $(INCLUDE_DIR)/package.mk include $(INCLUDE_DIR)/cmake.mk -CMAKE_OPTIONS += -DCLANG_TIDY_EXE= +CMAKE_OPTIONS += -DCLANG_TIDY_EXE= -DGIT_VERSION=$(PKG_VERSION)-$(PKG_RELEASE) define Package/https-dns-proxy SECTION:=net CATEGORY:=Network TITLE:=DNS Over HTTPS Proxy URL:=https://docs.openwrt.melmac.net/https-dns-proxy/ - DEPENDS:=+libcares +libcurl +libev +ca-bundle + DEPENDS:=+libcares +libcurl +libev +ca-bundle +jsonfilter CONFLICTS:=https_dns_proxy endef define Package/https-dns-proxy/description -https-dns-proxy is a light-weight DNS<-->HTTPS, non-caching translation proxy for the RFC 8484 DoH standard. -It receives regular (UDP) DNS requests and issues them via DoH. +Light-weight DNS-over-HTTPS, non-caching translation proxy for the RFC 8484 DoH standard. +It receives regular (UDP) DNS requests and resolves them via DoH resolver. Please see https://docs.openwrt.melmac.net/https-dns-proxy/ for more information. endef @@ -40,12 +40,14 @@ endef define Package/https-dns-proxy/install $(INSTALL_DIR) $(1)/usr/sbin $(INSTALL_DIR) $(1)/etc/init.d - $(INSTALL_DIR) ${1}/etc/config + $(INSTALL_DIR) $(1)/etc/config $(INSTALL_DIR) $(1)/etc/hotplug.d/iface + $(INSTALL_DIR) $(1)/etc/uci-defaults/ $(INSTALL_BIN) $(PKG_BUILD_DIR)/https_dns_proxy $(1)/usr/sbin/https-dns-proxy $(INSTALL_BIN) ./files/https-dns-proxy.init $(1)/etc/init.d/https-dns-proxy - $(SED) "s|^\(PKG_VERSION\).*|\1='$(PKG_VERSION)-$(PKG_RELEASE)'|" $(1)/etc/init.d/https-dns-proxy + $(SED) "s|^\(readonly PKG_VERSION\).*|\1='$(PKG_VERSION)-$(PKG_RELEASE)'|" $(1)/etc/init.d/https-dns-proxy $(INSTALL_CONF) ./files/https-dns-proxy.config $(1)/etc/config/https-dns-proxy + $(INSTALL_BIN) ./files/https-dns-proxy.defaults $(1)/etc/uci-defaults/50-https-dns-proxy-migrate-options.sh endef $(eval $(call BuildPackage,https-dns-proxy)) diff --git a/https-dns-proxy/files/README.md b/https-dns-proxy/files/README.md old mode 100755 new mode 100644 diff --git a/https-dns-proxy/files/https-dns-proxy.config b/https-dns-proxy/files/https-dns-proxy.config old mode 100755 new mode 100644 index f08e03ca9..39b807b45 --- a/https-dns-proxy/files/https-dns-proxy.config +++ b/https-dns-proxy/files/https-dns-proxy.config @@ -1,5 +1,7 @@ config main 'config' - option update_dnsmasq_config '*' + option canary_domains_icloud '1' + option canary_domains_mozilla '1' + option dnsmasq_config_update '*' option force_dns '1' list force_dns_port '53' list force_dns_port '853' @@ -11,12 +13,13 @@ config main 'config' # list force_dns_port '4434' # list force_dns_port '5443' # list force_dns_port '8443' + option procd_trigger_wan6 '0' config https-dns-proxy option bootstrap_dns '1.1.1.1,1.0.0.1' option resolver_url 'https://cloudflare-dns.com/dns-query' option listen_addr '127.0.0.1' - option listen_port '5054' + option listen_port '5053' option user 'nobody' option group 'nogroup' @@ -24,6 +27,6 @@ config https-dns-proxy option bootstrap_dns '8.8.8.8,8.8.4.4' option resolver_url 'https://dns.google/dns-query' option listen_addr '127.0.0.1' - option listen_port '5053' + option listen_port '5054' option user 'nobody' option group 'nogroup' diff --git a/https-dns-proxy/files/https-dns-proxy.defaults b/https-dns-proxy/files/https-dns-proxy.defaults new file mode 100644 index 000000000..8321ea99b --- /dev/null +++ b/https-dns-proxy/files/https-dns-proxy.defaults @@ -0,0 +1,3 @@ +#!/bin/sh + sed -i "s|update_dnsmasq_config|dnsmasq_config_update|" "/etc/config/https-dns-proxy" + sed -i "s|wan6_trigger|procd_trigger_wan6|" "/etc/config/https-dns-proxy" diff --git a/https-dns-proxy/files/https-dns-proxy.hotplug.iface b/https-dns-proxy/files/https-dns-proxy.hotplug.iface old mode 100755 new mode 100644 diff --git a/https-dns-proxy/files/https-dns-proxy.init b/https-dns-proxy/files/https-dns-proxy.init index ef0ffc7d2..d63dad9c5 100755 --- a/https-dns-proxy/files/https-dns-proxy.init +++ b/https-dns-proxy/files/https-dns-proxy.init @@ -1,10 +1,9 @@ #!/bin/sh /etc/rc.common -# Copyright 2019-2020 Stan Grishin (stangri@melmac.net) -# shellcheck disable=SC2039,SC3043,SC3060 -PKG_VERSION='dev-test' +# Copyright 2019-2022 Stan Grishin (stangri@melmac.ca) +# shellcheck disable=SC1091,SC3043,SC3060 # shellcheck disable=SC2034 -START=80 +START=95 # shellcheck disable=SC2034 USE_PROCD=1 @@ -15,8 +14,60 @@ else EXTRA_COMMANDS='version' fi +readonly PKG_VERSION='dev-test' +readonly packageName='https-dns-proxy' +readonly serviceName="$packageName $PKG_VERSION" +readonly _OK_='\033[0;32m\xe2\x9c\x93\033[0m' +readonly _FAIL_='\033[0;31m\xe2\x9c\x97\033[0m' readonly PROG=/usr/sbin/https-dns-proxy -dnsmasqConfig=''; forceDNS=''; forceDNSPorts=''; +readonly BOOTSTRAP_CF='1.1.1.1,1.0.0.1,2606:4700:4700::1111,2606:4700:4700::1001' +readonly BOOTSTRAP_GOOGLE='8.8.8.8,8.8.4.4,2001:4860:4860::8888,2001:4860:4860::8844' +readonly DEFAULT_BOOTSTRAP="${BOOTSTRAP_CF},${BOOTSTRAP_GOOGLE}" +readonly canaryDomainsMozilla='use-application-dns.net' +readonly canaryDomainsiCloud='mask.icloud.com mask-h2.icloud.com' + +str_contains() { [ -n "$1" ] &&[ -n "$2" ] && [ "${1//$2}" != "$1" ]; } +is_mac_address() { expr "$1" : '[0-9A-F][0-9A-F]:[0-9A-F][0-9A-F]:[0-9A-F][0-9A-F]:[0-9A-F][0-9A-F]:[0-9A-F][0-9A-F]:[0-9A-F][0-9A-F]$' >/dev/null; } +is_ipv4() { expr "$1" : '[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$' >/dev/null; } +is_ipv6() { ! is_mac_address "$1" && str_contains "$1" ":"; } +output() { + local msg memmsg logmsg + local sharedMemoryOutput="/dev/shm/$packageName-output" + [ -t 1 ] && printf "%b" "$@" + msg="${1//$serviceName /service }"; + if [ "$(printf "%b" "$msg" | wc -l)" -gt 0 ]; then + [ -s "$sharedMemoryOutput" ] && memmsg="$(cat "$sharedMemoryOutput")" + logmsg="$(printf "%b" "${memmsg}${msg}" | sed 's/\x1b\[[0-9;]*m//g')" + logger -t "$packageName" "$(printf "%b" "$logmsg")" + rm -f "$sharedMemoryOutput" + else + printf "%b" "$msg" >> "$sharedMemoryOutput" + fi +} +output_ok() { output "$_OK_"; } +output_okn() { output "${_OK_}\\n"; } +output_fail() { output "$_FAIL_"; } +output_failn() { output "${_FAIL_}\\n"; } +uci_add_list_if_new() { + local PACKAGE="$1" + local CONFIG="$2" + local OPTION="$3" + local VALUE="$4" + local i + [ -n "$PACKAGE" ] && [ -n "$CONFIG" ] && [ -n "$OPTION" ] && [ -n "$VALUE" ] || return 1 + for i in $(uci_get "$PACKAGE" "$CONFIG" "$OPTION"); do + [ "$i" = "$VALUE" ] && return 0 + done + uci_add_list "$PACKAGE" "$CONFIG" "$OPTION" "$VALUE" +} +uci_changes() { + local PACKAGE="$1" + local CONFIG="$2" + local OPTION="$3" + /sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} changes "$PACKAGE${CONFIG:+.$CONFIG}${OPTION:+.$OPTION}" +} + +dnsmasq_restart() { [ -x /etc/init.d/dnsmasq ] || return 0; /etc/init.d/dnsmasq restart >/dev/null 2>&1; } version() { echo "$PKG_VERSION"; } @@ -26,11 +77,10 @@ append_bool() { local section="$1" local option="$2" local value="$3" - local default="$4" + local default="${4:-0}" local _loctmp - [ -z "$default" ] && default="0" config_get_bool _loctmp "$section" "$option" "$default" - [ "$_loctmp" != "0" ] && xappend "$value" + [ "$_loctmp" -ne 0 ] && xappend "$value" } append_parm() { @@ -40,180 +90,280 @@ append_parm() { local default="$4" local _loctmp config_get _loctmp "$section" "$option" "$default" + [ -n "$_loctmp" ] && xappend "$switch $_loctmp" +} + +append_counter() { + local section="$1" + local option="$2" + local switch="$3" + local default="${4:-0}" + local _loctmp i + config_get _loctmp "$section" "$option" "$default" +# shellcheck disable=SC2086,SC2154 + for i in $(seq 1 $_loctmp); do + xappend '-v' + done +} + +append_bootstrap() { + local section="$1" + local option="$2" + local switch="$3" + local default="$4" + local _old_ifs="$IFS" + local _loctmp _newtmp i + config_get _loctmp "$section" "$option" "$default" [ -z "$_loctmp" ] && return 0 - xappend "$switch $_loctmp" + IFS=" ," + for i in $_loctmp; do + if { [ "$ipv6_resolvers_only" -eq 0 ] && is_ipv4 "$i"; } || \ + { [ "$ipv6_resolvers_only" -ne 0 ] && is_ipv6 "$i"; }; then + [ -z "$_newtmp" ] && _newtmp="$i" || _newtmp="${_newtmp},${i}" + fi + done + IFS="$_old_ifs" + [ -n "$_newtmp" ] && xappend "$switch $_newtmp" + [ "$ipv6_resolvers_only" -eq 0 ] && xappend '-4' +} + +boot() { + ubus -t 30 wait_for network.interface 2>/dev/null + rc_procd start_service 'on_boot' } start_instance() { - local cfg="$1" param listen_addr listen_port i + local cfg="$1" param listen_addr listen_port ipv6_resolvers_only p url iface + + config_get url "$cfg" 'resolver_url' + config_get_bool ipv6_resolvers_only "$cfg" 'use_ipv6_resolvers_only' '0' append_parm "$cfg" 'resolver_url' '-r' - append_parm "$cfg" 'polling_interval' '-i' append_parm "$cfg" 'listen_addr' '-a' '127.0.0.1' - append_parm "$cfg" 'listen_port' '-p' "$p" + append_parm "$cfg" 'listen_port' '-p' "$port" append_parm "$cfg" 'dscp_codepoint' '-c' - append_parm "$cfg" 'bootstrap_dns' '-b' + append_bootstrap "$cfg" 'bootstrap_dns' '-b' "$DEFAULT_BOOTSTRAP" append_parm "$cfg" 'user' '-u' 'nobody' append_parm "$cfg" 'group' '-g' 'nogroup' + append_parm "$cfg" 'ca_certs_file' '-C' + append_parm "$cfg" 'polling_interval' '-i' append_parm "$cfg" 'proxy_server' '-t' append_parm "$cfg" 'logfile' '-l' append_bool "$cfg" 'use_http1' '-x' - config_get_bool ipv6_resolvers_only "$cfg" 'use_ipv6_resolvers_only' '0' - config_get verbosity "$cfg" 'verbosity' '0' - -# shellcheck disable=SC2086,SC2154 - for i in $(seq 1 $verbosity); do - xappend '-v' - done -# shellcheck disable=SC2154 - if [ "$ipv6_resolvers_only" = 0 ]; then - xappend '-4' - fi + append_counter "$cfg" 'verbosity' '-v' '0' procd_open_instance # shellcheck disable=SC2086 - procd_set_param command ${PROG} ${param} + procd_set_param command $PROG $param procd_set_param stderr 1 procd_set_param stdout 1 procd_set_param respawn - procd_close_instance - - config_get listen_addr "$cfg" 'listen_addr' '127.0.0.1' - config_get listen_port "$cfg" 'listen_port' "$p" - - if [ "$dnsmasqConfig" = "*" ]; then - config_load 'dhcp' - config_foreach dnsmasq_add_doh_server 'dnsmasq' "${listen_addr}" "${listen_port}" - elif [ -n "$dnsmasqConfig" ]; then - for i in $dnsmasqConfig; do - dnsmasq_add_doh_server "@dnsmasq[${i}]" "${listen_addr}" "${listen_port}" - done - fi - p="$((p+1))" -} - -is_force_dns_active() { iptables-save 2>/dev/null | grep -q -w -- '--dport 53'; } - -start_service() { - local p=5053 c - config_load 'https-dns-proxy' - config_get dnsmasqConfig 'config' 'update_dnsmasq_config' '*' - config_get_bool forceDNS 'config' 'force_dns' '1' - config_get forceDNSPorts 'config' 'force_dns_port' '53 853' - dhcp_backup 'create' - config_load 'https-dns-proxy' - config_foreach start_instance 'https-dns-proxy' - if [ "$forceDNS" -ne 0 ]; then - procd_open_instance 'main' - procd_set_param command /bin/true - procd_set_param stdout 1 - procd_set_param stderr 1 - procd_open_data + procd_open_data + json_add_object mdns + procd_add_mdns_service "$packageName" 'udp' "$port" "DNS over HTTPS proxy" + json_close_object + json_add_string url "$url" + if [ "$force_dns" -ne 0 ]; then json_add_array firewall - for c in $forceDNSPorts; do - if netstat -tuln | grep 'LISTEN' | grep ":${c}" >/dev/null 2>&1 || [ "$c" = "53" ]; then - json_add_object "" - json_add_string type redirect - json_add_string target DNAT - json_add_string src lan - json_add_string proto "tcp udp" - json_add_string src_dport "$c" - json_add_string dest_port "$c" - json_add_boolean reflection 0 - json_close_object - else - json_add_object "" - json_add_string type rule - json_add_string src lan - json_add_string dest "*" - json_add_string proto "tcp udp" - json_add_string dest_port "$c" - json_add_string target REJECT - json_close_object - fi + for iface in $procd_fw_src_interfaces; do + for p in $force_dns_port; do + if netstat -tuln | grep 'LISTEN' | grep ":${p}" >/dev/null 2>&1 || [ "$p" = '53' ]; then + json_add_object '' + json_add_string type redirect + json_add_string target DNAT + json_add_string src "$iface" + json_add_string proto 'tcp udp' + json_add_string src_dport "$p" + json_add_string dest_port "$p" + json_add_string family any + json_add_boolean reflection 0 + json_close_object + else + json_add_object '' + json_add_string type rule + json_add_string src "$iface" + json_add_string dest '*' + json_add_string proto 'tcp udp' + json_add_string dest_port "$p" + json_add_string target REJECT + json_close_object + fi + done done json_close_array - procd_close_data - procd_close_instance fi - if [ -n "$(uci -q changes dhcp)" ]; then - uci -q commit dhcp - [ -x /etc/init.d/dnsmasq ] && /etc/init.d/dnsmasq restart >/dev/null 2>&1 + procd_close_data + procd_close_instance + + if [ "$?" ]; then + config_get listen_addr "$cfg" 'listen_addr' '127.0.0.1' + config_get listen_port "$cfg" 'listen_port' "$port" + if [ "$dnsmasq_config_update" = '*' ]; then + config_load 'dhcp' + config_foreach dnsmasq_doh_server 'dnsmasq' 'add' "${listen_addr}" "${listen_port}" + elif [ -n "$dnsmasq_config_update" ]; then + for i in $dnsmasq_config_update; do + if [ -n "$(uci_get 'dhcp' "@dnsmasq[$i]")" ]; then + dnsmasq_doh_server "@dnsmasq[$i]" 'add' "${listen_addr}" "${listen_port}" + elif [ -n "$(uci_get 'dhcp' "$i")" ]; then + dnsmasq_doh_server "${i}" 'add' "${listen_addr}" "${listen_port}" + fi + done + fi + output_ok + port="$((port+1))" + force_dns=0 + else + output_fail fi } +start_service() { + local canaryDomains canary_domains_icloud canary_domains_mozilla + local dnsmasq_config_update force_dns force_dns_port + local procd_fw_src_interfaces + + local port=5053 + output "Starting $serviceName " + config_load "$packageName" + config_get_bool canary_domains_icloud 'config' 'canary_domains_icloud' '1' + config_get_bool canary_domains_mozilla 'config' 'canary_domains_mozilla' '1' + config_get_bool force_dns 'config' 'force_dns' '1' + config_get dnsmasq_config_update 'config' 'dnsmasq_config_update' '*' + config_get force_dns_port 'config' 'force_dns_port' '53 853' + config_get procd_fw_src_interfaces 'config' 'procd_fw_src_interfaces' 'lan' + if [ "$canary_domains_icloud" -ne 0 ]; then + canaryDomains="${canaryDomains:+$canaryDomains }${canaryDomainsiCloud}" + fi + if [ "$canary_domains_mozilla" -ne 0 ]; then + canaryDomains="${canaryDomains:+$canaryDomains }${canaryDomainsMozilla}" + fi + dhcp_backup 'create' + config_load "$packageName" + config_foreach start_instance "$packageName" + if [ -n "$(uci_changes dhcp)" ]; then + uci_commit 'dhcp' + dnsmasq_restart + fi + output "\\n" +} + stop_service() { - config_load 'https-dns-proxy' - config_get dnsmasqConfig 'config' 'update_dnsmasq_config' '*' - dhcp_backup 'restore' - if [ -n "$(uci -q changes dhcp)" ]; then - uci -q commit dhcp - [ -x /etc/init.d/dnsmasq ] && /etc/init.d/dnsmasq restart >/dev/null 2>&1 + local canaryDomains canary_domains_icloud canary_domains_mozilla + local dnsmasq_config_update + local s=0 + output "Stopping $serviceName " + config_load "$packageName" + config_get dnsmasq_config_update 'config' 'dnsmasq_config_update' '*' + config_get_bool canary_domains_icloud 'config' 'canary_domains_icloud' '1' + config_get_bool canary_domains_mozilla 'config' 'canary_domains_mozilla' '1' + if [ "$canary_domains_icloud" -ne 0 ]; then + canaryDomains="${canaryDomains:+$canaryDomains }${canaryDomainsiCloud}" fi + if [ "$canary_domains_mozilla" -ne 0 ]; then + canaryDomains="${canaryDomains:+$canaryDomains }${canaryDomainsMozilla}" + fi + dhcp_backup 'restore' + if [ -n "$(uci_changes dhcp)" ]; then + uci_commit 'dhcp' + dnsmasq_restart || s=1 + fi +# shellcheck disable=SC2015 + [ "$s" -eq 0 ] && output_okn || output_failn } +# shellcheck disable=SC1091 service_triggers() { - procd_add_config_trigger "config.change" "https-dns-proxy" /etc/init.d/https-dns-proxy reload + local wan wan6 i + local procd_trigger_wan6 + config_load "$packageName" + config_get_bool procd_trigger_wan6 'config' 'procd_trigger_wan6' '0' + . /lib/functions/network.sh + network_flush_cache + network_find_wan wan + wan="${wan:-wan}" + if [ "$procd_trigger_wan6" -ne 0 ]; then + network_find_wan6 wan6 + wan6="${wan6:-wan6}" + fi + for i in "$wan" "$wan6"; do + [ -n "$i" ] && procd_add_interface_trigger "interface.*" "$i" "/etc/init.d/${packageName}" restart + done + procd_add_config_trigger "config.change" "$packageName" "/etc/init.d/${packageName}" reload } service_started() { procd_set_config_changed firewall; } service_stopped() { procd_set_config_changed firewall; } +restart() { procd_send_signal "$packageName"; rc_procd start_service; } -dnsmasq_add_doh_server() { - local cfg="$1" address="$2" port="$3" - case $address in - 0.0.0.0|::ffff:0.0.0.0) address='127.0.0.1';; - ::) address='::1';; +dnsmasq_doh_server() { + local cfg="$1" param="$2" address="${3:-127.0.0.1}" port="$4" i + case "$param" in + add) + if [ "$force_dns" -ne 0 ]; then + for i in $canaryDomains; do + uci_add_list_if_new 'dhcp' "$cfg" 'server' "/${i}/" + done + fi + case $address in + 0.0.0.0|::ffff:0.0.0.0) address='127.0.0.1';; + ::) address='::1';; + esac + uci_add_list_if_new 'dhcp' "$cfg" 'server' "${address}#${port}" + ;; + remove) + eval "$(ubus call service list "{ 'verbose': true, 'name': '$packageName' }" | jsonfilter -F '# ' -e 'TUPLES=@[*].instances[*].command[4,6]')" + for i in $TUPLES; do + uci_remove_list 'dhcp' "$cfg" 'server' "$i" + done + for i in $canaryDomains; do + uci_remove_list 'dhcp' "$cfg" 'server' "/${i}/" + done + ;; esac - uci -q del_list "dhcp.${cfg}.server=${address}#${port}" - uci -q add_list "dhcp.${cfg}.server=${address}#${port}" } dnsmasq_create_server_backup() { - local cfg="$1" - local i - uci -q get "dhcp.${cfg}" >/dev/null || return 1 - if ! uci -q get "dhcp.${cfg}.doh_backup_noresolv" >/dev/null; then - if [ -z "$(uci -q get "dhcp.${cfg}.noresolv")" ]; then - uci -q set "dhcp.${cfg}.noresolv=1" - uci -q set "dhcp.${cfg}.doh_backup_noresolv=-1" - elif [ "$(uci -q get "dhcp.${cfg}.noresolv")" != "1" ]; then - uci -q set "dhcp.${cfg}.noresolv=1" - uci -q set "dhcp.${cfg}.doh_backup_noresolv=0" + local cfg="$1" i + [ -n "$(uci_get 'dhcp' "$cfg")" ] || return 1 + if [ -z "$(uci_get 'dhcp' "$cfg" 'doh_backup_noresolv')" ]; then + if [ -z "$(uci_get 'dhcp' "$cfg" 'noresolv')" ]; then + uci_set 'dhcp' "$cfg" 'doh_backup_noresolv' '-1' + else + uci_set 'dhcp' "$cfg" 'doh_backup_noresolv' "$(uci_get 'dhcp' "$cfg" noresolv)" fi + uci_set 'dhcp' "$cfg" 'noresolv' 1 fi - if ! uci -q get "dhcp.${cfg}.doh_backup_server" >/dev/null; then - if [ -z "$(uci -q get "dhcp.${cfg}.server")" ]; then - uci -q add_list "dhcp.${cfg}.doh_backup_server=" + if [ -z "$(uci_get 'dhcp' "$cfg" 'doh_backup_server')" ]; then + if [ -z "$(uci_get 'dhcp' "$cfg" 'server')" ]; then + uci_add_list 'dhcp' "$cfg" 'doh_backup_server' "" fi - for i in $(uci -q get "dhcp.${cfg}.server"); do - uci -q add_list "dhcp.${cfg}.doh_backup_server=$i" + for i in $(uci_get 'dhcp' "$cfg" 'server'); do + uci_add_list 'dhcp' "$cfg" 'doh_backup_server' "$i" if [ "$i" = "$(echo "$i" | tr -d /\#)" ]; then - uci -q del_list "dhcp.${cfg}.server=$i" + uci_remove_list 'dhcp' "$cfg" 'server' "$i" fi done - uci -q del_list "dhcp.${cfg}.server=127.0.0.1#5353" fi return 0 } dnsmasq_restore_server_backup() { - local cfg="$1" - local i - uci -q get "dhcp.${cfg}" >/dev/null || return 0 - if uci -q get "dhcp.${cfg}.doh_backup_noresolv" >/dev/null; then - if [ "$(uci -q get "dhcp.${cfg}.doh_backup_noresolv")" = "0" ]; then - uci -q set "dhcp.${cfg}.noresolv=0" - else - uci -q del "dhcp.${cfg}.noresolv" + local cfg="$1" i + [ -n "$(uci_get 'dhcp' "$cfg")" ] || return 0 + if [ -n "$(uci_get 'dhcp' "$cfg" 'doh_backup_noresolv')" ]; then + if [ "$(uci_get 'dhcp' "$cfg" 'doh_backup_noresolv')" = "-1" ]; then + uci_remove 'dhcp' "$cfg" 'noresolv' + else + uci_set 'dhcp' "$cfg" 'noresolv' "$(uci_get 'dhcp' "$cfg" 'doh_backup_noresolv')" fi - uci -q del "dhcp.${cfg}.doh_backup_noresolv" + uci_remove 'dhcp' "$cfg" 'doh_backup_noresolv' fi - if uci -q get "dhcp.${cfg}.doh_backup_server" >/dev/null; then - uci -q del "dhcp.${cfg}.server" - for i in $(uci -q get "dhcp.${cfg}.doh_backup_server"); do - uci -q add_list "dhcp.${cfg}.server=$i" + if uci_get 'dhcp' "$cfg" 'doh_backup_server' >/dev/null 2>&1; then + dnsmasq_doh_server "$cfg" 'remove' + for i in $(uci_get 'dhcp' "$cfg" 'doh_backup_server'); do + uci_add_list_if_new 'dhcp' "$cfg" 'server' "$i" done - uci -q del "dhcp.${cfg}.doh_backup_server" + uci_remove 'dhcp' "$cfg" 'doh_backup_server' fi } @@ -222,12 +372,15 @@ dhcp_backup() { config_load 'dhcp' case "$1" in create) - if [ "$dnsmasqConfig" = "*" ]; then + if [ "$dnsmasq_config_update" = "*" ]; then config_foreach dnsmasq_create_server_backup 'dnsmasq' - elif [ -n "$dnsmasqConfig" ]; then - for i in $dnsmasqConfig; do - dnsmasq_create_server_backup "@dnsmasq[${i}]" || \ + elif [ -n "$dnsmasq_config_update" ]; then + for i in $dnsmasq_config_update; do + if [ -n "$(uci_get 'dhcp' "@dnsmasq[$i]")" ]; then + dnsmasq_create_server_backup "@dnsmasq[$i]" + elif [ -n "$(uci_get 'dhcp' "$i")" ]; then dnsmasq_create_server_backup "$i" + fi done fi ;; diff --git a/https-dns-proxy/patches/010-fix-cmakelists.patch b/https-dns-proxy/patches/010-cmakelists-remove-cflags.patch old mode 100755 new mode 100644 similarity index 56% rename from https-dns-proxy/patches/010-fix-cmakelists.patch rename to https-dns-proxy/patches/010-cmakelists-remove-cflags.patch index 106142579..cd60c6dc0 --- a/https-dns-proxy/patches/010-fix-cmakelists.patch +++ b/https-dns-proxy/patches/010-cmakelists-remove-cflags.patch @@ -1,13 +1,13 @@ --- a/CMakeLists.txt +++ b/CMakeLists.txt -@@ -21,9 +21,9 @@ if(NOT CMAKE_BUILD_TYPE) - message(STATUS "Setting build type to '${CMAKE_BUILD_TYPE}' as none was specified.") +@@ -25,9 +25,9 @@ if (NOT CMAKE_INSTALL_BINDIR) + set(CMAKE_INSTALL_BINDIR bin) endif() --set(CMAKE_C_FLAGS "-Wall -Wextra --pedantic -Wno-strict-aliasing -Wno-variadic-macros") +-set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra --pedantic -Wno-strict-aliasing -Wno-variadic-macros") -set(CMAKE_C_FLAGS_DEBUG "-g -DDEBUG") -set(CMAKE_C_FLAGS_RELEASE "-O2") -+#set(CMAKE_C_FLAGS "-Wall -Wextra --pedantic -Wno-strict-aliasing -Wno-variadic-macros") ++#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra --pedantic -Wno-strict-aliasing -Wno-variadic-macros") +#set(CMAKE_C_FLAGS_DEBUG "-g -DDEBUG") +#set(CMAKE_C_FLAGS_RELEASE "-O2") diff --git a/https-dns-proxy/patches/020-src-options.c-add-version.patch b/https-dns-proxy/patches/020-src-options.c-add-version.patch new file mode 100644 index 000000000..8bb2d9361 --- /dev/null +++ b/https-dns-proxy/patches/020-src-options.c-add-version.patch @@ -0,0 +1,11 @@ +--- a/src/options.c ++++ b/src/options.c +@@ -22,7 +22,7 @@ const char * options_sw_version() { + #ifdef SW_VERSION + return SW_VERSION; + #else +- return "2023.01.01-atLeast"; // update date sometimes, like 1-2 times a year ++ return "2023-05-25-1"; // update date sometimes, like 1-2 times a year + #endif + } + diff --git a/https-dns-proxy/test.sh b/https-dns-proxy/test.sh old mode 100755 new mode 100644 index 45469ed96..443b747a0 --- a/https-dns-proxy/test.sh +++ b/https-dns-proxy/test.sh @@ -1,3 +1,3 @@ #!/bin/sh -/etc/init.d/"$1" version 2>&1 | grep "$2" +/etc/init.d/"$1" version 2>&1 | grep "$2" && "$1" -V 2>&1 | grep "$2" diff --git a/luci-app-adguardhome/Makefile b/luci-app-adguardhome/Makefile deleted file mode 100755 index db03e8acb..000000000 --- a/luci-app-adguardhome/Makefile +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright (C) 2018-2019 Lienol -# -# This is free software, licensed under the Apache License, Version 2.0 . -# - -include $(TOPDIR)/rules.mk - -PKG_NAME:=luci-app-adguardhome -PKG_MAINTAINER:= - -LUCI_TITLE:=LuCI app for AdGuardHome -LUCI_PKGARCH:=all -LUCI_DEPENDS:=+ca-certs +curl +wget-ssl +PACKAGE_$(PKG_NAME)_INCLUDE_binary:adguardhome -LUCI_DESCRIPTION:=LuCI support for AdGuardHome - -define Package/$(PKG_NAME)/config -config PACKAGE_$(PKG_NAME)_INCLUDE_binary - bool "Include Binary File" - default y -endef - -PKG_CONFIG_DEPENDS:= CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_binary - -define Package/luci-app-adguardhome/conffiles -/usr/share/AdGuardHome/links.txt -/etc/config/AdGuardHome -/etc/AdGuardHome.yaml -endef - -define Package/luci-app-adguardhome/postinst -#!/bin/sh - /etc/init.d/AdGuardHome enable >/dev/null 2>&1 - enable=$(uci get AdGuardHome.AdGuardHome.enabled 2>/dev/null) - if [ "$enable" == "1" ]; then - /etc/init.d/AdGuardHome reload - fi - rm -f /tmp/luci-indexcache - rm -f /tmp/luci-modulecache/* -exit 0 -endef - -define Package/luci-app-adguardhome/prerm -#!/bin/sh -if [ -z "$${IPKG_INSTROOT}" ]; then - /etc/init.d/AdGuardHome disable - /etc/init.d/AdGuardHome stop -uci -q batch <<-EOF >/dev/null 2>&1 - delete ucitrack.@AdGuardHome[-1] - commit ucitrack -EOF -fi -exit 0 -endef - -include $(TOPDIR)/feeds/luci/luci.mk - -# call BuildPackage - OpenWrt buildroot signature diff --git a/luci-app-adguardhome/luasrc/controller/AdGuardHome.lua b/luci-app-adguardhome/luasrc/controller/AdGuardHome.lua deleted file mode 100755 index e9d37a766..000000000 --- a/luci-app-adguardhome/luasrc/controller/AdGuardHome.lua +++ /dev/null @@ -1,130 +0,0 @@ -module("luci.controller.AdGuardHome",package.seeall) -local fs=require"nixio.fs" -local http=require"luci.http" -local uci=require"luci.model.uci".cursor() -function index() -local page = entry({"admin", "services", "AdGuardHome"},alias("admin", "services", "AdGuardHome", "base"),_("AdGuard Home")) -page.order = 10 -page.dependent = true -page.acl_depends = { "luci-app-adguardhome" } -entry({"admin","services","AdGuardHome","base"},cbi("AdGuardHome/base"),_("Base Setting"),1).leaf = true -entry({"admin","services","AdGuardHome","log"},form("AdGuardHome/log"),_("Log"),2).leaf = true -entry({"admin","services","AdGuardHome","manual"},cbi("AdGuardHome/manual"),_("Manual Config"),3).leaf = true -entry({"admin","services","AdGuardHome","status"},call("act_status")).leaf=true -entry({"admin", "services", "AdGuardHome", "check"}, call("check_update")) -entry({"admin", "services", "AdGuardHome", "doupdate"}, call("do_update")) -entry({"admin", "services", "AdGuardHome", "getlog"}, call("get_log")) -entry({"admin", "services", "AdGuardHome", "dodellog"}, call("do_dellog")) -entry({"admin", "services", "AdGuardHome", "reloadconfig"}, call("reload_config")) -entry({"admin", "services", "AdGuardHome", "gettemplateconfig"}, call("get_template_config")) -end -function get_template_config() - local b - local d="" - for cnt in io.lines("/tmp/resolv.conf.d/resolv.conf.auto") do - b=string.match (cnt,"^[^#]*nameserver%s+([^%s]+)$") - if (b~=nil) then - d=d.." - "..b.."\n" - end - end - local f=io.open("/usr/share/AdGuardHome/AdGuardHome_template.yaml", "r+") - local tbl = {} - local a="" - while (1) do - a=f:read("*l") - if (a=="#bootstrap_dns") then - a=d - elseif (a=="#upstream_dns") then - a=d - elseif (a==nil) then - break - end - table.insert(tbl, a) - end - f:close() - http.prepare_content("text/plain; charset=utf-8") - http.write(table.concat(tbl, "\n")) -end -function reload_config() - fs.remove("/tmp/AdGuardHometmpconfig.yaml") - http.prepare_content("application/json") - http.write('') -end -function act_status() - local e={} - local binpath=uci:get("AdGuardHome","AdGuardHome","binpath") - e.running=luci.sys.call("pgrep "..binpath.." >/dev/null")==0 - e.redirect=(fs.readfile("/var/run/AdGredir")=="1") - http.prepare_content("application/json") - http.write_json(e) -end -function do_update() - fs.writefile("/var/run/lucilogpos","0") - http.prepare_content("application/json") - http.write('') - local arg - if luci.http.formvalue("force") == "1" then - arg="force" - else - arg="" - end - if fs.access("/var/run/update_core") then - if arg=="force" then - luci.sys.exec("kill $(pgrep /usr/share/AdGuardHome/update_core.sh) ; sh /usr/share/AdGuardHome/update_core.sh "..arg.." >/tmp/AdGuardHome_update.log 2>&1 &") - end - else - luci.sys.exec("sh /usr/share/AdGuardHome/update_core.sh "..arg.." >/tmp/AdGuardHome_update.log 2>&1 &") - end -end -function get_log() - local logfile=uci:get("AdGuardHome","AdGuardHome","logfile") - if (logfile==nil) then - http.write("no log available\n") - return - elseif (logfile=="syslog") then - if not fs.access("/var/run/AdGuardHomesyslog") then - luci.sys.exec("(/usr/share/AdGuardHome/getsyslog.sh &); sleep 1;") - end - logfile="/tmp/AdGuardHometmp.log" - fs.writefile("/var/run/AdGuardHomesyslog","1") - elseif not fs.access(logfile) then - http.write("") - return - end - http.prepare_content("text/plain; charset=utf-8") - local fdp - if fs.access("/var/run/lucilogreload") then - fdp=0 - fs.remove("/var/run/lucilogreload") - else - fdp=tonumber(fs.readfile("/var/run/lucilogpos")) or 0 - end - local f=io.open(logfile, "r+") - f:seek("set",fdp) - local a=f:read(2048000) or "" - fdp=f:seek() - fs.writefile("/var/run/lucilogpos",tostring(fdp)) - f:close() - http.write(a) -end -function do_dellog() - local logfile=uci:get("AdGuardHome","AdGuardHome","logfile") - fs.writefile(logfile,"") - http.prepare_content("application/json") - http.write('') -end -function check_update() - http.prepare_content("text/plain; charset=utf-8") - local fdp=tonumber(fs.readfile("/var/run/lucilogpos")) or 0 - local f=io.open("/tmp/AdGuardHome_update.log", "r+") - f:seek("set",fdp) - local a=f:read(2048000) or "" - fdp=f:seek() - fs.writefile("/var/run/lucilogpos",tostring(fdp)) - f:close() -if fs.access("/var/run/update_core") then - http.write(a) -else - http.write(a.."\0") -end -end diff --git a/luci-app-adguardhome/luasrc/model/cbi/AdGuardHome/base.lua b/luci-app-adguardhome/luasrc/model/cbi/AdGuardHome/base.lua deleted file mode 100755 index 6896b61ef..000000000 --- a/luci-app-adguardhome/luasrc/model/cbi/AdGuardHome/base.lua +++ /dev/null @@ -1,304 +0,0 @@ -require("luci.sys") -require("luci.util") -require("io") -local m,s,o,o1 -local fs=require"nixio.fs" -local uci=require"luci.model.uci".cursor() -local configpath=uci:get("AdGuardHome","AdGuardHome","configpath") or "/etc/AdGuardHome.yaml" -local binpath=uci:get("AdGuardHome","AdGuardHome","binpath") or "/usr/bin/AdGuardHome" -httpport=uci:get("AdGuardHome","AdGuardHome","httpport") or "3000" -m = Map("AdGuardHome", "AdGuard Home") -m.description = translate("Free and open source, powerful network-wide ads & trackers blocking DNS server.") -m:section(SimpleSection).template = "AdGuardHome/AdGuardHome_status" - -s = m:section(TypedSection, "AdGuardHome") -s.anonymous=true -s.addremove=false ----- enable -o = s:option(Flag, "enabled", translate("Enable")) -o.default = 0 -o.optional = false ----- httpport -o =s:option(Value,"httpport",translate("Browser management port")) -o.placeholder=3000 -o.default=3000 -o.datatype="port" -o.optional = false -o.description = translate("") ----- update warning not safe -local binmtime=uci:get("AdGuardHome","AdGuardHome","binmtime") or "0" -local e="" -if not fs.access(configpath) then - e=e.." "..translate("no config") -end -if not fs.access(binpath) then - e=e.." "..translate("no core") -else - local version=uci:get("AdGuardHome","AdGuardHome","version") - local testtime=fs.stat(binpath,"mtime") - if testtime~=tonumber(binmtime) or version==nil then - local tmp=luci.sys.exec(binpath.." --version | grep -m 1 -E 'v[0-9.]+' -o ") - version=string.sub(tmp, 1) - if version=="" then version="core error" end - uci:set("AdGuardHome","AdGuardHome","version",version) - uci:set("AdGuardHome","AdGuardHome","binmtime",testtime) - uci:save("AdGuardHome") - end - e=version..e -end -o=s:option(Button,"restart",translate("Update")) -o.inputtitle=translate("Update core version") -o.template = "AdGuardHome/AdGuardHome_check" -o.showfastconfig=(not fs.access(configpath)) -o.description=string.format(translate("core version:").."%s ",e) ----- port warning not safe -local port=luci.sys.exec("awk '/ port:/{printf($2);exit;}' "..configpath.." 2>nul") -if (port=="") then port="?" end ----- Redirect -o = s:option(ListValue, "redirect", port..translate("Redirect"), translate("AdGuardHome redirect mode")) -o.placeholder = "none" -o:value("none", translate("none")) -o:value("dnsmasq-upstream", translate("Run as dnsmasq upstream server")) -o:value("redirect", translate("Redirect 53 port to AdGuardHome")) -o:value("exchange", translate("Use port 53 replace dnsmasq")) -o.default = "none" -o.optional = true ----- bin path -o = s:option(Value, "binpath", translate("Bin Path"), translate("AdGuardHome Bin path if no bin will auto download")) -o.default = "/usr/bin/AdGuardHome" -o.datatype = "string" -o.optional = false -o.rmempty=false -o.validate=function(self, value) -if value=="" then return nil end -if fs.stat(value,"type")=="dir" then - fs.rmdir(value) -end -if fs.stat(value,"type")=="dir" then - if (m.message) then - m.message =m.message.."\nerror!bin path is a dir" - else - m.message ="error!bin path is a dir" - end - return nil -end -return value -end ---- upx -o = s:option(ListValue, "upxflag", translate("use upx to compress bin after download")) -o:value("", translate("none")) -o:value("-1", translate("compress faster")) -o:value("-9", translate("compress better")) -o:value("--best", translate("compress best(can be slow for big files)")) -o:value("--brute", translate("try all available compression methods & filters [slow]")) -o:value("--ultra-brute", translate("try even more compression variants [very slow]")) -o.default = "" -o.description=translate("bin use less space,but may have compatibility issues") -o.rmempty = true ----- config path -o = s:option(Value, "configpath", translate("Config Path"), translate("AdGuardHome config path")) -o.default = "/etc/AdGuardHome.yaml" -o.datatype = "string" -o.optional = false -o.rmempty=false -o.validate=function(self, value) -if value==nil then return nil end -if fs.stat(value,"type")=="dir" then - fs.rmdir(value) -end -if fs.stat(value,"type")=="dir" then - if m.message then - m.message =m.message.."\nerror!config path is a dir" - else - m.message ="error!config path is a dir" - end - return nil -end -return value -end ----- work dir -o = s:option(Value, "workdir", translate("Work dir"), translate("AdGuardHome work dir include rules,audit log and database")) -o.default = "/etc/AdGuardHome" -o.datatype = "string" -o.optional = false -o.rmempty=false -o.validate=function(self, value) -if value=="" then return nil end -if fs.stat(value,"type")=="reg" then - if m.message then - m.message =m.message.."\nerror!work dir is a file" - else - m.message ="error!work dir is a file" - end - return nil -end -if string.sub(value, -1)=="/" then - return string.sub(value, 1, -2) -else - return value -end -end ----- log file -o = s:option(Value, "logfile", translate("Runtime log file"), translate("AdGuardHome runtime Log file if 'syslog': write to system log;if empty no log")) -o.datatype = "string" -o.rmempty = true -o.validate=function(self, value) -if fs.stat(value,"type")=="dir" then - fs.rmdir(value) -end -if fs.stat(value,"type")=="dir" then - if m.message then - m.message =m.message.."\nerror!log file is a dir" - else - m.message ="error!log file is a dir" - end - return nil -end -return value -end ----- debug -o = s:option(Flag, "verbose", translate("Verbose log")) -o.default = 0 -o.optional = true ----- gfwlist -local a=luci.sys.call("grep -m 1 -q programadd "..configpath) -if (a==0) then -a="Added" -else -a="Not added" -end -o=s:option(Button,"gfwdel",translate("Del gfwlist"),translate(a)) -o.optional = true -o.inputtitle=translate("Del") -o.write=function() - luci.sys.exec("sh /usr/share/AdGuardHome/gfw2adg.sh del 2>&1") - luci.http.redirect(luci.dispatcher.build_url("admin","services","AdGuardHome")) -end -o=s:option(Button,"gfwadd",translate("Add gfwlist"),translate(a)) -o.optional = true -o.inputtitle=translate("Add") -o.write=function() - luci.sys.exec("sh /usr/share/AdGuardHome/gfw2adg.sh 2>&1") - luci.http.redirect(luci.dispatcher.build_url("admin","services","AdGuardHome")) -end -o = s:option(Value, "gfwupstream", translate("Gfwlist upstream dns server"), translate("Gfwlist domain upstream dns service")..translate(a)) -o.default = "tcp://208.67.220.220:5353" -o.datatype = "string" -o.optional = true ----- chpass -o = s:option(Value, "hashpass", translate("Change browser management password"), translate("Press load culculate model and culculate finally save/apply")) -o.default = "" -o.datatype = "string" -o.template = "AdGuardHome/AdGuardHome_chpass" -o.optional = true ----- upgrade protect -o = s:option(MultiValue, "upprotect", translate("Keep files when system upgrade")) -o:value("$binpath",translate("core bin")) -o:value("$configpath",translate("config file")) -o:value("$logfile",translate("log file")) -o:value("$workdir/data/sessions.db",translate("sessions.db")) -o:value("$workdir/data/stats.db",translate("stats.db")) -o:value("$workdir/data/querylog.json",translate("querylog.json")) -o:value("$workdir/data/filters",translate("filters")) -o.widget = "checkbox" -o.default = nil -o.optional=true ----- wait net on boot -o = s:option(Flag, "waitonboot", translate("On boot when network ok restart")) -o.default = 1 -o.optional = true ----- backup workdir on shutdown -local workdir=uci:get("AdGuardHome","AdGuardHome","workdir") or "/etc/AdGuardHome" -o = s:option(MultiValue, "backupfile", translate("Backup workdir files when shutdown")) -o1 = s:option(Value, "backupwdpath", translate("Backup workdir path")) -local name -o:value("filters","filters") -o:value("stats.db","stats.db") -o:value("querylog.json","querylog.json") -o:value("sessions.db","sessions.db") -o1:depends ("backupfile", "filters") -o1:depends ("backupfile", "stats.db") -o1:depends ("backupfile", "querylog.json") -o1:depends ("backupfile", "sessions.db") -for name in fs.glob(workdir.."/data/*") -do - name=fs.basename (name) - if name~="filters" and name~="stats.db" and name~="querylog.json" and name~="sessions.db" then - o:value(name,name) - o1:depends ("backupfile", name) - end -end -o.widget = "checkbox" -o.default = nil -o.optional=false -o.description=translate("Will be restore when workdir/data is empty") -----backup workdir path - -o1.default = "/etc/AdGuardHome" -o1.datatype = "string" -o1.optional = false -o1.validate=function(self, value) -if fs.stat(value,"type")=="reg" then - if m.message then - m.message =m.message.."\nerror!backup dir is a file" - else - m.message ="error!backup dir is a file" - end - return nil -end -if string.sub(value,-1)=="/" then - return string.sub(value, 1, -2) -else - return value -end -end - -----Crontab -o = s:option(MultiValue, "crontab", translate("Crontab task"),translate("Please change time and args in crontab")) -o:value("autoupdate",translate("Auto update core")) -o:value("cutquerylog",translate("Auto tail querylog")) -o:value("cutruntimelog",translate("Auto tail runtime log")) -o:value("autohost",translate("Auto update ipv6 hosts and restart adh")) -o:value("autogfw",translate("Auto update gfwlist and restart adh")) -o.widget = "checkbox" -o.default = nil -o.optional=true - -----downloadpath -o = s:option(TextValue, "downloadlinks",translate("Download links for update")) -o.optional = false -o.rows = 4 -o.wrap = "soft" -o.cfgvalue = function(self, section) - return fs.readfile("/usr/share/AdGuardHome/links.txt") -end -o.write = function(self, section, value) - fs.writefile("/usr/share/AdGuardHome/links.txt", value:gsub("\r\n", "\n")) -end -fs.writefile("/var/run/lucilogpos","0") -function m.on_commit(map) - if (fs.access("/var/run/AdGserverdis")) then - io.popen("/etc/init.d/AdGuardHome reload &") - return - end - local ucitracktest=uci:get("AdGuardHome","AdGuardHome","ucitracktest") - if ucitracktest=="1" then - return - elseif ucitracktest=="0" then - io.popen("/etc/init.d/AdGuardHome reload &") - else - if (fs.access("/var/run/AdGlucitest")) then - uci:set("AdGuardHome","AdGuardHome","ucitracktest","0") - io.popen("/etc/init.d/AdGuardHome reload &") - else - fs.writefile("/var/run/AdGlucitest","") - if (ucitracktest=="2") then - uci:set("AdGuardHome","AdGuardHome","ucitracktest","1") - else - uci:set("AdGuardHome","AdGuardHome","ucitracktest","2") - end - end - uci:save("AdGuardHome") - end -end -return m diff --git a/luci-app-adguardhome/luasrc/model/cbi/AdGuardHome/log.lua b/luci-app-adguardhome/luasrc/model/cbi/AdGuardHome/log.lua deleted file mode 100755 index 5d18a88db..000000000 --- a/luci-app-adguardhome/luasrc/model/cbi/AdGuardHome/log.lua +++ /dev/null @@ -1,16 +0,0 @@ -local fs=require"nixio.fs" -local uci=require"luci.model.uci".cursor() -local f,t -f=SimpleForm("logview") -f.reset = false -f.submit = false -t=f:field(TextValue,"conf") -t.rmempty=true -t.rows=20 -t.template="AdGuardHome/log" -t.readonly="readonly" -local logfile=uci:get("AdGuardHome","AdGuardHome","logfile") or "" -t.timereplace=(logfile~="syslog" and logfile~="" ) -t.pollcheck=logfile~="" -fs.writefile("/var/run/lucilogreload","") -return f diff --git a/luci-app-adguardhome/luasrc/model/cbi/AdGuardHome/manual.lua b/luci-app-adguardhome/luasrc/model/cbi/AdGuardHome/manual.lua deleted file mode 100755 index ecf072bbc..000000000 --- a/luci-app-adguardhome/luasrc/model/cbi/AdGuardHome/manual.lua +++ /dev/null @@ -1,97 +0,0 @@ -local m, s, o -local fs = require "nixio.fs" -local uci=require"luci.model.uci".cursor() -local sys=require"luci.sys" -require("string") -require("io") -require("table") -function gen_template_config() - local b - local d="" - for cnt in io.lines("/tmp/resolv.conf.d/resolv.conf.auto") do - b=string.match (cnt,"^[^#]*nameserver%s+([^%s]+)$") - if (b~=nil) then - d=d.." - "..b.."\n" - end - end - local f=io.open("/usr/share/AdGuardHome/AdGuardHome_template.yaml", "r+") - local tbl = {} - local a="" - while (1) do - a=f:read("*l") - if (a=="#bootstrap_dns") then - a=d - elseif (a=="#upstream_dns") then - a=d - elseif (a==nil) then - break - end - table.insert(tbl, a) - end - f:close() - return table.concat(tbl, "\n") -end -m = Map("AdGuardHome") -local configpath = uci:get("AdGuardHome","AdGuardHome","configpath") -local binpath = uci:get("AdGuardHome","AdGuardHome","binpath") -s = m:section(TypedSection, "AdGuardHome") -s.anonymous=true -s.addremove=false ---- config -o = s:option(TextValue, "escconf") -o.rows = 66 -o.wrap = "off" -o.rmempty = true -o.cfgvalue = function(self, section) - return fs.readfile("/tmp/AdGuardHometmpconfig.yaml") or fs.readfile(configpath) or gen_template_config() or "" -end -o.validate=function(self, value) - fs.writefile("/tmp/AdGuardHometmpconfig.yaml", value:gsub("\r\n", "\n")) - if fs.access(binpath) then - if (sys.call(binpath.." -c /tmp/AdGuardHometmpconfig.yaml --check-config 2> /tmp/AdGuardHometest.log")==0) then - return value - end - else - return value - end - luci.http.redirect(luci.dispatcher.build_url("admin","services","AdGuardHome","manual")) - return nil -end -o.write = function(self, section, value) - fs.move("/tmp/AdGuardHometmpconfig.yaml",configpath) -end -o.remove = function(self, section, value) - fs.writefile(configpath, "") -end ---- js and reload button -o = s:option(DummyValue, "") -o.anonymous=true -o.template = "AdGuardHome/yamleditor" -if not fs.access(binpath) then - o.description=translate("WARNING!!! no bin found apply config will not be test") -end ---- log -if (fs.access("/tmp/AdGuardHometmpconfig.yaml")) then -local c=fs.readfile("/tmp/AdGuardHometest.log") -if (c~="") then -o = s:option(TextValue, "") -o.readonly=true -o.rows = 5 -o.rmempty = true -o.name="" -o.cfgvalue = function(self, section) - return fs.readfile("/tmp/AdGuardHometest.log") -end -end -end -function m.on_commit(map) - local ucitracktest=uci:get("AdGuardHome","AdGuardHome","ucitracktest") - if ucitracktest=="1" then - return - elseif ucitracktest=="0" then - io.popen("/etc/init.d/AdGuardHome reload &") - else - fs.writefile("/var/run/AdGlucitest","") - end -end -return m diff --git a/luci-app-adguardhome/luasrc/view/AdGuardHome/AdGuardHome_check.htm b/luci-app-adguardhome/luasrc/view/AdGuardHome/AdGuardHome_check.htm deleted file mode 100755 index 832a1df46..000000000 --- a/luci-app-adguardhome/luasrc/view/AdGuardHome/AdGuardHome_check.htm +++ /dev/null @@ -1,78 +0,0 @@ -<%+cbi/valueheader%> -<%local fs=require"nixio.fs"%> - - -<% if self.showfastconfig then %> - -<%end%> - - -<%+cbi/valuefooter%> diff --git a/luci-app-adguardhome/luasrc/view/AdGuardHome/AdGuardHome_chpass.htm b/luci-app-adguardhome/luasrc/view/AdGuardHome/AdGuardHome_chpass.htm deleted file mode 100755 index b6ff3ebb3..000000000 --- a/luci-app-adguardhome/luasrc/view/AdGuardHome/AdGuardHome_chpass.htm +++ /dev/null @@ -1,49 +0,0 @@ -<%+cbi/valueheader%> - - 0, "data-choices", { self.keylist, self.vallist }) - %> /> - <% if self.password then %><% end %> - -<%+cbi/valuefooter%> diff --git a/luci-app-adguardhome/luasrc/view/AdGuardHome/AdGuardHome_status.htm b/luci-app-adguardhome/luasrc/view/AdGuardHome/AdGuardHome_status.htm deleted file mode 100755 index 7e924d119..000000000 --- a/luci-app-adguardhome/luasrc/view/AdGuardHome/AdGuardHome_status.htm +++ /dev/null @@ -1,27 +0,0 @@ - - -
-

- <%:Collecting data...%> -

-
\ No newline at end of file diff --git a/luci-app-adguardhome/luasrc/view/AdGuardHome/log.htm b/luci-app-adguardhome/luasrc/view/AdGuardHome/log.htm deleted file mode 100755 index 11a1f787a..000000000 --- a/luci-app-adguardhome/luasrc/view/AdGuardHome/log.htm +++ /dev/null @@ -1,111 +0,0 @@ -<%+cbi/valueheader%> -<%:reverse%> -<%if self.timereplace then%> -<%:localtime%>
-<%end%> - - - - -<%+cbi/valuefooter%> diff --git a/luci-app-adguardhome/luasrc/view/AdGuardHome/yamleditor.htm b/luci-app-adguardhome/luasrc/view/AdGuardHome/yamleditor.htm deleted file mode 100755 index 639cb9988..000000000 --- a/luci-app-adguardhome/luasrc/view/AdGuardHome/yamleditor.htm +++ /dev/null @@ -1,39 +0,0 @@ -<%+cbi/valueheader%> - - - - - - - - - -<%fs=require"nixio.fs"%> -<%if fs.access("/tmp/AdGuardHometmpconfig.yaml") then%> - -<%end%> - -<%+cbi/valuefooter%> \ No newline at end of file diff --git a/luci-app-adguardhome/po/zh-cn b/luci-app-adguardhome/po/zh-cn deleted file mode 100755 index 8d69574dd..000000000 --- a/luci-app-adguardhome/po/zh-cn +++ /dev/null @@ -1 +0,0 @@ -zh_Hans \ No newline at end of file diff --git a/luci-app-adguardhome/po/zh_Hans/adguardhome.po b/luci-app-adguardhome/po/zh_Hans/adguardhome.po deleted file mode 100755 index 0ace89bae..000000000 --- a/luci-app-adguardhome/po/zh_Hans/adguardhome.po +++ /dev/null @@ -1,408 +0,0 @@ -msgid "" -msgstr "" -"Content-Type: text/plain; charset=UTF-8\n" -"Project-Id-Version: PACKAGE VERSION\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" -"Language: zh_Hans\n" -"MIME-Version: 1.0\n" -"Content-Transfer-Encoding: 8bit\n" - -#: /mnt/A/openwrt-latest/package/ctcgfw/luci-app-adguardhome/luasrc/model/cbi/AdGuardHome/base.lua:27 -msgid "" -"/dev/null 2>&1 - if [ $? -eq 0 ]; then - return - fi - uci delete dhcp.@dnsmasq[0].server 2>/dev/null - uci add_list dhcp.@dnsmasq[0].server=$addr - for server in $OLD_SERVER; do - if [ "$server" = "$addr" ]; then - continue - fi - # uci add_list dhcp.@dnsmasq[0].server=$server - done - uci delete dhcp.@dnsmasq[0].resolvfile 2>/dev/null - uci set dhcp.@dnsmasq[0].noresolv=1 - uci commit dhcp - /etc/init.d/dnsmasq restart -} - -stop_forward_dnsmasq() -{ - local OLD_PORT="$1" - addr="127.0.0.1#$OLD_PORT" - OLD_SERVER="`uci get dhcp.@dnsmasq[0].server 2>/dev/null`" - echo $OLD_SERVER | grep "^$addr" >/dev/null 2>&1 - if [ $? -ne 0 ]; then - return - fi - - uci del_list dhcp.@dnsmasq[0].server=$addr 2>/dev/null - addrlist="`uci get dhcp.@dnsmasq[0].server 2>/dev/null`" - if [ -z "$addrlist" ] ; then - uci set dhcp.@dnsmasq[0].resolvfile=/tmp/resolv.conf.d/resolv.conf.auto 2>/dev/null - uci delete dhcp.@dnsmasq[0].noresolv 2>/dev/null - fi - uci commit dhcp - /etc/init.d/dnsmasq restart -} - -set_iptable() -{ - local ipv6_server=$1 - local tcp_server=$2 - uci -q batch <<-EOF >/dev/null 2>&1 - delete firewall.AdGuardHome - set firewall.AdGuardHome=include - set firewall.AdGuardHome.type=script - set firewall.AdGuardHome.path=/usr/share/AdGuardHome/firewall.start - set firewall.AdGuardHome.reload=1 - commit firewall -EOF - - IPS="`ifconfig | grep "inet addr" | grep -v ":127" | grep "Bcast" | awk '{print $2}' | awk -F : '{print $2}'`" - for IP in $IPS - do - if [ "$tcp_server" == "1" ]; then - iptables -t nat -A PREROUTING -p tcp -d $IP --dport 53 -j REDIRECT --to-ports $AdGuardHome_PORT >/dev/null 2>&1 - fi - iptables -t nat -A PREROUTING -p udp -d $IP --dport 53 -j REDIRECT --to-ports $AdGuardHome_PORT >/dev/null 2>&1 - done - - if [ "$ipv6_server" == 0 ]; then - return - fi - - IPS="`ifconfig | grep "inet6 addr" | grep -v " fe80::" | grep -v " ::1" | grep "Global" | awk '{print $3}'`" - for IP in $IPS - do - if [ "$tcp_server" == "1" ]; then - ip6tables -t nat -A PREROUTING -p tcp -d $IP --dport 53 -j REDIRECT --to-ports $AdGuardHome_PORT >/dev/null 2>&1 - fi - ip6tables -t nat -A PREROUTING -p udp -d $IP --dport 53 -j REDIRECT --to-ports $AdGuardHome_PORT >/dev/null 2>&1 - done -} - -clear_iptable() -{ - uci -q batch <<-EOF >/dev/null 2>&1 - delete firewall.AdGuardHome - commit firewall -EOF - local OLD_PORT="$1" - local ipv6_server=$2 - IPS="`ifconfig | grep "inet addr" | grep -v ":127" | grep "Bcast" | awk '{print $2}' | awk -F : '{print $2}'`" - for IP in $IPS - do - iptables -t nat -D PREROUTING -p udp -d $IP --dport 53 -j REDIRECT --to-ports $OLD_PORT >/dev/null 2>&1 - iptables -t nat -D PREROUTING -p tcp -d $IP --dport 53 -j REDIRECT --to-ports $OLD_PORT >/dev/null 2>&1 - done - - if [ "$ipv6_server" == 0 ]; then - return - fi - echo "warn ip6tables nat mod is needed" - IPS="`ifconfig | grep "inet6 addr" | grep -v " fe80::" | grep -v " ::1" | grep "Global" | awk '{print $3}'`" - for IP in $IPS - do - ip6tables -t nat -D PREROUTING -p udp -d $IP --dport 53 -j REDIRECT --to-ports $OLD_PORT >/dev/null 2>&1 - ip6tables -t nat -D PREROUTING -p tcp -d $IP --dport 53 -j REDIRECT --to-ports $OLD_PORT >/dev/null 2>&1 - done -} - -service_triggers() { - procd_add_reload_trigger "$CONFIGURATION" - [ "$(uci get AdGuardHome.AdGuardHome.redirect)" == "redirect" ] && procd_add_reload_trigger firewall -} - -isrunning(){ - config_load "${CONFIGURATION}" - _isrunning - local r=$? - ([ "$r" == "0" ] && echo "running") || ([ "$r" == "1" ] && echo "not run" ) || echo "no bin" - return $r -} - -_isrunning(){ - config_get binpath $CONFIGURATION binpath "/usr/bin/AdGuardHome" - [ ! -f "$binpath" ] && return 2 - pgrep $binpath 2>&1 >/dev/null && return 0 - return 1 -} - -force_reload(){ - config_load "${CONFIGURATION}" - _isrunning && procd_send_signal "$CONFIGURATION" || start -} - -get_tz() -{ - SET_TZ="" - - if [ -e "/etc/localtime" ]; then - return - fi - - for tzfile in /etc/TZ /var/etc/TZ - do - if [ ! -e "$tzfile" ]; then - continue - fi - - tz="`cat $tzfile 2>/dev/null`" - done - - if [ -z "$tz" ]; then - return - fi - - SET_TZ=$tz -} - -rm_port53() -{ - local AdGuardHome_PORT=$(config_editor "dns.port" "" "$configpath" "1") - dnsmasq_port=$(uci get dhcp.@dnsmasq[0].port 2>/dev/null) - if [ -z "$dnsmasq_port" ]; then - dnsmasq_port="53" - fi - if [ "$dnsmasq_port" == "$AdGuardHome_PORT" ]; then - if [ "$dnsmasq_port" == "53" ]; then - dnsmasq_port="1745" - fi - elif [ "$dnsmasq_port" == "53" ]; then - return - fi - config_editor "dns.port" "$dnsmasq_port" "$configpath" - uci set dhcp.@dnsmasq[0].port="53" - uci commit dhcp - config_get binpath $CONFIGURATION binpath "/usr/bin/AdGuardHome" - killall -9 $binpath - /etc/init.d/dnsmasq restart -} - -use_port53() -{ - local AdGuardHome_PORT=$(config_editor "dns.port" "" "$configpath" "1") - dnsmasq_port=$(uci get dhcp.@dnsmasq[0].port 2>/dev/null) - if [ -z "$dnsmasq_port" ]; then - dnsmasq_port="53" - fi - if [ "$dnsmasq_port" == "$AdGuardHome_PORT" ]; then - if [ "$dnsmasq_port" == "53" ]; then - AdGuardHome_PORT="1745" - fi - elif [ "$AdGuardHome_PORT" == "53" ]; then - return - fi - config_editor "dns.port" "53" "$configpath" - uci set dhcp.@dnsmasq[0].port="$AdGuardHome_PORT" - uci commit dhcp - /etc/init.d/dnsmasq reload -} - -do_redirect() -{ - config_load "${CONFIGURATION}" - _do_redirect $1 -} - -_do_redirect() -{ - local section="$CONFIGURATION" - args="" - ipv6_server=1 - tcp_server=0 - enabled=$1 - if [ "$enabled" == "1" ]; then - echo -n "1">/var/run/AdGredir - else - echo -n "0">/var/run/AdGredir - fi - config_get configpath $CONFIGURATION configpath "/etc/AdGuardHome.yaml" - AdGuardHome_PORT=$(config_editor "dns.port" "" "$configpath" "1") - if [ ! -s "$configpath" ]; then - cp -f /usr/share/AdGuardHome/AdGuardHome_template.yaml $configpath - fi - if [ -z "$AdGuardHome_PORT" ]; then - AdGuardHome_PORT="0" - fi - config_get "redirect" "$section" "redirect" "none" - config_get "old_redirect" "$section" "old_redirect" "none" - config_get "old_port" "$section" "old_port" "0" - config_get "old_enabled" "$section" "old_enabled" "0" - uci get dhcp.@dnsmasq[0].port >/dev/null 2>&1 || uci set dhcp.@dnsmasq[0].port="53" >/dev/null 2>&1 - if [ "$old_enabled" = "1" -a "$old_redirect" == "exchange" ]; then - AdGuardHome_PORT=$(uci get dhcp.@dnsmasq[0].port 2>/dev/null) - fi - - if [ "$old_redirect" != "$redirect" ] || [ "$old_port" != "$AdGuardHome_PORT" ] || [ "$old_enabled" = "1" -a "$enabled" = "0" ]; then - if [ "$old_redirect" != "none" ]; then - if [ "$old_redirect" == "redirect" -a "$old_port" != "0" ]; then - clear_iptable "$old_port" "$ipv6_server" - elif [ "$old_redirect" == "dnsmasq-upstream" ]; then - stop_forward_dnsmasq "$old_port" - elif [ "$old_redirect" == "exchange" ]; then - rm_port53 - fi - fi - elif [ "$old_enabled" = "1" -a "$enabled" = "1" ]; then - if [ "$old_redirect" == "redirect" -a "$old_port" != "0" ]; then - clear_iptable "$old_port" "$ipv6_server" - fi - fi - uci delete AdGuardHome.@AdGuardHome[0].old_redirect 2>/dev/null - uci delete AdGuardHome.@AdGuardHome[0].old_port 2>/dev/null - uci delete AdGuardHome.@AdGuardHome[0].old_enabled 2>/dev/null - uci add_list AdGuardHome.@AdGuardHome[0].old_redirect="$redirect" 2>/dev/null - uci add_list AdGuardHome.@AdGuardHome[0].old_port="$AdGuardHome_PORT" 2>/dev/null - uci add_list AdGuardHome.@AdGuardHome[0].old_enabled="$enabled" 2>/dev/null - uci commit AdGuardHome - [ "$enabled" == "0" ] && return 1 - if [ "$AdGuardHome_PORT" == "0" ]; then - return 1 - fi - if [ "$redirect" = "redirect" ]; then - set_iptable $ipv6_server $tcp_server - elif [ "$redirect" = "dnsmasq-upstream" ]; then - set_forward_dnsmasq "$AdGuardHome_PORT" - elif [ "$redirect" == "exchange" -a "$(uci get dhcp.@dnsmasq[0].port 2>/dev/null)" == "53" ]; then - use_port53 - fi -} - -get_filesystem() -{ -# print out path filesystem - echo $1 | awk ' - BEGIN{ - while (("mount"| getline ret) > 0) - { - split(ret,d); - fs[d[3]]=d[5]; - m=index(d[1],":") - if (m==0) - { - pt[d[3]]=d[1] - }else{ - pt[d[3]]=substr(d[1],m+1) - }}}{ - split($0,d,"/"); - if ("/" in fs) - { - result1=fs["/"]; - } - if ("/" in pt) - { - result2=pt["/"]; - } - for (i=2;i<=length(d);i++) - { - p[i]=p[i-1]"/"d[i]; - if (p[i] in fs) - { - result1=fs[p[i]]; - result2=pt[p[i]]; - } - } - if (result2 in fs){ - result=fs[result2]} - else{ - result=result1} - print(result);}' -} - -config_editor() -{ - awk -v yaml="$1" -v value="$2" -v file="$3" -v ro="$4" ' - BEGIN{split(yaml,part,"\.");s="";i=1;l=length(part);} - { - if (match($0,s""part[i]":")) - { - if (i==l) - { - split($0,t,": "); - if (ro==""){ - system("sed -i '\''"FNR"c \\"t[1]": "value"'\'' "file); - }else{ - print(t[2]); - } - exit; - } - s=s"[- ]{2}"; - i++; - } - }' $3 -} - -boot_service() { - rm /var/run/AdGserverdis >/dev/null 2>&1 - config_load "${CONFIGURATION}" - config_get waitonboot $CONFIGURATION waitonboot "0" - config_get_bool enabled $CONFIGURATION enabled 0 - config_get binpath $CONFIGURATION binpath "/usr/bin/AdGuardHome" - [ -f "$binpath" ] && start_service - if [ "$enabled" == "1" ] && [ "$waitonboot" == "1" ]; then - procd_open_instance "waitnet" - procd_set_param command "/usr/share/AdGuardHome/waitnet.sh" - procd_close_instance - echo "no net start pinging" - fi -} - -testbackup(){ - config_load "${CONFIGURATION}" - if [ "$1" == "backup" ]; then - backup - elif [ "$1" == "restore" ]; then - restore - fi -} - -restore() -{ - config_get workdir $CONFIGURATION workdir "/etc/AdGuardHome" - config_get backupwdpath $CONFIGURATION backupwdpath "/etc/AdGuardHome" - cp -u -r -f $backupwdpath/data $workdir -} - -backup() { - config_get backupwdpath $CONFIGURATION backupwdpath "/etc/AdGuardHome" - mkdir -p $backupwdpath/data - config_get workdir $CONFIGURATION workdir "/etc/AdGuardHome" - config_get backupfile $CONFIGURATION backupfile "" - for one in $backupfile; - do - while : - do - if [ -d "$backupwdpath/data/$one" ]; then - cpret=$(cp -u -r -f $workdir/data/$one $backupwdpath/data 2>&1) - else - cpret=$(cp -u -r -f $workdir/data/$one $backupwdpath/data/$one 2>&1) - fi - echo "$cpret" - echo "$cpret" | grep "no space left on device" - if [ "$?" == "0" ]; then - echo "磁盘已满,删除log重试中" - del_querylog && continue - rm -f -r $backupwdpath/data/filters - rm -f -r $workdir/data/filters && continue - echo "backup failed" - fi - break - done - done -} - -start_service() { - # Reading config - rm /var/run/AdGserverdis >/dev/null 2>&1 - config_load "${CONFIGURATION}" - # update password - config_get hashpass $CONFIGURATION hashpass "" - config_get configpath $CONFIGURATION configpath "/etc/AdGuardHome.yaml" - if [ -n "$hashpass" ]; then - config_editor "users.password" "$hashpass" "$configpath" - uci set $CONFIGURATION.$CONFIGURATION.hashpass="" - fi - local enabled - config_get_bool enabled $CONFIGURATION enabled 0 - # update crontab - do_crontab - if [ "$enabled" == "0" ]; then - _do_redirect 0 - return - fi - #what need to do before reload - config_get workdir $CONFIGURATION workdir "/etc/AdGuardHome" - - config_get backupfile $CONFIGURATION backupfile "" - mkdir -p $workdir/data - if [ -n "$backupfile" ] && [ ! -d "$workdir/data" ]; then - restore - fi - # for overlay data-stk-oo not suppport - local cwdfs=$(get_filesystem $workdir) - echo "workdir is a $cwdfs filesystem" - if [ "$cwdfs" == "jffs2" ]; then - echo "fs error ln db to tmp $workdir $cwdfs" - logger "AdGuardHome" "warning db redirect to tmp" - touch $workdir/data/stats.db - if [ ! -L $workdir/data/stats.db ]; then - mv -f $workdir/data/stats.db /tmp/stats.db 2>/dev/null - ln -s /tmp/stats.db $workdir/data/stats.db 2>/dev/null - fi - touch $workdir/data/sessions.db - if [ ! -L $workdir/data/sessions.db ]; then - mv -f $workdir/data/sessions.db /tmp/sessions.db 2>/dev/null - ln -s /tmp/sessions.db $workdir/data/sessions.db 2>/dev/null - fi - fi - local ADDITIONAL_ARGS="" - config_get binpath $CONFIGURATION binpath "/usr/bin/AdGuardHome" - - mkdir -p ${binpath%/*} - ADDITIONAL_ARGS="$ADDITIONAL_ARGS -c $configpath" - ADDITIONAL_ARGS="$ADDITIONAL_ARGS -w $workdir" - config_get httpport $CONFIGURATION httpport 3000 - ADDITIONAL_ARGS="$ADDITIONAL_ARGS -p $httpport" - - # hack to save config file when upgrade system - config_get upprotect $CONFIGURATION upprotect "" - eval upprotect=${upprotect// /\\\\n} - echo -e "$upprotect">/lib/upgrade/keep.d/luci-app-adguardhome - - config_get logfile $CONFIGURATION logfile "" - if [ -n "$logfile" ]; then - ADDITIONAL_ARGS="$ADDITIONAL_ARGS -l $logfile" - fi - - if [ ! -f "$binpath" ]; then - _do_redirect 0 - /usr/share/AdGuardHome/update_core.sh 2>&1 >/tmp/AdGuardHome_update.log & - exit 0 - fi - - config_get_bool verbose $CONFIGURATION verbose 0 - if [ "$verbose" -eq 1 ]; then - ADDITIONAL_ARGS="$ADDITIONAL_ARGS -v" - fi - - procd_open_instance - get_tz - if [ -n "$SET_TZ" ]; then - procd_set_param env TZ="$SET_TZ" - fi - procd_set_param respawn ${respawn_threshold:-3600} ${respawn_timeout:-5} ${respawn_retry:-5} - procd_set_param limits core="unlimited" nofile="65535 65535" - procd_set_param stderr 1 - procd_set_param command $binpath $ADDITIONAL_ARGS - procd_set_param file "$configpath" "/etc/hosts" "/etc/config/AdGuardHome" - procd_close_instance - if [ -f "$configpath" ]; then - _do_redirect 1 - else - _do_redirect 0 - config_get "redirect" "AdGuardHome" "redirect" "none" - if [ "$redirect" != "none" ]; then - procd_open_instance "waitconfig" - procd_set_param command "/usr/share/AdGuardHome/watchconfig.sh" - procd_close_instance - echo "no config start watching" - fi - fi - echo "AdGuardHome service enabled" - echo "luci enable switch=$enabled" - (sleep 10 && [ -z "$(pgrep $binpath)" ] && logger "AdGuardHome" "no process in 10s cancel redirect" && _do_redirect 0 )& - if [[ "`uci get bypass.@global[0].global_server 2>/dev/null`" && "`uci get bypass.@global[0].adguardhome 2>/dev/null`" == 1 && "$(uci get dhcp.@dnsmasq[0].port)" == "53" ]]; then - uci -q set AdGuardHome.AdGuardHome.redirect='exchange' - uci commit AdGuardHome - do_redirect 1 - fi -} - -reload_service() -{ - rm /var/run/AdGlucitest >/dev/null 2>&1 - echo "AdGuardHome reloading" - start -} - -del_querylog(){ - local btarget=$(ls $backupwdpath/data | grep -F "querylog.json" | sort -r | head -n 1) - local wtarget=$(ls $workdir/data | grep -F "querylog.json" | sort -r | head -n 1) - if [ "$btarget"x == "$wtarget"x ]; then - [ -z "$btarget" ] && return 1 - rm -f $workdir/data/$wtarget - rm -f $backupwdpath/data/$btarget - return 0 - fi - if [ "$btarget" \> "$wtarget" ]; then - rm -f $backupwdpath/data/$btarget - return 0 - else - rm -f $workdir/data/$wtarget - return 0 - fi -} - -stop_service() -{ - config_load "${CONFIGURATION}" - _do_redirect 0 - do_crontab - if [ "$1" != "nobackup" ]; then - config_get backupfile $CONFIGURATION backupfile "0" - if [ -n "$backupfile" ]; then - backup - fi - fi - echo "AdGuardHome service disabled" - touch /var/run/AdGserverdis -} - -boot() { - rc_procd boot_service "$@" - if eval "type service_started" 2>/dev/null >/dev/null; then - service_started - fi -} - -test_crontab(){ - config_load "${CONFIGURATION}" - do_crontab -} - -do_crontab(){ - config_get_bool enabled $CONFIGURATION enabled 0 - config_get crontab $CONFIGURATION crontab "" - local findstr default cronenable replace commit - local cronreload=0 - local commit=0 - findstr="/usr/share/AdGuardHome/update_core.sh" - default="30 3 * * * /usr/share/AdGuardHome/update_core.sh 2>&1" - [ "$enabled" == "0" ] || [ "${crontab//autoupdate/}" == "$crontab" ] && cronenable=0 || cronenable=1 - crontab_editor - - config_get workdir $CONFIGURATION workdir "/etc/AdGuardHome" - config_get lastworkdir $CONFIGURATION lastworkdir "/etc/AdGuardHome" - findstr="/usr/share/AdGuardHome/tailto.sh [0-9]* \$(uci get AdGuardHome.AdGuardHome.workdir)/data/querylog.json" - #[ -n "$lastworkdir" ] && findstr="/usr/share/AdGuardHome/tailto.sh [0-9]* $lastworkdir/data/querylog.json" && [ "$lastworkdir" != "$workdir" ] && replace="${lastworkdir//\//\\/}/${workdir//\//\\/}" - default="0 * * * * /usr/share/AdGuardHome/tailto.sh 2000 \$(uci get AdGuardHome.AdGuardHome.workdir)/data/querylog.json" - [ "$enabled" == "0" ] || [ "${crontab//cutquerylog/}" == "$crontab" ] && cronenable=0 || cronenable=1 - crontab_editor - #[ "$lastworkdir" != "$workdir" ] && uci set AdGuardHome.AdGuardHome.lastworkdir="$workdir" && commit=1 - - config_get logfile $CONFIGURATION logfile "" - config_get lastlogfile $CONFIGURATION lastlogfile "" - findstr="/usr/share/AdGuardHome/tailto.sh [0-9]* \$(uci get AdGuardHome.AdGuardHome.logfile)" - default="30 3 * * * /usr/share/AdGuardHome/tailto.sh 2000 \$(uci get AdGuardHome.AdGuardHome.logfile)" - #[ -n "$lastlogfile" ] && findstr="/usr/share/AdGuardHome/tailto.sh [0-9]* $lastlogfile" && [ -n "$logfile" ] && [ "$lastlogfile" != "$logfile" ] && replace="${lastlogfile//\//\\/}/${logfile//\//\\/}" - [ "$logfile" == "syslog" ] || [ "$logfile" == "" ] || [ "$enabled" == "0" ] || [ "${crontab//cutruntimelog/}" == "$crontab" ] && cronenable=0 || cronenable=1 - crontab_editor - #[ -n "$logfile" ] && [ "$lastlogfile" != "$logfile" ] && uci set AdGuardHome.AdGuardHome.lastlogfile="$logfile" && commit=1 - - findstr="/usr/share/AdGuardHome/addhost.sh" - default="0 * * * * /usr/share/AdGuardHome/addhost.sh" - [ "$enabled" == "0" ] || [ "${crontab//autohost/}" == "$crontab" ] && cronenable=0 || cronenable=1 - crontab_editor - [ "$cronenable" == "0" ] && /usr/share/AdGuardHome/addhost.sh "del" "noreload" || /usr/share/AdGuardHome/addhost.sh "" "noreload" - - findstr="/usr/share/AdGuardHome/gfw2adg.sh" - default="30 3 * * * /usr/share/AdGuardHome/gfw2adg.sh" - [ "$enabled" == "0" ] || [ "${crontab//autogfw/}" == "$crontab" ] && cronenable=0 || cronenable=1 - crontab_editor - [ "$cronreload" -gt 0 ] && /etc/init.d/cron restart - #[ "$commit" -gt 0 ] && uci commit AdGuardHome -} - -crontab_editor(){ - #usage input: - #findstr= - #default= - #cronenable= - #replace="${last//\//\\/}/${now//\//\\/}" - #output:cronreload:if >1 please /etc/init.d/cron restart manual - local testline reload - local line="$(grep "$findstr" $CRON_FILE)" - [ -n "$replace" ] && [ -n "$line" ] && eval testline="\${line//$replace}" && [ "$testline" != "$line" ] && line="$testline" && reload="1" && replace="" - if [ "${line:0:1}" != "#" ]; then - if [ $cronenable -eq 1 ]; then - [ -z "$line" ] && line="$default" && reload="1" - if [ -n "$reload" ]; then - sed -i "\,$findstr,d" $CRON_FILE - echo "$line" >> $CRON_FILE - cronreload=$((cronreload+1)) - fi - elif [ -n "$line" ]; then - sed -i "\,$findstr,d" $CRON_FILE - echo "#$line" >> $CRON_FILE - cronreload=$((cronreload+1)) - fi - else - if [ $cronenable -eq 1 ]; then - sed -i "\,$findstr,d" $CRON_FILE - echo "${line:1}" >> $CRON_FILE - cronreload=$((cronreload+1)) - elif [ -z "$reload" ]; then - sed -i "\,$findstr,d" $CRON_FILE - echo "$line" >> $CRON_FILE - fi - fi -} diff --git a/luci-app-adguardhome/root/etc/uci-defaults/40_luci-AdGuardHome b/luci-app-adguardhome/root/etc/uci-defaults/40_luci-AdGuardHome deleted file mode 100755 index 37e192cdd..000000000 --- a/luci-app-adguardhome/root/etc/uci-defaults/40_luci-AdGuardHome +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -uci -q batch <<-EOF >/dev/null 2>&1 - delete ucitrack.@AdGuardHome[-1] - add ucitrack AdGuardHome - set ucitrack.@AdGuardHome[-1].init=AdGuardHome - commit ucitrack - delete AdGuardHome.AdGuardHome.ucitracktest - /etc/init.d/AdGuardHome restart -EOF - -rm -f /tmp/luci-indexcache - -chmod +x /etc/init.d/AdGuardHome /usr/share/AdGuardHome/* -exit 0 diff --git a/luci-app-adguardhome/root/usr/share/AdGuardHome/AdGuardHome_template.yaml b/luci-app-adguardhome/root/usr/share/AdGuardHome/AdGuardHome_template.yaml deleted file mode 100755 index 612a57706..000000000 --- a/luci-app-adguardhome/root/usr/share/AdGuardHome/AdGuardHome_template.yaml +++ /dev/null @@ -1,131 +0,0 @@ -bind_host: 0.0.0.0 -bind_port: 3000 -beta_bind_port: 0 -users: -- name: root - password: $2y$10$dwn0hTYoECQMZETBErGlzOId2VANOVsPHsuH13TM/8KnysM5Dh/ve -auth_attempts: 5 -block_auth_min: 15 -http_proxy: "" -language: zh-cn -debug_pprof: false -web_session_ttl: 720 -dns: - bind_hosts: - - 0.0.0.0 - port: 1745 - statistics_interval: 30 - querylog_enabled: true - querylog_file_enabled: true - querylog_interval: 6h - querylog_size_memory: 1000 - anonymize_client_ip: false - protection_enabled: true - blocking_mode: default - blocking_ipv4: "" - blocking_ipv6: "" - blocked_response_ttl: 60 - parental_block_host: family-block.dns.adguard.com - safebrowsing_block_host: standard-block.dns.adguard.com - ratelimit: 0 - ratelimit_whitelist: [] - refuse_any: false - upstream_dns: - - 223.5.5.5 - upstream_dns_file: "" - bootstrap_dns: - - 119.29.29.29 - - 223.5.5.5 - all_servers: false - fastest_addr: false - fastest_timeout: 1s - allowed_clients: [] - disallowed_clients: [] - blocked_hosts: - - version.bind - - id.server - - hostname.bind - trusted_proxies: - - 127.0.0.0/8 - - ::1/128 - cache_size: 4194304 - cache_ttl_min: 0 - cache_ttl_max: 0 - cache_optimistic: true - bogus_nxdomain: [] - aaaa_disabled: false - enable_dnssec: false - edns_client_subnet: false - max_goroutines: 300 - ipset: [] - filtering_enabled: true - filters_update_interval: 24 - parental_enabled: false - safesearch_enabled: false - safebrowsing_enabled: false - safebrowsing_cache_size: 1048576 - safesearch_cache_size: 1048576 - parental_cache_size: 1048576 - cache_time: 30 - rewrites: [] - blocked_services: [] - upstream_timeout: 10s - local_domain_name: lan - resolve_clients: true - use_private_ptr_resolvers: true - local_ptr_upstreams: [] -tls: - enabled: false - server_name: "" - force_https: false - port_https: 443 - port_dns_over_tls: 853 - port_dns_over_quic: 784 - port_dnscrypt: 0 - dnscrypt_config_file: "" - allow_unencrypted_doh: false - strict_sni_check: false - certificate_chain: "" - private_key: "" - certificate_path: "" - private_key_path: "" -filters: -- enabled: true - url: https://adguardteam.github.io/AdGuardSDNSFilter/Filters/filter.txt - name: AdGuard DNS filter - id: 1628750870 -- enabled: true - url: https://anti-ad.net/easylist.txt - name: 'CHN: anti-AD' - id: 1628750871 -whitelist_filters: [] -user_rules: [] -dhcp: - enabled: false - interface_name: "" - dhcpv4: - gateway_ip: "" - subnet_mask: "" - range_start: "" - range_end: "" - lease_duration: 86400 - icmp_timeout_msec: 1000 - options: [] - dhcpv6: - range_start: "" - lease_duration: 86400 - ra_slaac_only: false - ra_allow_slaac: false -clients: [] -log_compress: false -log_localtime: false -log_max_backups: 0 -log_max_size: 100 -log_max_age: 3 -log_file: "" -verbose: false -os: - group: "" - user: "" - rlimit_nofile: 0 -schema_version: 12 diff --git a/luci-app-adguardhome/root/usr/share/AdGuardHome/addhost.sh b/luci-app-adguardhome/root/usr/share/AdGuardHome/addhost.sh deleted file mode 100755 index 6c6b7b769..000000000 --- a/luci-app-adguardhome/root/usr/share/AdGuardHome/addhost.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/sh - -checkmd5(){ -local nowmd5=$(md5sum /etc/hosts) -nowmd5=${nowmd5%% *} -local lastmd5=$(uci get AdGuardHome.AdGuardHome.hostsmd5 2>/dev/null) -if [ "$nowmd5" != "$lastmd5" ]; then - uci set AdGuardHome.AdGuardHome.hostsmd5="$nowmd5" - uci commit AdGuardHome - [ "$1" == "noreload" ] || /etc/init.d/AdGuardHome reload -fi -} - -[ "$1" == "del" ] && sed -i '/programaddstart/,/programaddend/d' /etc/hosts && checkmd5 "$2" && exit 0 -/usr/bin/awk 'BEGIN{ -while ((getline < "/tmp/dhcp.leases") > 0) -{ - a[$2]=$4; -} -while (("ip -6 neighbor show | grep -v fe80" | getline) > 0) -{ - if (a[$5]) {print $1" "a[$5] >"/tmp/tmphost"; } -} -print "#programaddend" >"/tmp/tmphost"; -}' -grep programaddstart /etc/hosts >/dev/null 2>&1 -if [ "$?" == "0" ]; then - sed -i '/programaddstart/,/programaddend/c\#programaddstart' /etc/hosts - sed -i '/programaddstart/'r/tmp/tmphost /etc/hosts -else - echo "#programaddstart" >>/etc/hosts - cat /tmp/tmphost >> /etc/hosts -fi -rm /tmp/tmphost -checkmd5 "$2" diff --git a/luci-app-adguardhome/root/usr/share/AdGuardHome/firewall.start b/luci-app-adguardhome/root/usr/share/AdGuardHome/firewall.start deleted file mode 100755 index 562117e52..000000000 --- a/luci-app-adguardhome/root/usr/share/AdGuardHome/firewall.start +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -AdGuardHome_enable=$(uci get AdGuardHome.AdGuardHome.enabled) -redirect=$(uci get AdGuardHome.AdGuardHome.redirect) - -if [ $AdGuardHome_enable -eq 1 -a "$redirect" == "redirect" ]; then - /etc/init.d/AdGuardHome do_redirect 1 -fi diff --git a/luci-app-adguardhome/root/usr/share/AdGuardHome/getsyslog.sh b/luci-app-adguardhome/root/usr/share/AdGuardHome/getsyslog.sh deleted file mode 100755 index 908bdf631..000000000 --- a/luci-app-adguardhome/root/usr/share/AdGuardHome/getsyslog.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sh - -PATH="/usr/sbin:/usr/bin:/sbin:/bin" -logread -e AdGuardHome > /tmp/AdGuardHometmp.log -logread -e AdGuardHome -f >> /tmp/AdGuardHometmp.log & -pid=$! -echo "1">/var/run/AdGuardHomesyslog -while true -do - sleep 12 - watchdog=$(cat /var/run/AdGuardHomesyslog) - if [ "$watchdog"x == "0"x ]; then - kill $pid - rm /tmp/AdGuardHometmp.log - rm /var/run/AdGuardHomesyslog - exit 0 - else - echo "0">/var/run/AdGuardHomesyslog - fi -done diff --git a/luci-app-adguardhome/root/usr/share/AdGuardHome/gfw2adg.sh b/luci-app-adguardhome/root/usr/share/AdGuardHome/gfw2adg.sh deleted file mode 100755 index a3add84e8..000000000 --- a/luci-app-adguardhome/root/usr/share/AdGuardHome/gfw2adg.sh +++ /dev/null @@ -1,89 +0,0 @@ -#!/bin/sh - -PATH="/usr/sbin:/usr/bin:/sbin:/bin" - -checkmd5(){ -local nowmd5=$(md5sum /tmp/adguard.list 2>/dev/null) -nowmd5=${nowmd5%% *} -local lastmd5=$(uci get AdGuardHome.AdGuardHome.gfwlistmd5 2>/dev/null) -if [ "$nowmd5" != "$lastmd5" ]; then - uci set AdGuardHome.AdGuardHome.gfwlistmd5="$nowmd5" - uci commit AdGuardHome - [ "$1" == "noreload" ] || /etc/init.d/AdGuardHome reload -fi -} - -configpath=$(uci get AdGuardHome.AdGuardHome.configpath 2>/dev/null) -[ "$1" == "del" ] && sed -i '/programaddstart/,/programaddend/d' $configpath && checkmd5 "$2" && exit 0 -gfwupstream=$(uci get AdGuardHome.AdGuardHome.gfwupstream 2>/dev/null) -if [ -z $gfwupstream ]; then -gfwupstream="tcp://208.67.220.220:5353" -fi -if [ ! -f "$configpath" ]; then - echo "please make a config first" - exit 1 -fi -wget-ssl --no-check-certificate https://cdn.jsdelivr.net/gh/gfwlist/gfwlist/gfwlist.txt -O- | base64 -d > /tmp/gfwlist.txt -cat /tmp/gfwlist.txt | awk -v upst="$gfwupstream" 'BEGIN{getline;}{ -s1=substr($0,1,1); -if (s1=="!") -{next;} -if (s1=="@"){ - $0=substr($0,3); - s1=substr($0,1,1); - white=1;} -else{ - white=0; -} - -if (s1=="|") - {s2=substr($0,2,1); - if (s2=="|") - { - $0=substr($0,3); - split($0,d,"/"); - $0=d[1]; - }else{ - split($0,d,"/"); - $0=d[3]; - }} -else{ - split($0,d,"/"); - $0=d[1]; -} -star=index($0,"*"); -if (star!=0) -{ - $0=substr($0,star+1); - dot=index($0,"."); - if (dot!=0) - $0=substr($0,dot+1); - else - next; - s1=substr($0,1,1); -} -if (s1==".") -{fin=substr($0,2);} -else{fin=$0;} -if (index(fin,".")==0) next; -if (index(fin,"%")!=0) next; -if (index(fin,":")!=0) next; -match(fin,"^[0-9\.]+") -if (RSTART==1 && RLENGTH==length(fin)) {print "ipset add gfwlist "fin>"/tmp/doipset.sh";next;} -if (fin=="" || finl==fin) next; -finl=fin; -if (white==0) - {print(" - '\''[/"fin"/]"upst"'\''");} -else{ - print(" - '\''[/"fin"/]#'\''");} -}END{print(" - '\''[/programaddend/]#'\''")}' > /tmp/adguard.list -grep programaddstart $configpath -if [ "$?" == "0" ]; then - sed -i '/programaddstart/,/programaddend/c\ - '\''\[\/programaddstart\/\]#'\''' $configpath - sed -i '/programaddstart/'r/tmp/adguard.list $configpath -else - sed -i '1i\ - '\''[/programaddstart/]#'\''' /tmp/adguard.list - sed -i '/upstream_dns:/'r/tmp/adguard.list $configpath -fi -checkmd5 "$2" -rm -f /tmp/gfwlist.txt /tmp/adguard.list diff --git a/luci-app-adguardhome/root/usr/share/AdGuardHome/links.txt b/luci-app-adguardhome/root/usr/share/AdGuardHome/links.txt deleted file mode 100755 index e4f1c8fa7..000000000 --- a/luci-app-adguardhome/root/usr/share/AdGuardHome/links.txt +++ /dev/null @@ -1,3 +0,0 @@ -https://static.adguard.com/adguardhome/beta/AdGuardHome_linux_${Arch}.tar.gz -https://github.com/AdguardTeam/AdGuardHome/releases/download/${latest_ver}/AdGuardHome_linux_${Arch}.tar.gz -https://static.adguard.com/adguardhome/release/AdGuardHome_linux_${Arch}.tar.gz diff --git a/luci-app-adguardhome/root/usr/share/AdGuardHome/tailto.sh b/luci-app-adguardhome/root/usr/share/AdGuardHome/tailto.sh deleted file mode 100755 index 9ccc21903..000000000 --- a/luci-app-adguardhome/root/usr/share/AdGuardHome/tailto.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh - -tail -n $1 "$2" > /var/run/tailtmp -cat /var/run/tailtmp > "$2" -rm /var/run/tailtmp diff --git a/luci-app-adguardhome/root/usr/share/AdGuardHome/update_core.sh b/luci-app-adguardhome/root/usr/share/AdGuardHome/update_core.sh deleted file mode 100755 index 74ba7268d..000000000 --- a/luci-app-adguardhome/root/usr/share/AdGuardHome/update_core.sh +++ /dev/null @@ -1,236 +0,0 @@ -#!/bin/bash - -PATH="/usr/sbin:/usr/bin:/sbin:/bin" -binpath=$(uci get AdGuardHome.AdGuardHome.binpath) -if [ -z "$binpath" ]; then -uci set AdGuardHome.AdGuardHome.binpath="/tmp/AdGuardHome/AdGuardHome" -binpath="/tmp/AdGuardHome/AdGuardHome" -fi -mkdir -p ${binpath%/*} -upxflag=$(uci get AdGuardHome.AdGuardHome.upxflag 2>/dev/null) - -check_if_already_running(){ - running_tasks="$(ps |grep "AdGuardHome" |grep "update_core" |grep -v "grep" |awk '{print $1}' |wc -l)" - [ "${running_tasks}" -gt "2" ] && echo -e "\nA task is already running." && EXIT 2 -} - -check_wgetcurl(){ - which curl && downloader="curl -L -k --retry 2 --connect-timeout 20 -o" && return - which wget-ssl && downloader="wget-ssl --no-check-certificate -t 2 -T 20 -O" && return - [ -z "$1" ] && opkg update || (echo error opkg && EXIT 1) - [ -z "$1" ] && (opkg remove wget wget-nossl --force-depends ; opkg install wget ; check_wgetcurl 1 ;return) - [ "$1" == "1" ] && (opkg install curl ; check_wgetcurl 2 ; return) - echo error curl and wget && EXIT 1 -} - -check_latest_version(){ - check_wgetcurl - latest_ver="$($downloader - https://api.github.com/repos/AdguardTeam/AdGuardHome/releases/latest 2>/dev/null|grep -E 'tag_name' |grep -E 'v[0-9.]+' -o 2>/dev/null)" - if [ -z "${latest_ver}" ]; then - echo -e "\nFailed to check latest version, please try again later." && EXIT 1 - fi - now_ver="$($binpath -c /dev/null --check-config 2>&1| grep -m 1 -E 'v[0-9.]+' -o)" - if [ "${latest_ver}"x != "${now_ver}"x ] || [ "$1" == "force" ]; then - echo -e "Local version: ${now_ver}., cloud version: ${latest_ver}." - doupdate_core - else - echo -e "\nLocal version: ${now_ver}, cloud version: ${latest_ver}." - echo -e "You're already using the latest version." - if [ ! -z "$upxflag" ]; then - filesize=$(ls -l $binpath | awk '{ print $5 }') - if [ $filesize -gt 8000000 ]; then - echo -e "start upx may take a long time" - doupx - mkdir -p "/tmp/AdGuardHomeupdate/AdGuardHome" >/dev/null 2>&1 - rm -fr /tmp/AdGuardHomeupdate/AdGuardHome/${binpath##*/} - /tmp/upx-${upx_latest_ver}-${Arch}_linux/upx $upxflag $binpath -o /tmp/AdGuardHomeupdate/AdGuardHome/${binpath##*/} - rm -rf /tmp/upx-${upx_latest_ver}-${Arch}_linux - /etc/init.d/AdGuardHome stop nobackup - rm $binpath - mv -f /tmp/AdGuardHomeupdate/AdGuardHome/${binpath##*/} $binpath - /etc/init.d/AdGuardHome start - echo -e "finished" - fi - fi - EXIT 0 - fi -} - -doupx(){ - Archt="$(opkg info kernel | grep Architecture | awk -F "[ _]" '{print($2)}')" - case $Archt in - "i386") - Arch="i386" - ;; - "i686") - Arch="i386" - echo -e "i686 use $Arch may have bug" - ;; - "x86") - Arch="amd64" - ;; - "mipsel") - Arch="mipsel" - ;; - "mips64el") - Arch="mips64el" - Arch="mipsel" - echo -e "mips64el use $Arch may have bug" - ;; - "mips") - Arch="mips" - ;; - "mips64") - Arch="mips64" - Arch="mips" - echo -e "mips64 use $Arch may have bug" - ;; - "arm") - Arch="arm" - ;; - "armeb") - Arch="armeb" - ;; - "aarch64") - Arch="arm64" - ;; - "powerpc") - Arch="powerpc" - ;; - "powerpc64") - Arch="powerpc64" - ;; - *) - echo -e "error not support $Archt if you can use offical release please issue a bug" - EXIT 1 - ;; - esac - upx_latest_ver="$($downloader - https://api.github.com/repos/upx/upx/releases/latest 2>/dev/null|grep -E 'tag_name' |grep -E '[0-9.]+' -o 2>/dev/null)" - $downloader /tmp/upx-${upx_latest_ver}-${Arch}_linux.tar.xz "https://github.com/upx/upx/releases/download/v${upx_latest_ver}/upx-${upx_latest_ver}-${Arch}_linux.tar.xz" 2>&1 - #tar xvJf - which xz || (opkg list | grep ^xz || opkg update && opkg install xz) || (echo "xz download fail" && EXIT 1) - mkdir -p /tmp/upx-${upx_latest_ver}-${Arch}_linux - xz -d -c /tmp/upx-${upx_latest_ver}-${Arch}_linux.tar.xz| tar -x -C "/tmp" >/dev/null 2>&1 - if [ ! -e "/tmp/upx-${upx_latest_ver}-${Arch}_linux/upx" ]; then - echo -e "Failed to download upx." - EXIT 1 - fi - rm /tmp/upx-${upx_latest_ver}-${Arch}_linux.tar.xz -} - -doupdate_core(){ - echo -e "Updating core..." - mkdir -p "/tmp/AdGuardHomeupdate" - rm -rf /tmp/AdGuardHomeupdate/* >/dev/null 2>&1 - Archt="$(opkg info kernel | grep Architecture | awk -F "[ _]" '{print($2)}')" - case $Archt in - "i386") - Arch="386" - ;; - "i686") - Arch="386" - ;; - "x86") - Arch="amd64" - ;; - "mipsel") - Arch="mipsle" - ;; - "mips64el") - Arch="mips64le" - Arch="mipsle" - echo -e "mips64el use $Arch may have bug" - ;; - "mips") - Arch="mips" - ;; - "mips64") - Arch="mips64" - Arch="mips" - echo -e "mips64 use $Arch may have bug" - ;; - "arm") - Arch="arm" - ;; - "aarch64") - Arch="arm64" - ;; - "powerpc") - Arch="ppc" - echo -e "error not support $Archt" - EXIT 1 - ;; - "powerpc64") - Arch="ppc64" - echo -e "error not support $Archt" - EXIT 1 - ;; - *) - echo -e "error not support $Archt if you can use offical release please issue a bug" - EXIT 1 - ;; - esac - echo -e "start download" - grep -v "^#" /usr/share/AdGuardHome/links.txt >/tmp/run/AdHlinks.txt - while read link - do - eval link="$link" - $downloader /tmp/AdGuardHomeupdate/${link##*/} "$link" 2>&1 - if [ "$?" != "0" ]; then - echo "download failed try another download" - rm -f /tmp/AdGuardHomeupdate/${link##*/} - else - local success="1" - break - fi - done < "/tmp/run/AdHlinks.txt" - rm /tmp/run/AdHlinks.txt - [ -z "$success" ] && echo "no download success" && EXIT 1 - if [ "${link##*.}" == "gz" ]; then - tar -zxf "/tmp/AdGuardHomeupdate/${link##*/}" -C "/tmp/AdGuardHomeupdate/" - if [ ! -e "/tmp/AdGuardHomeupdate/AdGuardHome" ]; then - echo -e "Failed to download core." - rm -rf "/tmp/AdGuardHomeupdate" >/dev/null 2>&1 - EXIT 1 - fi - downloadbin="/tmp/AdGuardHomeupdate/AdGuardHome/AdGuardHome" - else - downloadbin="/tmp/AdGuardHomeupdate/${link##*/}" - fi - chmod 755 $downloadbin - echo -e "download success start copy" - if [ -n "$upxflag" ]; then - echo -e "start upx may take a long time" - doupx - /tmp/upx-${upx_latest_ver}-${Arch}_linux/upx $upxflag $downloadbin - rm -rf /tmp/upx-${upx_latest_ver}-${Arch}_linux - fi - echo -e "start copy" - /etc/init.d/AdGuardHome stop nobackup - rm "$binpath" - mv -f "$downloadbin" "$binpath" - if [ "$?" == "1" ]; then - echo "mv failed maybe not enough space please use upx or change bin to /tmp/AdGuardHome" - EXIT 1 - fi - /etc/init.d/AdGuardHome start - rm -rf "/tmp/AdGuardHomeupdate" >/dev/null 2>&1 - echo -e "Succeeded in updating core." - echo -e "Local version: ${latest_ver}, cloud version: ${latest_ver}.\n" - EXIT 0 -} - -EXIT(){ - rm /var/run/update_core 2>/dev/null - [ "$1" != "0" ] && touch /var/run/update_core_error - exit $1 -} - -main(){ - check_if_already_running - check_latest_version $1 -} - trap "EXIT 1" SIGTERM SIGINT - touch /var/run/update_core - rm /var/run/update_core_error 2>/dev/null - main $1 diff --git a/luci-app-adguardhome/root/usr/share/AdGuardHome/waitnet.sh b/luci-app-adguardhome/root/usr/share/AdGuardHome/waitnet.sh deleted file mode 100755 index c7745e101..000000000 --- a/luci-app-adguardhome/root/usr/share/AdGuardHome/waitnet.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/sh - -PATH="/usr/sbin:/usr/bin:/sbin:/bin" -count=0 -while : -do - ping -c 1 -W 1 -q www.baidu.com 1>/dev/null 2>&1 - if [ "$?" == "0" ]; then - /etc/init.d/AdGuardHome force_reload - break - fi - ping -c 1 -W 1 -q 202.108.22.5 1>/dev/null 2>&1 - if [ "$?" == "0" ]; then - /etc/init.d/AdGuardHome force_reload - break - fi - sleep 5 - ping -c 1 -W 1 -q www.google.com 1>/dev/null 2>&1 - if [ "$?" == "0" ]; then - /etc/init.d/AdGuardHome force_reload - break - fi - ping -c 1 -W 1 -q 8.8.8.8 1>/dev/null 2>&1 - if [ "$?" == "0" ]; then - /etc/init.d/AdGuardHome force_reload - break - fi - sleep 5 - count=$((count+1)) - if [ $count -gt 18 ]; then - /etc/init.d/AdGuardHome force_reload - break - fi -done -return 0 diff --git a/luci-app-adguardhome/root/usr/share/AdGuardHome/watchconfig.sh b/luci-app-adguardhome/root/usr/share/AdGuardHome/watchconfig.sh deleted file mode 100755 index 61ba09de7..000000000 --- a/luci-app-adguardhome/root/usr/share/AdGuardHome/watchconfig.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh - -PATH="/usr/sbin:/usr/bin:/sbin:/bin" -configpath=$(uci get AdGuardHome.AdGuardHome.configpath) -while : -do - sleep 10 - if [ -f "$configpath" ]; then - /etc/init.d/AdGuardHome do_redirect 1 - break - fi -done -return 0 diff --git a/luci-app-adguardhome/root/usr/share/rpcd/acl.d/luci-app-adguardhome.json b/luci-app-adguardhome/root/usr/share/rpcd/acl.d/luci-app-adguardhome.json deleted file mode 100755 index 485aa6205..000000000 --- a/luci-app-adguardhome/root/usr/share/rpcd/acl.d/luci-app-adguardhome.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "luci-app-adguardhome": { - "description": "Grant UCI access for luci-app-adguardhome", - "read": { - "uci": [ "AdGuardHome" ] - }, - "write": { - "uci": [ "AdGuardHome" ] - } - } -} diff --git a/luci-app-adguardhome/root/www/luci-static/resources/codemirror/addon/fold/foldcode.js b/luci-app-adguardhome/root/www/luci-static/resources/codemirror/addon/fold/foldcode.js deleted file mode 100755 index f93d42b7f..000000000 --- a/luci-app-adguardhome/root/www/luci-static/resources/codemirror/addon/fold/foldcode.js +++ /dev/null @@ -1 +0,0 @@ -!function(n){"object"==typeof exports&&"object"==typeof module?n(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],n):n(CodeMirror)}(function(n){"use strict";function e(e,o,i,t){if(i&&i.call){var l=i;i=null}else l=r(e,i,"rangeFinder");"number"==typeof o&&(o=n.Pos(o,0));var f=r(e,i,"minFoldSize");function d(n){var r=l(e,o);if(!r||r.to.line-r.from.linee.firstLine();)o=n.Pos(o.line-1,0),u=d(!1);if(u&&!u.cleared&&"unfold"!==t){var a=function(n,e){var o=r(n,e,"widget");if("string"==typeof o){var i=document.createTextNode(o);(o=document.createElement("span")).appendChild(i),o.className="CodeMirror-foldmarker"}else o&&(o=o.cloneNode(!0));return o}(e,i);n.on(a,"mousedown",function(e){c.clear(),n.e_preventDefault(e)});var c=e.markText(u.from,u.to,{replacedWith:a,clearOnEnter:r(e,i,"clearOnEnter"),__isFold:!0});c.on("clear",function(o,r){n.signal(e,"unfold",e,o,r)}),n.signal(e,"fold",e,u.from,u.to)}}n.newFoldFunction=function(n,o){return function(r,i){e(r,i,{rangeFinder:n,widget:o})}},n.defineExtension("foldCode",function(n,o,r){e(this,n,o,r)}),n.defineExtension("isFolded",function(n){for(var e=this.findMarksAt(n),o=0;o=u){if(s&&f&&s.test(f.className))return;i=r(a.indicatorOpen)}}(i||f)&&t.setGutterMarker(n,a.gutter,i)})}function i(t){return new RegExp("(^|\\s)"+t+"(?:$|\\s)\\s*")}function f(t){var o=t.getViewport(),e=t.state.foldGutter;e&&(t.operation(function(){n(t,o.from,o.to)}),e.from=o.from,e.to=o.to)}function a(t,r,n){var i=t.state.foldGutter;if(i){var f=i.options;if(n==f.gutter){var a=e(t,r);a?a.clear():t.foldCode(o(r,0),f)}}}function d(t){var o=t.state.foldGutter;if(o){var e=o.options;o.from=o.to=0,clearTimeout(o.changeUpdate),o.changeUpdate=setTimeout(function(){f(t)},e.foldOnChangeTimeSpan||600)}}function u(t){var o=t.state.foldGutter;if(o){var e=o.options;clearTimeout(o.changeUpdate),o.changeUpdate=setTimeout(function(){var e=t.getViewport();o.from==o.to||e.from-o.to>20||o.from-e.to>20?f(t):t.operation(function(){e.fromo.to&&(n(t,o.to,e.to),o.to=e.to)})},e.updateViewportTimeSpan||400)}}function l(t,o){var e=t.state.foldGutter;if(e){var r=o.line;r>=e.from&&ro))break;r=l}}return r?{from:e.Pos(i.line,t.getLine(i.line).length),to:e.Pos(r,t.getLine(r).length)}:void 0}})}); \ No newline at end of file diff --git a/luci-app-adguardhome/root/www/luci-static/resources/codemirror/lib/codemirror.css b/luci-app-adguardhome/root/www/luci-static/resources/codemirror/lib/codemirror.css deleted file mode 100755 index 43ac1a9fa..000000000 --- a/luci-app-adguardhome/root/www/luci-static/resources/codemirror/lib/codemirror.css +++ /dev/null @@ -1 +0,0 @@ -.CodeMirror{font-family:monospace;height:500px;color:black;direction:ltr}.CodeMirror-lines{padding:4px 0}.CodeMirror pre.CodeMirror-line,.CodeMirror pre.CodeMirror-line-like{padding:0 4px}.CodeMirror-scrollbar-filler,.CodeMirror-gutter-filler{background-color:white}.CodeMirror-gutters{border-right:1px solid #ddd;background-color:#f7f7f7;white-space:nowrap}.CodeMirror-linenumber{padding:0 3px 0 5px;min-width:20px;text-align:right;color:#999;white-space:nowrap}.CodeMirror-guttermarker{color:black}.CodeMirror-guttermarker-subtle{color:#999}.CodeMirror-cursor{border-left:1px solid black;border-right:0;width:0}.CodeMirror div.CodeMirror-secondarycursor{border-left:1px solid silver}.cm-fat-cursor .CodeMirror-cursor{width:auto;border:0 !important;background:#7e7}.cm-fat-cursor div.CodeMirror-cursors{z-index:1}.cm-fat-cursor-mark{background-color:rgba(20,255,20,0.5);-webkit-animation:blink 1.06s steps(1) infinite;-moz-animation:blink 1.06s steps(1) infinite;animation:blink 1.06s steps(1) infinite}.cm-animate-fat-cursor{width:auto;border:0;-webkit-animation:blink 1.06s steps(1) infinite;-moz-animation:blink 1.06s steps(1) infinite;animation:blink 1.06s steps(1) infinite;background-color:#7e7}@-moz-keyframes blink{50%{background-color:transparent}}@-webkit-keyframes blink{50%{background-color:transparent}}@keyframes blink{50%{background-color:transparent}}.cm-tab{display:inline-block;text-decoration:inherit}.CodeMirror-rulers{position:absolute;left:0;right:0;top:-50px;bottom:0;overflow:hidden}.CodeMirror-ruler{border-left:1px solid #ccc;top:0;bottom:0;position:absolute}.cm-s-default .cm-header{color:blue}.cm-s-default .cm-quote{color:#090}.cm-negative{color:#d44}.cm-positive{color:#292}.cm-header,.cm-strong{font-weight:bold}.cm-em{font-style:italic}.cm-link{text-decoration:underline}.cm-strikethrough{text-decoration:line-through}.cm-s-default .cm-keyword{color:#708}.cm-s-default .cm-atom{color:#219}.cm-s-default .cm-number{color:#164}.cm-s-default .cm-def{color:#00f}.cm-s-default .cm-variable-2{color:#05a}.cm-s-default .cm-variable-3,.cm-s-default .cm-type{color:#085}.cm-s-default .cm-comment{color:#a50}.cm-s-default .cm-string{color:#a11}.cm-s-default .cm-string-2{color:#f50}.cm-s-default .cm-meta{color:#555}.cm-s-default .cm-qualifier{color:#555}.cm-s-default .cm-builtin{color:#30a}.cm-s-default .cm-bracket{color:#997}.cm-s-default .cm-tag{color:#170}.cm-s-default .cm-attribute{color:#00c}.cm-s-default .cm-hr{color:#999}.cm-s-default .cm-link{color:#00c}.cm-s-default .cm-error{color:red}.cm-invalidchar{color:red}.CodeMirror-composing{border-bottom:2px solid}div.CodeMirror span.CodeMirror-matchingbracket{color:#0b0}div.CodeMirror span.CodeMirror-nonmatchingbracket{color:#a22}.CodeMirror-matchingtag{background:rgba(255,150,0,.3)}.CodeMirror-activeline-background{background:#e8f2ff}.CodeMirror{position:relative;overflow:hidden;background:white}.CodeMirror-scroll{overflow:scroll !important;margin-bottom:-30px;margin-right:-30px;padding-bottom:30px;height:100%;outline:0;position:relative}.CodeMirror-sizer{position:relative;border-right:30px solid transparent}.CodeMirror-vscrollbar,.CodeMirror-hscrollbar,.CodeMirror-scrollbar-filler,.CodeMirror-gutter-filler{position:absolute;z-index:6;display:none}.CodeMirror-vscrollbar{right:0;top:0;overflow-x:hidden;overflow-y:scroll}.CodeMirror-hscrollbar{bottom:0;left:0;overflow-y:hidden;overflow-x:scroll}.CodeMirror-scrollbar-filler{right:0;bottom:0}.CodeMirror-gutter-filler{left:0;bottom:0}.CodeMirror-gutters{position:absolute;left:0;top:0;min-height:100%;z-index:3}.CodeMirror-gutter{white-space:normal;height:100%;display:inline-block;vertical-align:top;margin-bottom:-30px}.CodeMirror-gutter-wrapper{position:absolute;z-index:4;background:none !important;border:none !important}.CodeMirror-gutter-background{position:absolute;top:0;bottom:0;z-index:4}.CodeMirror-gutter-elt{position:absolute;cursor:default;z-index:4}.CodeMirror-gutter-wrapper ::selection{background-color:transparent}.CodeMirror-gutter-wrapper ::-moz-selection{background-color:transparent}.CodeMirror-lines{cursor:text;min-height:1px}.CodeMirror pre.CodeMirror-line,.CodeMirror pre.CodeMirror-line-like{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0;border-width:0;background:transparent;font-family:inherit;font-size:inherit;margin:0;white-space:pre;word-wrap:normal;line-height:inherit;color:inherit;z-index:2;position:relative;overflow:visible;-webkit-tap-highlight-color:transparent;-webkit-font-variant-ligatures:contextual;font-variant-ligatures:contextual}.CodeMirror-wrap pre.CodeMirror-line,.CodeMirror-wrap pre.CodeMirror-line-like{word-wrap:break-word;white-space:pre-wrap;word-break:normal}.CodeMirror-linebackground{position:absolute;left:0;right:0;top:0;bottom:0;z-index:0}.CodeMirror-linewidget{position:relative;z-index:2;padding:.1px}.CodeMirror-rtl pre{direction:rtl}.CodeMirror-code{outline:0}.CodeMirror-scroll,.CodeMirror-sizer,.CodeMirror-gutter,.CodeMirror-gutters,.CodeMirror-linenumber{-moz-box-sizing:content-box;box-sizing:content-box}.CodeMirror-measure{position:absolute;width:100%;height:0;overflow:hidden;visibility:hidden}.CodeMirror-cursor{position:absolute;pointer-events:none}.CodeMirror-measure pre{position:static}div.CodeMirror-cursors{visibility:hidden;position:relative;z-index:3}div.CodeMirror-dragcursors{visibility:visible}.CodeMirror-focused div.CodeMirror-cursors{visibility:visible}.CodeMirror-selected{background:#d9d9d9}.CodeMirror-focused .CodeMirror-selected{background:#d7d4f0}.CodeMirror-crosshair{cursor:crosshair}.CodeMirror-line::selection,.CodeMirror-line>span::selection,.CodeMirror-line>span>span::selection{background:#d7d4f0}.CodeMirror-line::-moz-selection,.CodeMirror-line>span::-moz-selection,.CodeMirror-line>span>span::-moz-selection{background:#d7d4f0}.cm-searching{background-color:#ffa;background-color:rgba(255,255,0,.4)}.cm-force-border{padding-right:.1px}@media print{.CodeMirror div.CodeMirror-cursors{visibility:hidden}}.cm-tab-wrap-hack:after{content:''}span.CodeMirror-selectedtext{background:0} diff --git a/luci-app-adguardhome/root/www/luci-static/resources/codemirror/lib/codemirror.js b/luci-app-adguardhome/root/www/luci-static/resources/codemirror/lib/codemirror.js deleted file mode 100755 index d01f072ee..000000000 --- a/luci-app-adguardhome/root/www/luci-static/resources/codemirror/lib/codemirror.js +++ /dev/null @@ -1 +0,0 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.CodeMirror=t()}(this,function(){"use strict";var e=navigator.userAgent,t=navigator.platform,r=/gecko\/\d/i.test(e),n=/MSIE \d/.test(e),i=/Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(e),o=/Edge\/(\d+)/.exec(e),l=n||i||o,s=l&&(n?document.documentMode||6:+(o||i)[1]),a=!o&&/WebKit\//.test(e),u=a&&/Qt\/\d+\.\d+/.test(e),c=!o&&/Chrome\//.test(e),h=/Opera\//.test(e),f=/Apple Computer/.test(navigator.vendor),d=/Mac OS X 1\d\D([8-9]|\d\d)\D/.test(e),p=/PhantomJS/.test(e),g=!o&&/AppleWebKit/.test(e)&&/Mobile\/\w+/.test(e),v=/Android/.test(e),m=g||v||/webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(e),y=g||/Mac/.test(t),b=/\bCrOS\b/.test(e),w=/win/i.test(t),x=h&&e.match(/Version\/(\d*\.\d*)/);x&&(x=Number(x[1])),x&&x>=15&&(h=!1,a=!0);var C=y&&(u||h&&(null==x||x<12.11)),S=r||l&&s>=9;function L(e){return new RegExp("(^|\\s)"+e+"(?:$|\\s)\\s*")}var k,T=function(e,t){var r=e.className,n=L(t).exec(r);if(n){var i=r.slice(n.index+n[0].length);e.className=r.slice(0,n.index)+(i?n[1]+i:"")}};function M(e){for(var t=e.childNodes.length;t>0;--t)e.removeChild(e.firstChild);return e}function N(e,t){return M(e).appendChild(t)}function O(e,t,r,n){var i=document.createElement(e);if(r&&(i.className=r),n&&(i.style.cssText=n),"string"==typeof t)i.appendChild(document.createTextNode(t));else if(t)for(var o=0;o=t)return l+(t-o);l+=s-o,l+=r-l%r,o=s+1}}g?P=function(e){e.selectionStart=0,e.selectionEnd=e.value.length}:l&&(P=function(e){try{e.select()}catch(e){}});var R=function(){this.id=null,this.f=null,this.time=0,this.handler=E(this.onTimeout,this)};function B(e,t){for(var r=0;r=t)return n+Math.min(l,t-i);if(i+=o-n,n=o+1,(i+=r-i%r)>=t)return n}}var Y=[""];function _(e){for(;Y.length<=e;)Y.push($(Y)+" ");return Y[e]}function $(e){return e[e.length-1]}function q(e,t){for(var r=[],n=0;n"€"&&(e.toUpperCase()!=e.toLowerCase()||J.test(e))}function te(e,t){return t?!!(t.source.indexOf("\\w")>-1&&ee(e))||t.test(e):ee(e)}function re(e){for(var t in e)if(e.hasOwnProperty(t)&&e[t])return!1;return!0}var ne=/[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065e\u0670\u06d6-\u06dc\u06de-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0900-\u0902\u093c\u0941-\u0948\u094d\u0951-\u0955\u0962\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81\u0a82\u0abc\u0ac1-\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d3e\u0d41-\u0d44\u0d4d\u0d57\u0d62\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039\u103a\u103d\u103e\u1058\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085\u1086\u108d\u109d\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193b\u1a17\u1a18\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80\u1b81\u1ba2-\u1ba5\u1ba8\u1ba9\u1c2c-\u1c33\u1c36\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1dc0-\u1de6\u1dfd-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\ua672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua825\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\uaa29-\uaa2e\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe5\uabe8\uabed\udc00-\udfff\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]/;function ie(e){return e.charCodeAt(0)>=768&&ne.test(e)}function oe(e,t,r){for(;(r<0?t>0:tr?-1:1;;){if(t==r)return t;var i=(t+r)/2,o=n<0?Math.ceil(i):Math.floor(i);if(o==t)return e(o)?t:r;e(o)?r=o:t=o+n}}var se=null;function ae(e,t,r){var n;se=null;for(var i=0;it)return i;o.to==t&&(o.from!=o.to&&"before"==r?n=i:se=i),o.from==t&&(o.from!=o.to&&"before"!=r?n=i:se=i)}return null!=n?n:se}var ue=function(){var e="bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN",t="nnnnnnNNr%%r,rNNmmmmmmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmmmnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmnNmmmmmmrrmmNmmmmrr1111111111";var r=/[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/,n=/[stwN]/,i=/[LRr]/,o=/[Lb1n]/,l=/[1n]/;function s(e,t,r){this.level=e,this.from=t,this.to=r}return function(a,u){var c="ltr"==u?"L":"R";if(0==a.length||"ltr"==u&&!r.test(a))return!1;for(var h,f=a.length,d=[],p=0;p-1&&(n[t]=i.slice(0,o).concat(i.slice(o+1)))}}}function ge(e,t){var r=de(e,t);if(r.length)for(var n=Array.prototype.slice.call(arguments,2),i=0;i0}function be(e){e.prototype.on=function(e,t){fe(this,e,t)},e.prototype.off=function(e,t){pe(this,e,t)}}function we(e){e.preventDefault?e.preventDefault():e.returnValue=!1}function xe(e){e.stopPropagation?e.stopPropagation():e.cancelBubble=!0}function Ce(e){return null!=e.defaultPrevented?e.defaultPrevented:0==e.returnValue}function Se(e){we(e),xe(e)}function Le(e){return e.target||e.srcElement}function ke(e){var t=e.which;return null==t&&(1&e.button?t=1:2&e.button?t=3:4&e.button&&(t=2)),y&&e.ctrlKey&&1==t&&(t=3),t}var Te,Me,Ne=function(){if(l&&s<9)return!1;var e=O("div");return"draggable"in e||"dragDrop"in e}();function Oe(e){if(null==Te){var t=O("span","​");N(e,O("span",[t,document.createTextNode("x")])),0!=e.firstChild.offsetHeight&&(Te=t.offsetWidth<=1&&t.offsetHeight>2&&!(l&&s<8))}var r=Te?O("span","​"):O("span"," ",null,"display: inline-block; width: 1px; margin-right: -1px");return r.setAttribute("cm-text",""),r}function Ae(e){if(null!=Me)return Me;var t=N(e,document.createTextNode("AخA")),r=k(t,0,1).getBoundingClientRect(),n=k(t,1,2).getBoundingClientRect();return M(e),!(!r||r.left==r.right)&&(Me=n.right-r.right<3)}var De,We=3!="\n\nb".split(/\n/).length?function(e){for(var t=0,r=[],n=e.length;t<=n;){var i=e.indexOf("\n",t);-1==i&&(i=e.length);var o=e.slice(t,"\r"==e.charAt(i-1)?i-1:i),l=o.indexOf("\r");-1!=l?(r.push(o.slice(0,l)),t+=l+1):(r.push(o),t=i+1)}return r}:function(e){return e.split(/\r\n?|\n/)},He=window.getSelection?function(e){try{return e.selectionStart!=e.selectionEnd}catch(e){return!1}}:function(e){var t;try{t=e.ownerDocument.selection.createRange()}catch(e){}return!(!t||t.parentElement()!=e)&&0!=t.compareEndPoints("StartToEnd",t)},Fe="oncopy"in(De=O("div"))||(De.setAttribute("oncopy","return;"),"function"==typeof De.oncopy),Pe=null;var Ee={},Ie={};function ze(e){if("string"==typeof e&&Ie.hasOwnProperty(e))e=Ie[e];else if(e&&"string"==typeof e.name&&Ie.hasOwnProperty(e.name)){var t=Ie[e.name];"string"==typeof t&&(t={name:t}),(e=Q(t,e)).name=t.name}else{if("string"==typeof e&&/^[\w\-]+\/[\w\-]+\+xml$/.test(e))return ze("application/xml");if("string"==typeof e&&/^[\w\-]+\/[\w\-]+\+json$/.test(e))return ze("application/json")}return"string"==typeof e?{name:e}:e||{name:"null"}}function Re(e,t){t=ze(t);var r=Ee[t.name];if(!r)return Re(e,"text/plain");var n=r(e,t);if(Be.hasOwnProperty(t.name)){var i=Be[t.name];for(var o in i)i.hasOwnProperty(o)&&(n.hasOwnProperty(o)&&(n["_"+o]=n[o]),n[o]=i[o])}if(n.name=t.name,t.helperType&&(n.helperType=t.helperType),t.modeProps)for(var l in t.modeProps)n[l]=t.modeProps[l];return n}var Be={};function Ge(e,t){I(t,Be.hasOwnProperty(e)?Be[e]:Be[e]={})}function Ue(e,t){if(!0===t)return t;if(e.copyState)return e.copyState(t);var r={};for(var n in t){var i=t[n];i instanceof Array&&(i=i.concat([])),r[n]=i}return r}function Ve(e,t){for(var r;e.innerMode&&(r=e.innerMode(t))&&r.mode!=e;)t=r.state,e=r.mode;return r||{mode:e,state:t}}function Ke(e,t,r){return!e.startState||e.startState(t,r)}var je=function(e,t,r){this.pos=this.start=0,this.string=e,this.tabSize=t||8,this.lastColumnPos=this.lastColumnValue=0,this.lineStart=0,this.lineOracle=r};function Xe(e,t){if((t-=e.first)<0||t>=e.size)throw new Error("There is no line "+(t+e.first)+" in the document.");for(var r=e;!r.lines;)for(var n=0;;++n){var i=r.children[n],o=i.chunkSize();if(t=e.first&&tr?et(r,Xe(e,r).text.length):function(e,t){var r=e.ch;return null==r||r>t?et(e.line,t):r<0?et(e.line,0):e}(t,Xe(e,t.line).text.length)}function at(e,t){for(var r=[],n=0;n=this.string.length},je.prototype.sol=function(){return this.pos==this.lineStart},je.prototype.peek=function(){return this.string.charAt(this.pos)||void 0},je.prototype.next=function(){if(this.post},je.prototype.eatSpace=function(){for(var e=this.pos;/[\s\u00a0]/.test(this.string.charAt(this.pos));)++this.pos;return this.pos>e},je.prototype.skipToEnd=function(){this.pos=this.string.length},je.prototype.skipTo=function(e){var t=this.string.indexOf(e,this.pos);if(t>-1)return this.pos=t,!0},je.prototype.backUp=function(e){this.pos-=e},je.prototype.column=function(){return this.lastColumnPos0?null:(n&&!1!==t&&(this.pos+=n[0].length),n)}var i=function(e){return r?e.toLowerCase():e};if(i(this.string.substr(this.pos,e.length))==i(e))return!1!==t&&(this.pos+=e.length),!0},je.prototype.current=function(){return this.string.slice(this.start,this.pos)},je.prototype.hideFirstChars=function(e,t){this.lineStart+=e;try{return t()}finally{this.lineStart-=e}},je.prototype.lookAhead=function(e){var t=this.lineOracle;return t&&t.lookAhead(e)},je.prototype.baseToken=function(){var e=this.lineOracle;return e&&e.baseToken(this.pos)};var ut=function(e,t){this.state=e,this.lookAhead=t},ct=function(e,t,r,n){this.state=t,this.doc=e,this.line=r,this.maxLookAhead=n||0,this.baseTokens=null,this.baseTokenPos=1};function ht(e,t,r,n){var i=[e.state.modeGen],o={};wt(e,t.text,e.doc.mode,r,function(e,t){return i.push(e,t)},o,n);for(var l=r.state,s=function(n){r.baseTokens=i;var s=e.state.overlays[n],a=1,u=0;r.state=!0,wt(e,t.text,s.mode,r,function(e,t){for(var r=a;ue&&i.splice(a,1,e,i[a+1],n),a+=2,u=Math.min(e,n)}if(t)if(s.opaque)i.splice(r,a-r,e,"overlay "+t),a=r+2;else for(;re.options.maxHighlightLength&&Ue(e.doc.mode,n.state),o=ht(e,t,n);i&&(n.state=i),t.stateAfter=n.save(!i),t.styles=o.styles,o.classes?t.styleClasses=o.classes:t.styleClasses&&(t.styleClasses=null),r===e.doc.highlightFrontier&&(e.doc.modeFrontier=Math.max(e.doc.modeFrontier,++e.doc.highlightFrontier))}return t.styles}function dt(e,t,r){var n=e.doc,i=e.display;if(!n.mode.startState)return new ct(n,!0,t);var o=function(e,t,r){for(var n,i,o=e.doc,l=r?-1:t-(e.doc.mode.innerMode?1e3:100),s=t;s>l;--s){if(s<=o.first)return o.first;var a=Xe(o,s-1),u=a.stateAfter;if(u&&(!r||s+(u instanceof ut?u.lookAhead:0)<=o.modeFrontier))return s;var c=z(a.text,null,e.options.tabSize);(null==i||n>c)&&(i=s-1,n=c)}return i}(e,t,r),l=o>n.first&&Xe(n,o-1).stateAfter,s=l?ct.fromSaved(n,l,o):new ct(n,Ke(n.mode),o);return n.iter(o,t,function(r){pt(e,r.text,s);var n=s.line;r.stateAfter=n==t-1||n%5==0||n>=i.viewFrom&&nt.start)return o}throw new Error("Mode "+e.name+" failed to advance stream.")}ct.prototype.lookAhead=function(e){var t=this.doc.getLine(this.line+e);return null!=t&&e>this.maxLookAhead&&(this.maxLookAhead=e),t},ct.prototype.baseToken=function(e){if(!this.baseTokens)return null;for(;this.baseTokens[this.baseTokenPos]<=e;)this.baseTokenPos+=2;var t=this.baseTokens[this.baseTokenPos+1];return{type:t&&t.replace(/( |^)overlay .*/,""),size:this.baseTokens[this.baseTokenPos]-e}},ct.prototype.nextLine=function(){this.line++,this.maxLookAhead>0&&this.maxLookAhead--},ct.fromSaved=function(e,t,r){return t instanceof ut?new ct(e,Ue(e.mode,t.state),r,t.lookAhead):new ct(e,Ue(e.mode,t),r)},ct.prototype.save=function(e){var t=!1!==e?Ue(this.doc.mode,this.state):this.state;return this.maxLookAhead>0?new ut(t,this.maxLookAhead):t};var mt=function(e,t,r){this.start=e.start,this.end=e.pos,this.string=e.current(),this.type=t||null,this.state=r};function yt(e,t,r,n){var i,o,l=e.doc,s=l.mode,a=Xe(l,(t=st(l,t)).line),u=dt(e,t.line,r),c=new je(a.text,e.options.tabSize,u);for(n&&(o=[]);(n||c.pose.options.maxHighlightLength?(s=!1,l&&pt(e,t,n,h.pos),h.pos=t.length,a=null):a=bt(vt(r,h,n.state,f),o),f){var d=f[0].name;d&&(a="m-"+(a?d+" "+a:d))}if(!s||c!=a){for(;u=t:o.to>t);(n||(n=[])).push(new St(l,o.from,s?null:o.to))}}return n}(r,i,l),a=function(e,t,r){var n;if(e)for(var i=0;i=t:o.to>t)||o.from==t&&"bookmark"==l.type&&(!r||o.marker.insertLeft)){var s=null==o.from||(l.inclusiveLeft?o.from<=t:o.from0&&s)for(var b=0;bt)&&(!r||Wt(r,o.marker)<0)&&(r=o.marker)}return r}function It(e,t,r,n,i){var o=Xe(e,t),l=Ct&&o.markedSpans;if(l)for(var s=0;s=0&&h<=0||c<=0&&h>=0)&&(c<=0&&(a.marker.inclusiveRight&&i.inclusiveLeft?tt(u.to,r)>=0:tt(u.to,r)>0)||c>=0&&(a.marker.inclusiveRight&&i.inclusiveLeft?tt(u.from,n)<=0:tt(u.from,n)<0)))return!0}}}function zt(e){for(var t;t=Ft(e);)e=t.find(-1,!0).line;return e}function Rt(e,t){var r=Xe(e,t),n=zt(r);return r==n?t:qe(n)}function Bt(e,t){if(t>e.lastLine())return t;var r,n=Xe(e,t);if(!Gt(e,n))return t;for(;r=Pt(n);)n=r.find(1,!0).line;return qe(n)+1}function Gt(e,t){var r=Ct&&t.markedSpans;if(r)for(var n=void 0,i=0;it.maxLineLength&&(t.maxLineLength=r,t.maxLine=e)})}var Xt=function(e,t,r){this.text=e,Ot(this,t),this.height=r?r(this):1};function Yt(e){e.parent=null,Nt(e)}Xt.prototype.lineNo=function(){return qe(this)},be(Xt);var _t={},$t={};function qt(e,t){if(!e||/^\s*$/.test(e))return null;var r=t.addModeClass?$t:_t;return r[e]||(r[e]=e.replace(/\S+/g,"cm-$&"))}function Zt(e,t){var r=A("span",null,null,a?"padding-right: .1px":null),n={pre:A("pre",[r],"CodeMirror-line"),content:r,col:0,pos:0,cm:e,trailingSpace:!1,splitSpaces:e.getOption("lineWrapping")};t.measure={};for(var i=0;i<=(t.rest?t.rest.length:0);i++){var o=i?t.rest[i-1]:t.line,l=void 0;n.pos=0,n.addToken=Jt,Ae(e.display.measure)&&(l=ce(o,e.doc.direction))&&(n.addToken=er(n.addToken,l)),n.map=[],rr(o,n,ft(e,o,t!=e.display.externalMeasured&&qe(o))),o.styleClasses&&(o.styleClasses.bgClass&&(n.bgClass=F(o.styleClasses.bgClass,n.bgClass||"")),o.styleClasses.textClass&&(n.textClass=F(o.styleClasses.textClass,n.textClass||""))),0==n.map.length&&n.map.push(0,0,n.content.appendChild(Oe(e.display.measure))),0==i?(t.measure.map=n.map,t.measure.cache={}):((t.measure.maps||(t.measure.maps=[])).push(n.map),(t.measure.caches||(t.measure.caches=[])).push({}))}if(a){var s=n.content.lastChild;(/\bcm-tab\b/.test(s.className)||s.querySelector&&s.querySelector(".cm-tab"))&&(n.content.className="cm-tab-wrap-hack")}return ge(e,"renderLine",e,t.line,n.pre),n.pre.className&&(n.textClass=F(n.pre.className,n.textClass||"")),n}function Qt(e){var t=O("span","•","cm-invalidchar");return t.title="\\u"+e.charCodeAt(0).toString(16),t.setAttribute("aria-label",t.title),t}function Jt(e,t,r,n,i,o,a){if(t){var u,c=e.splitSpaces?function(e,t){if(e.length>1&&!/ /.test(e))return e;for(var r=t,n="",i=0;iu&&h.from<=u);f++);if(h.to>=c)return e(r,n,i,o,l,s,a);e(r,n.slice(0,h.to-u),i,o,null,s,a),o=null,n=n.slice(h.to-u),u=h.to}}}function tr(e,t,r,n){var i=!n&&r.widgetNode;i&&e.map.push(e.pos,e.pos+t,i),!n&&e.cm.display.input.needsContentAttribute&&(i||(i=e.content.appendChild(document.createElement("span"))),i.setAttribute("cm-marker",r.id)),i&&(e.cm.display.input.setUneditable(i),e.content.appendChild(i)),e.pos+=t,e.trailingSpace=!1}function rr(e,t,r){var n=e.markedSpans,i=e.text,o=0;if(n)for(var l,s,a,u,c,h,f,d=i.length,p=0,g=1,v="",m=0;;){if(m==p){a=u=c=s="",f=null,h=null,m=1/0;for(var y=[],b=void 0,w=0;wp||C.collapsed&&x.to==p&&x.from==p)){if(null!=x.to&&x.to!=p&&m>x.to&&(m=x.to,u=""),C.className&&(a+=" "+C.className),C.css&&(s=(s?s+";":"")+C.css),C.startStyle&&x.from==p&&(c+=" "+C.startStyle),C.endStyle&&x.to==m&&(b||(b=[])).push(C.endStyle,x.to),C.title&&((f||(f={})).title=C.title),C.attributes)for(var S in C.attributes)(f||(f={}))[S]=C.attributes[S];C.collapsed&&(!h||Wt(h.marker,C)<0)&&(h=x)}else x.from>p&&m>x.from&&(m=x.from)}if(b)for(var L=0;L=d)break;for(var T=Math.min(d,m);;){if(v){var M=p+v.length;if(!h){var N=M>T?v.slice(0,T-p):v;t.addToken(t,N,l?l+a:a,c,p+N.length==m?u:"",s,f)}if(M>=T){v=v.slice(T-p),p=T;break}p=M,c=""}v=i.slice(o,o=r[g++]),l=qt(r[g++],t.cm.options)}}else for(var O=1;Or)return{map:e.measure.maps[i],cache:e.measure.caches[i],before:!0}}function Or(e,t,r,n){return Wr(e,Dr(e,t),r,n)}function Ar(e,t){if(t>=e.display.viewFrom&&t=r.lineN&&t2&&o.push((a.bottom+u.top)/2-r.top)}}o.push(r.bottom-r.top)}}(e,t.view,t.rect),t.hasHeights=!0),(o=function(e,t,r,n){var i,o=Pr(t.map,r,n),a=o.node,u=o.start,c=o.end,h=o.collapse;if(3==a.nodeType){for(var f=0;f<4;f++){for(;u&&ie(t.line.text.charAt(o.coverStart+u));)--u;for(;o.coverStart+c1}(e))return t;var r=screen.logicalXDPI/screen.deviceXDPI,n=screen.logicalYDPI/screen.deviceYDPI;return{left:t.left*r,right:t.right*r,top:t.top*n,bottom:t.bottom*n}}(e.display.measure,i))}else{var d;u>0&&(h=n="right"),i=e.options.lineWrapping&&(d=a.getClientRects()).length>1?d["right"==n?d.length-1:0]:a.getBoundingClientRect()}if(l&&s<9&&!u&&(!i||!i.left&&!i.right)){var p=a.parentNode.getClientRects()[0];i=p?{left:p.left,right:p.left+tn(e.display),top:p.top,bottom:p.bottom}:Fr}for(var g=i.top-t.rect.top,v=i.bottom-t.rect.top,m=(g+v)/2,y=t.view.measure.heights,b=0;bt)&&(i=(o=a-s)-1,t>=a&&(l="right")),null!=i){if(n=e[u+2],s==a&&r==(n.insertLeft?"left":"right")&&(l=r),"left"==r&&0==i)for(;u&&e[u-2]==e[u-3]&&e[u-1].insertLeft;)n=e[2+(u-=3)],l="left";if("right"==r&&i==a-s)for(;u=0&&(r=e[i]).left==r.right;i--);return r}function Ir(e){if(e.measure&&(e.measure.cache={},e.measure.heights=null,e.rest))for(var t=0;t=n.text.length?(a=n.text.length,u="before"):a<=0&&(a=0,u="after"),!s)return l("before"==u?a-1:a,"before"==u);function c(e,t,r){return l(r?e-1:e,1==s[t].level!=r)}var h=ae(s,a,u),f=se,d=c(a,h,"before"==u);return null!=f&&(d.other=c(a,f,"before"!=u)),d}function Yr(e,t){var r=0;t=st(e.doc,t),e.options.lineWrapping||(r=tn(e.display)*t.ch);var n=Xe(e.doc,t.line),i=Vt(n)+Cr(e.display);return{left:r,right:r,top:i,bottom:i+n.height}}function _r(e,t,r,n,i){var o=et(e,t,r);return o.xRel=i,n&&(o.outside=n),o}function $r(e,t,r){var n=e.doc;if((r+=e.display.viewOffset)<0)return _r(n.first,0,null,-1,-1);var i=Ze(n,r),o=n.first+n.size-1;if(i>o)return _r(n.first+n.size-1,Xe(n,o).text.length,null,1,1);t<0&&(t=0);for(var l=Xe(n,i);;){var s=Jr(e,l,i,t,r),a=Et(l,s.ch+(s.xRel>0||s.outside>0?1:0));if(!a)return s;var u=a.find(1);if(u.line==i)return u;l=Xe(n,i=u.line)}}function qr(e,t,r,n){n-=Ur(t);var i=t.text.length,o=le(function(t){return Wr(e,r,t-1).bottom<=n},i,0);return{begin:o,end:i=le(function(t){return Wr(e,r,t).top>n},o,i)}}function Zr(e,t,r,n){return r||(r=Dr(e,t)),qr(e,t,r,Vr(e,t,Wr(e,r,n),"line").top)}function Qr(e,t,r,n){return!(e.bottom<=r)&&(e.top>r||(n?e.left:e.right)>t)}function Jr(e,t,r,n,i){i-=Vt(t);var o=Dr(e,t),l=Ur(t),s=0,a=t.text.length,u=!0,c=ce(t,e.doc.direction);if(c){var h=(e.options.lineWrapping?function(e,t,r,n,i,o,l){var s=qr(e,t,n,l),a=s.begin,u=s.end;/\s/.test(t.text.charAt(u-1))&&u--;for(var c=null,h=null,f=0;f=u||d.to<=a)){var p=1!=d.level,g=Wr(e,n,p?Math.min(u,d.to)-1:Math.max(a,d.from)).right,v=gv)&&(c=d,h=v)}}c||(c=i[i.length-1]);c.fromu&&(c={from:c.from,to:u,level:c.level});return c}:function(e,t,r,n,i,o,l){var s=le(function(s){var a=i[s],u=1!=a.level;return Qr(Xr(e,et(r,u?a.to:a.from,u?"before":"after"),"line",t,n),o,l,!0)},0,i.length-1),a=i[s];if(s>0){var u=1!=a.level,c=Xr(e,et(r,u?a.from:a.to,u?"after":"before"),"line",t,n);Qr(c,o,l,!0)&&c.top>l&&(a=i[s-1])}return a})(e,t,r,o,c,n,i);s=(u=1!=h.level)?h.from:h.to-1,a=u?h.to:h.from-1}var f,d,p=null,g=null,v=le(function(t){var r=Wr(e,o,t);return r.top+=l,r.bottom+=l,!!Qr(r,n,i,!1)&&(r.top<=i&&r.left<=n&&(p=t,g=r),!0)},s,a),m=!1;if(g){var y=n-g.left=w.bottom?1:0}return _r(r,v=oe(t.text,v,1),d,m,n-f)}function en(e){if(null!=e.cachedTextHeight)return e.cachedTextHeight;if(null==Hr){Hr=O("pre",null,"CodeMirror-line-like");for(var t=0;t<49;++t)Hr.appendChild(document.createTextNode("x")),Hr.appendChild(O("br"));Hr.appendChild(document.createTextNode("x"))}N(e.measure,Hr);var r=Hr.offsetHeight/50;return r>3&&(e.cachedTextHeight=r),M(e.measure),r||1}function tn(e){if(null!=e.cachedCharWidth)return e.cachedCharWidth;var t=O("span","xxxxxxxxxx"),r=O("pre",[t],"CodeMirror-line-like");N(e.measure,r);var n=t.getBoundingClientRect(),i=(n.right-n.left)/10;return i>2&&(e.cachedCharWidth=i),i||10}function rn(e){for(var t=e.display,r={},n={},i=t.gutters.clientLeft,o=t.gutters.firstChild,l=0;o;o=o.nextSibling,++l){var s=e.display.gutterSpecs[l].className;r[s]=o.offsetLeft+o.clientLeft+i,n[s]=o.clientWidth}return{fixedPos:nn(t),gutterTotalWidth:t.gutters.offsetWidth,gutterLeft:r,gutterWidth:n,wrapperWidth:t.wrapper.clientWidth}}function nn(e){return e.scroller.getBoundingClientRect().left-e.sizer.getBoundingClientRect().left}function on(e){var t=en(e.display),r=e.options.lineWrapping,n=r&&Math.max(5,e.display.scroller.clientWidth/tn(e.display)-3);return function(i){if(Gt(e.doc,i))return 0;var o=0;if(i.widgets)for(var l=0;l=e.display.viewTo)return null;if((t-=e.display.viewFrom)<0)return null;for(var r=e.display.view,n=0;nt)&&(i.updateLineNumbers=t),e.curOp.viewChanged=!0,t>=i.viewTo)Ct&&Rt(e.doc,t)i.viewFrom?hn(e):(i.viewFrom+=n,i.viewTo+=n);else if(t<=i.viewFrom&&r>=i.viewTo)hn(e);else if(t<=i.viewFrom){var o=fn(e,r,r+n,1);o?(i.view=i.view.slice(o.index),i.viewFrom=o.lineN,i.viewTo+=n):hn(e)}else if(r>=i.viewTo){var l=fn(e,t,t,-1);l?(i.view=i.view.slice(0,l.index),i.viewTo=l.lineN):hn(e)}else{var s=fn(e,t,t,-1),a=fn(e,r,r+n,1);s&&a?(i.view=i.view.slice(0,s.index).concat(ir(e,s.lineN,a.lineN)).concat(i.view.slice(a.index)),i.viewTo+=n):hn(e)}var u=i.externalMeasured;u&&(r=i.lineN&&t=n.viewTo)){var o=n.view[an(e,t)];if(null!=o.node){var l=o.changes||(o.changes=[]);-1==B(l,r)&&l.push(r)}}}function hn(e){e.display.viewFrom=e.display.viewTo=e.doc.first,e.display.view=[],e.display.viewOffset=0}function fn(e,t,r,n){var i,o=an(e,t),l=e.display.view;if(!Ct||r==e.doc.first+e.doc.size)return{index:o,lineN:r};for(var s=e.display.viewFrom,a=0;a0){if(o==l.length-1)return null;i=s+l[o].size-t,o++}else i=s-t;t+=i,r+=i}for(;Rt(e.doc,r)!=r;){if(o==(n<0?0:l.length-1))return null;r+=n*l[o-(n<0?1:0)].size,o+=n}return{index:o,lineN:r}}function dn(e){for(var t=e.display.view,r=0,n=0;n=e.display.viewTo||s.to().linet||t==r&&l.to==t)&&(n(Math.max(l.from,t),Math.min(l.to,r),1==l.level?"rtl":"ltr",o),i=!0)}i||n(t,r,"ltr")}(g,r||0,null==n?f:n,function(e,t,i,h){var v="ltr"==i,m=d(e,v?"left":"right"),y=d(t-1,v?"right":"left"),b=null==r&&0==e,w=null==n&&t==f,x=0==h,C=!g||h==g.length-1;if(y.top-m.top<=3){var S=(u?w:b)&&C,L=(u?b:w)&&x?s:(v?m:y).left,k=S?a:(v?y:m).right;c(L,m.top,k-L,m.bottom)}else{var T,M,N,O;v?(T=u&&b&&x?s:m.left,M=u?a:p(e,i,"before"),N=u?s:p(t,i,"after"),O=u&&w&&C?a:y.right):(T=u?p(e,i,"before"):s,M=!u&&b&&x?a:m.right,N=!u&&w&&C?s:y.left,O=u?p(t,i,"after"):a),c(T,m.top,M-T,m.bottom),m.bottom0?t.blinker=setInterval(function(){return t.cursorDiv.style.visibility=(r=!r)?"":"hidden"},e.options.cursorBlinkRate):e.options.cursorBlinkRate<0&&(t.cursorDiv.style.visibility="hidden")}}function wn(e){e.state.focused||(e.display.input.focus(),Cn(e))}function xn(e){e.state.delayingBlurEvent=!0,setTimeout(function(){e.state.delayingBlurEvent&&(e.state.delayingBlurEvent=!1,Sn(e))},100)}function Cn(e,t){e.state.delayingBlurEvent&&(e.state.delayingBlurEvent=!1),"nocursor"!=e.options.readOnly&&(e.state.focused||(ge(e,"focus",e,t),e.state.focused=!0,H(e.display.wrapper,"CodeMirror-focused"),e.curOp||e.display.selForContextMenu==e.doc.sel||(e.display.input.reset(),a&&setTimeout(function(){return e.display.input.reset(!0)},20)),e.display.input.receivedFocus()),bn(e))}function Sn(e,t){e.state.delayingBlurEvent||(e.state.focused&&(ge(e,"blur",e,t),e.state.focused=!1,T(e.display.wrapper,"CodeMirror-focused")),clearInterval(e.display.blinker),setTimeout(function(){e.state.focused||(e.display.shift=!1)},150))}function Ln(e){for(var t=e.display,r=t.lineDiv.offsetTop,n=0;n.005||f<-.005)&&($e(i.line,a),kn(i.line),i.rest))for(var d=0;de.display.sizerWidth){var p=Math.ceil(u/tn(e.display));p>e.display.maxLineLength&&(e.display.maxLineLength=p,e.display.maxLine=i.line,e.display.maxLineChanged=!0)}}}}function kn(e){if(e.widgets)for(var t=0;t=l&&(o=Ze(t,Vt(Xe(t,a))-e.wrapper.clientHeight),l=a)}return{from:o,to:Math.max(l,o+1)}}function Mn(e,t){var r=e.display,n=en(e.display);t.top<0&&(t.top=0);var i=e.curOp&&null!=e.curOp.scrollTop?e.curOp.scrollTop:r.scroller.scrollTop,o=Mr(e),l={};t.bottom-t.top>o&&(t.bottom=t.top+o);var s=e.doc.height+Sr(r),a=t.tops-n;if(t.topi+o){var c=Math.min(t.top,(u?s:t.bottom)-o);c!=i&&(l.scrollTop=c)}var h=e.curOp&&null!=e.curOp.scrollLeft?e.curOp.scrollLeft:r.scroller.scrollLeft,f=Tr(e)-(e.options.fixedGutter?r.gutters.offsetWidth:0),d=t.right-t.left>f;return d&&(t.right=t.left+f),t.left<10?l.scrollLeft=0:t.leftf+h-3&&(l.scrollLeft=t.right+(d?0:10)-f),l}function Nn(e,t){null!=t&&(Dn(e),e.curOp.scrollTop=(null==e.curOp.scrollTop?e.doc.scrollTop:e.curOp.scrollTop)+t)}function On(e){Dn(e);var t=e.getCursor();e.curOp.scrollToPos={from:t,to:t,margin:e.options.cursorScrollMargin}}function An(e,t,r){null==t&&null==r||Dn(e),null!=t&&(e.curOp.scrollLeft=t),null!=r&&(e.curOp.scrollTop=r)}function Dn(e){var t=e.curOp.scrollToPos;t&&(e.curOp.scrollToPos=null,Wn(e,Yr(e,t.from),Yr(e,t.to),t.margin))}function Wn(e,t,r,n){var i=Mn(e,{left:Math.min(t.left,r.left),top:Math.min(t.top,r.top)-n,right:Math.max(t.right,r.right),bottom:Math.max(t.bottom,r.bottom)+n});An(e,i.scrollLeft,i.scrollTop)}function Hn(e,t){Math.abs(e.doc.scrollTop-t)<2||(r||oi(e,{top:t}),Fn(e,t,!0),r&&oi(e),ei(e,100))}function Fn(e,t,r){t=Math.min(e.display.scroller.scrollHeight-e.display.scroller.clientHeight,t),(e.display.scroller.scrollTop!=t||r)&&(e.doc.scrollTop=t,e.display.scrollbars.setScrollTop(t),e.display.scroller.scrollTop!=t&&(e.display.scroller.scrollTop=t))}function Pn(e,t,r,n){t=Math.min(t,e.display.scroller.scrollWidth-e.display.scroller.clientWidth),(r?t==e.doc.scrollLeft:Math.abs(e.doc.scrollLeft-t)<2)&&!n||(e.doc.scrollLeft=t,ai(e),e.display.scroller.scrollLeft!=t&&(e.display.scroller.scrollLeft=t),e.display.scrollbars.setScrollLeft(t))}function En(e){var t=e.display,r=t.gutters.offsetWidth,n=Math.round(e.doc.height+Sr(e.display));return{clientHeight:t.scroller.clientHeight,viewHeight:t.wrapper.clientHeight,scrollWidth:t.scroller.scrollWidth,clientWidth:t.scroller.clientWidth,viewWidth:t.wrapper.clientWidth,barLeft:e.options.fixedGutter?r:0,docHeight:n,scrollHeight:n+kr(e)+t.barHeight,nativeBarWidth:t.nativeBarWidth,gutterWidth:r}}var In=function(e,t,r){this.cm=r;var n=this.vert=O("div",[O("div",null,null,"min-width: 1px")],"CodeMirror-vscrollbar"),i=this.horiz=O("div",[O("div",null,null,"height: 100%; min-height: 1px")],"CodeMirror-hscrollbar");n.tabIndex=i.tabIndex=-1,e(n),e(i),fe(n,"scroll",function(){n.clientHeight&&t(n.scrollTop,"vertical")}),fe(i,"scroll",function(){i.clientWidth&&t(i.scrollLeft,"horizontal")}),this.checkedZeroWidth=!1,l&&s<8&&(this.horiz.style.minHeight=this.vert.style.minWidth="18px")};In.prototype.update=function(e){var t=e.scrollWidth>e.clientWidth+1,r=e.scrollHeight>e.clientHeight+1,n=e.nativeBarWidth;if(r){this.vert.style.display="block",this.vert.style.bottom=t?n+"px":"0";var i=e.viewHeight-(t?n:0);this.vert.firstChild.style.height=Math.max(0,e.scrollHeight-e.clientHeight+i)+"px"}else this.vert.style.display="",this.vert.firstChild.style.height="0";if(t){this.horiz.style.display="block",this.horiz.style.right=r?n+"px":"0",this.horiz.style.left=e.barLeft+"px";var o=e.viewWidth-e.barLeft-(r?n:0);this.horiz.firstChild.style.width=Math.max(0,e.scrollWidth-e.clientWidth+o)+"px"}else this.horiz.style.display="",this.horiz.firstChild.style.width="0";return!this.checkedZeroWidth&&e.clientHeight>0&&(0==n&&this.zeroWidthHack(),this.checkedZeroWidth=!0),{right:r?n:0,bottom:t?n:0}},In.prototype.setScrollLeft=function(e){this.horiz.scrollLeft!=e&&(this.horiz.scrollLeft=e),this.disableHoriz&&this.enableZeroWidthBar(this.horiz,this.disableHoriz,"horiz")},In.prototype.setScrollTop=function(e){this.vert.scrollTop!=e&&(this.vert.scrollTop=e),this.disableVert&&this.enableZeroWidthBar(this.vert,this.disableVert,"vert")},In.prototype.zeroWidthHack=function(){var e=y&&!d?"12px":"18px";this.horiz.style.height=this.vert.style.width=e,this.horiz.style.pointerEvents=this.vert.style.pointerEvents="none",this.disableHoriz=new R,this.disableVert=new R},In.prototype.enableZeroWidthBar=function(e,t,r){e.style.pointerEvents="auto",t.set(1e3,function n(){var i=e.getBoundingClientRect();("vert"==r?document.elementFromPoint(i.right-1,(i.top+i.bottom)/2):document.elementFromPoint((i.right+i.left)/2,i.bottom-1))!=e?e.style.pointerEvents="none":t.set(1e3,n)})},In.prototype.clear=function(){var e=this.horiz.parentNode;e.removeChild(this.horiz),e.removeChild(this.vert)};var zn=function(){};function Rn(e,t){t||(t=En(e));var r=e.display.barWidth,n=e.display.barHeight;Bn(e,t);for(var i=0;i<4&&r!=e.display.barWidth||n!=e.display.barHeight;i++)r!=e.display.barWidth&&e.options.lineWrapping&&Ln(e),Bn(e,En(e)),r=e.display.barWidth,n=e.display.barHeight}function Bn(e,t){var r=e.display,n=r.scrollbars.update(t);r.sizer.style.paddingRight=(r.barWidth=n.right)+"px",r.sizer.style.paddingBottom=(r.barHeight=n.bottom)+"px",r.heightForcer.style.borderBottom=n.bottom+"px solid transparent",n.right&&n.bottom?(r.scrollbarFiller.style.display="block",r.scrollbarFiller.style.height=n.bottom+"px",r.scrollbarFiller.style.width=n.right+"px"):r.scrollbarFiller.style.display="",n.bottom&&e.options.coverGutterNextToScrollbar&&e.options.fixedGutter?(r.gutterFiller.style.display="block",r.gutterFiller.style.height=n.bottom+"px",r.gutterFiller.style.width=t.gutterWidth+"px"):r.gutterFiller.style.display=""}zn.prototype.update=function(){return{bottom:0,right:0}},zn.prototype.setScrollLeft=function(){},zn.prototype.setScrollTop=function(){},zn.prototype.clear=function(){};var Gn={native:In,null:zn};function Un(e){e.display.scrollbars&&(e.display.scrollbars.clear(),e.display.scrollbars.addClass&&T(e.display.wrapper,e.display.scrollbars.addClass)),e.display.scrollbars=new Gn[e.options.scrollbarStyle](function(t){e.display.wrapper.insertBefore(t,e.display.scrollbarFiller),fe(t,"mousedown",function(){e.state.focused&&setTimeout(function(){return e.display.input.focus()},0)}),t.setAttribute("cm-not-content","true")},function(t,r){"horizontal"==r?Pn(e,t):Hn(e,t)},e),e.display.scrollbars.addClass&&H(e.display.wrapper,e.display.scrollbars.addClass)}var Vn=0;function Kn(e){var t;e.curOp={cm:e,viewChanged:!1,startHeight:e.doc.height,forceUpdate:!1,updateInput:0,typing:!1,changeObjs:null,cursorActivityHandlers:null,cursorActivityCalled:0,selectionChanged:!1,updateMaxLine:!1,scrollLeft:null,scrollTop:null,scrollToPos:null,focus:!1,id:++Vn},t=e.curOp,or?or.ops.push(t):t.ownsGroup=or={ops:[t],delayedCallbacks:[]}}function jn(e){var t=e.curOp;t&&function(e,t){var r=e.ownsGroup;if(r)try{!function(e){var t=e.delayedCallbacks,r=0;do{for(;r=r.viewTo)||r.maxLineChanged&&t.options.lineWrapping,e.update=e.mustUpdate&&new ri(t,e.mustUpdate&&{top:e.scrollTop,ensure:e.scrollToPos},e.forceUpdate)}function Yn(e){var t=e.cm,r=t.display;e.updatedDisplay&&Ln(t),e.barMeasure=En(t),r.maxLineChanged&&!t.options.lineWrapping&&(e.adjustWidthTo=Or(t,r.maxLine,r.maxLine.text.length).left+3,t.display.sizerWidth=e.adjustWidthTo,e.barMeasure.scrollWidth=Math.max(r.scroller.clientWidth,r.sizer.offsetLeft+e.adjustWidthTo+kr(t)+t.display.barWidth),e.maxScrollLeft=Math.max(0,r.sizer.offsetLeft+e.adjustWidthTo-Tr(t))),(e.updatedDisplay||e.selectionChanged)&&(e.preparedSelection=r.input.prepareSelection())}function _n(e){var t=e.cm;null!=e.adjustWidthTo&&(t.display.sizer.style.minWidth=e.adjustWidthTo+"px",e.maxScrollLeft(window.innerHeight||document.documentElement.clientHeight)&&(i=!1),null!=i&&!p){var o=O("div","​",null,"position: absolute;\n top: "+(t.top-r.viewOffset-Cr(e.display))+"px;\n height: "+(t.bottom-t.top+kr(e)+r.barHeight)+"px;\n left: "+t.left+"px; width: "+Math.max(2,t.right-t.left)+"px;");e.display.lineSpace.appendChild(o),o.scrollIntoView(i),e.display.lineSpace.removeChild(o)}}}(t,function(e,t,r,n){var i;null==n&&(n=0),e.options.lineWrapping||t!=r||(r="before"==(t=t.ch?et(t.line,"before"==t.sticky?t.ch-1:t.ch,"after"):t).sticky?et(t.line,t.ch+1,"before"):t);for(var o=0;o<5;o++){var l=!1,s=Xr(e,t),a=r&&r!=t?Xr(e,r):s,u=Mn(e,i={left:Math.min(s.left,a.left),top:Math.min(s.top,a.top)-n,right:Math.max(s.left,a.left),bottom:Math.max(s.bottom,a.bottom)+n}),c=e.doc.scrollTop,h=e.doc.scrollLeft;if(null!=u.scrollTop&&(Hn(e,u.scrollTop),Math.abs(e.doc.scrollTop-c)>1&&(l=!0)),null!=u.scrollLeft&&(Pn(e,u.scrollLeft),Math.abs(e.doc.scrollLeft-h)>1&&(l=!0)),!l)break}return i}(t,st(n,e.scrollToPos.from),st(n,e.scrollToPos.to),e.scrollToPos.margin));var i=e.maybeHiddenMarkers,o=e.maybeUnhiddenMarkers;if(i)for(var l=0;l=e.display.viewTo)){var r=+new Date+e.options.workTime,n=dt(e,t.highlightFrontier),i=[];t.iter(n.line,Math.min(t.first+t.size,e.display.viewTo+500),function(o){if(n.line>=e.display.viewFrom){var l=o.styles,s=o.text.length>e.options.maxHighlightLength?Ue(t.mode,n.state):null,a=ht(e,o,n,!0);s&&(n.state=s),o.styles=a.styles;var u=o.styleClasses,c=a.classes;c?o.styleClasses=c:u&&(o.styleClasses=null);for(var h=!l||l.length!=o.styles.length||u!=c&&(!u||!c||u.bgClass!=c.bgClass||u.textClass!=c.textClass),f=0;!h&&fr)return ei(e,e.options.workDelay),!0}),t.highlightFrontier=n.line,t.modeFrontier=Math.max(t.modeFrontier,n.line),i.length&&qn(e,function(){for(var t=0;t=r.viewFrom&&t.visible.to<=r.viewTo&&(null==r.updateLineNumbers||r.updateLineNumbers>=r.viewTo)&&r.renderedView==r.view&&0==dn(e))return!1;ui(e)&&(hn(e),t.dims=rn(e));var i=n.first+n.size,o=Math.max(t.visible.from-e.options.viewportMargin,n.first),l=Math.min(i,t.visible.to+e.options.viewportMargin);r.viewFroml&&r.viewTo-l<20&&(l=Math.min(i,r.viewTo)),Ct&&(o=Rt(e.doc,o),l=Bt(e.doc,l));var s=o!=r.viewFrom||l!=r.viewTo||r.lastWrapHeight!=t.wrapperHeight||r.lastWrapWidth!=t.wrapperWidth;!function(e,t,r){var n=e.display;0==n.view.length||t>=n.viewTo||r<=n.viewFrom?(n.view=ir(e,t,r),n.viewFrom=t):(n.viewFrom>t?n.view=ir(e,t,n.viewFrom).concat(n.view):n.viewFromr&&(n.view=n.view.slice(0,an(e,r)))),n.viewTo=r}(e,o,l),r.viewOffset=Vt(Xe(e.doc,r.viewFrom)),e.display.mover.style.top=r.viewOffset+"px";var u=dn(e);if(!s&&0==u&&!t.force&&r.renderedView==r.view&&(null==r.updateLineNumbers||r.updateLineNumbers>=r.viewTo))return!1;var c=function(e){if(e.hasFocus())return null;var t=W();if(!t||!D(e.display.lineDiv,t))return null;var r={activeElt:t};if(window.getSelection){var n=window.getSelection();n.anchorNode&&n.extend&&D(e.display.lineDiv,n.anchorNode)&&(r.anchorNode=n.anchorNode,r.anchorOffset=n.anchorOffset,r.focusNode=n.focusNode,r.focusOffset=n.focusOffset)}return r}(e);return u>4&&(r.lineDiv.style.display="none"),function(e,t,r){var n=e.display,i=e.options.lineNumbers,o=n.lineDiv,l=o.firstChild;function s(t){var r=t.nextSibling;return a&&y&&e.display.currentWheelTarget==t?t.style.display="none":t.parentNode.removeChild(t),r}for(var u=n.view,c=n.viewFrom,h=0;h-1&&(d=!1),ur(e,f,c,r)),d&&(M(f.lineNumber),f.lineNumber.appendChild(document.createTextNode(Je(e.options,c)))),l=f.node.nextSibling}else{var p=vr(e,f,c,r);o.insertBefore(p,l)}c+=f.size}for(;l;)l=s(l)}(e,r.updateLineNumbers,t.dims),u>4&&(r.lineDiv.style.display=""),r.renderedView=r.view,function(e){if(e&&e.activeElt&&e.activeElt!=W()&&(e.activeElt.focus(),e.anchorNode&&D(document.body,e.anchorNode)&&D(document.body,e.focusNode))){var t=window.getSelection(),r=document.createRange();r.setEnd(e.anchorNode,e.anchorOffset),r.collapse(!1),t.removeAllRanges(),t.addRange(r),t.extend(e.focusNode,e.focusOffset)}}(c),M(r.cursorDiv),M(r.selectionDiv),r.gutters.style.height=r.sizer.style.minHeight=0,s&&(r.lastWrapHeight=t.wrapperHeight,r.lastWrapWidth=t.wrapperWidth,ei(e,400)),r.updateLineNumbers=null,!0}function ii(e,t){for(var r=t.viewport,n=!0;(n&&e.options.lineWrapping&&t.oldDisplayWidth!=Tr(e)||(r&&null!=r.top&&(r={top:Math.min(e.doc.height+Sr(e.display)-Mr(e),r.top)}),t.visible=Tn(e.display,e.doc,r),!(t.visible.from>=e.display.viewFrom&&t.visible.to<=e.display.viewTo)))&&ni(e,t);n=!1){Ln(e);var i=En(e);pn(e),Rn(e,i),si(e,i),t.force=!1}t.signal(e,"update",e),e.display.viewFrom==e.display.reportedViewFrom&&e.display.viewTo==e.display.reportedViewTo||(t.signal(e,"viewportChange",e,e.display.viewFrom,e.display.viewTo),e.display.reportedViewFrom=e.display.viewFrom,e.display.reportedViewTo=e.display.viewTo)}function oi(e,t){var r=new ri(e,t);if(ni(e,r)){Ln(e),ii(e,r);var n=En(e);pn(e),Rn(e,n),si(e,n),r.finish()}}function li(e){var t=e.gutters.offsetWidth;e.sizer.style.marginLeft=t+"px"}function si(e,t){e.display.sizer.style.minHeight=t.docHeight+"px",e.display.heightForcer.style.top=t.docHeight+"px",e.display.gutters.style.height=t.docHeight+e.display.barHeight+kr(e)+"px"}function ai(e){var t=e.display,r=t.view;if(t.alignWidgets||t.gutters.firstChild&&e.options.fixedGutter){for(var n=nn(t)-t.scroller.scrollLeft+e.doc.scrollLeft,i=t.gutters.offsetWidth,o=n+"px",l=0;ls.clientWidth,c=s.scrollHeight>s.clientHeight;if(i&&u||o&&c){if(o&&y&&a)e:for(var f=t.target,d=l.view;f!=s;f=f.parentNode)for(var p=0;p=0&&tt(e,n.to())<=0)return r}return-1};var bi=function(e,t){this.anchor=e,this.head=t};function wi(e,t,r){var n=e&&e.options.selectionsMayTouch,i=t[r];t.sort(function(e,t){return tt(e.from(),t.from())}),r=B(t,i);for(var o=1;o0:a>=0){var u=ot(s.from(),l.from()),c=it(s.to(),l.to()),h=s.empty()?l.from()==l.head:s.from()==s.head;o<=r&&--r,t.splice(--o,2,new bi(h?c:u,h?u:c))}}return new yi(t,r)}function xi(e,t){return new yi([new bi(e,t||e)],0)}function Ci(e){return e.text?et(e.from.line+e.text.length-1,$(e.text).length+(1==e.text.length?e.from.ch:0)):e.to}function Si(e,t){if(tt(e,t.from)<0)return e;if(tt(e,t.to)<=0)return Ci(t);var r=e.line+t.text.length-(t.to.line-t.from.line)-1,n=e.ch;return e.line==t.to.line&&(n+=Ci(t).ch-t.to.ch),et(r,n)}function Li(e,t){for(var r=[],n=0;n1&&e.remove(s.line+1,p-1),e.insert(s.line+1,m)}sr(e,"change",e,t)}function Ai(e,t,r){!function e(n,i,o){if(n.linked)for(var l=0;ls-(e.cm?e.cm.options.historyEventDelay:500)||"*"==t.origin.charAt(0)))&&(o=function(e,t){return t?(Pi(e.done),$(e.done)):e.done.length&&!$(e.done).ranges?$(e.done):e.done.length>1&&!e.done[e.done.length-2].ranges?(e.done.pop(),$(e.done)):void 0}(i,i.lastOp==n)))l=$(o.changes),0==tt(t.from,t.to)&&0==tt(t.from,l.to)?l.to=Ci(t):o.changes.push(Fi(e,t));else{var a=$(i.done);for(a&&a.ranges||zi(e.sel,i.done),o={changes:[Fi(e,t)],generation:i.generation},i.done.push(o);i.done.length>i.undoDepth;)i.done.shift(),i.done[0].ranges||i.done.shift()}i.done.push(r),i.generation=++i.maxGeneration,i.lastModTime=i.lastSelTime=s,i.lastOp=i.lastSelOp=n,i.lastOrigin=i.lastSelOrigin=t.origin,l||ge(e,"historyAdded")}function Ii(e,t,r,n){var i=e.history,o=n&&n.origin;r==i.lastSelOp||o&&i.lastSelOrigin==o&&(i.lastModTime==i.lastSelTime&&i.lastOrigin==o||function(e,t,r,n){var i=t.charAt(0);return"*"==i||"+"==i&&r.ranges.length==n.ranges.length&&r.somethingSelected()==n.somethingSelected()&&new Date-e.history.lastSelTime<=(e.cm?e.cm.options.historyEventDelay:500)}(e,o,$(i.done),t))?i.done[i.done.length-1]=t:zi(t,i.done),i.lastSelTime=+new Date,i.lastSelOrigin=o,i.lastSelOp=r,n&&!1!==n.clearRedo&&Pi(i.undone)}function zi(e,t){var r=$(t);r&&r.ranges&&r.equals(e)||t.push(e)}function Ri(e,t,r,n){var i=t["spans_"+e.id],o=0;e.iter(Math.max(e.first,r),Math.min(e.first+e.size,n),function(r){r.markedSpans&&((i||(i=t["spans_"+e.id]={}))[o]=r.markedSpans),++o})}function Bi(e){if(!e)return null;for(var t,r=0;r-1&&($(s)[h]=u[h],delete u[h])}}}return n}function Vi(e,t,r,n){if(n){var i=e.anchor;if(r){var o=tt(t,i)<0;o!=tt(r,i)<0?(i=t,t=r):o!=tt(t,r)<0&&(t=r)}return new bi(i,t)}return new bi(r||t,t)}function Ki(e,t,r,n,i){null==i&&(i=e.cm&&(e.cm.display.shift||e.extend)),$i(e,new yi([Vi(e.sel.primary(),t,r,i)],0),n)}function ji(e,t,r){for(var n=[],i=e.cm&&(e.cm.display.shift||e.extend),o=0;o=t.ch:s.to>t.ch))){if(i&&(ge(a,"beforeCursorEnter"),a.explicitlyCleared)){if(o.markedSpans){--l;continue}break}if(!a.atomic)continue;if(r){var h=a.find(n<0?1:-1),f=void 0;if((n<0?c:u)&&(h=ro(e,h,-n,h&&h.line==t.line?o:null)),h&&h.line==t.line&&(f=tt(h,r))&&(n<0?f<0:f>0))return eo(e,h,t,n,i)}var d=a.find(n<0?-1:1);return(n<0?u:c)&&(d=ro(e,d,n,d.line==t.line?o:null)),d?eo(e,d,t,n,i):null}}return t}function to(e,t,r,n,i){var o=n||1,l=eo(e,t,r,o,i)||!i&&eo(e,t,r,o,!0)||eo(e,t,r,-o,i)||!i&&eo(e,t,r,-o,!0);return l||(e.cantEdit=!0,et(e.first,0))}function ro(e,t,r,n){return r<0&&0==t.ch?t.line>e.first?st(e,et(t.line-1)):null:r>0&&t.ch==(n||Xe(e,t.line)).text.length?t.line0)){var c=[a,1],h=tt(u.from,s.from),f=tt(u.to,s.to);(h<0||!l.inclusiveLeft&&!h)&&c.push({from:u.from,to:s.from}),(f>0||!l.inclusiveRight&&!f)&&c.push({from:s.to,to:u.to}),i.splice.apply(i,c),a+=c.length-3}}return i}(e,t.from,t.to);if(n)for(var i=n.length-1;i>=0;--i)lo(e,{from:n[i].from,to:n[i].to,text:i?[""]:t.text,origin:t.origin});else lo(e,t)}}function lo(e,t){if(1!=t.text.length||""!=t.text[0]||0!=tt(t.from,t.to)){var r=Li(e,t);Ei(e,t,r,e.cm?e.cm.curOp.id:NaN),uo(e,t,r,Tt(e,t));var n=[];Ai(e,function(e,r){r||-1!=B(n,e.history)||(po(e.history,t),n.push(e.history)),uo(e,t,null,Tt(e,t))})}}function so(e,t,r){var n=e.cm&&e.cm.state.suppressEdits;if(!n||r){for(var i,o=e.history,l=e.sel,s="undo"==t?o.done:o.undone,a="undo"==t?o.undone:o.done,u=0;u=0;--d){var p=f(d);if(p)return p.v}}}}function ao(e,t){if(0!=t&&(e.first+=t,e.sel=new yi(q(e.sel.ranges,function(e){return new bi(et(e.anchor.line+t,e.anchor.ch),et(e.head.line+t,e.head.ch))}),e.sel.primIndex),e.cm)){un(e.cm,e.first,e.first-t,t);for(var r=e.cm.display,n=r.viewFrom;ne.lastLine())){if(t.from.lineo&&(t={from:t.from,to:et(o,Xe(e,o).text.length),text:[t.text[0]],origin:t.origin}),t.removed=Ye(e,t.from,t.to),r||(r=Li(e,t)),e.cm?function(e,t,r){var n=e.doc,i=e.display,o=t.from,l=t.to,s=!1,a=o.line;e.options.lineWrapping||(a=qe(zt(Xe(n,o.line))),n.iter(a,l.line+1,function(e){if(e==i.maxLine)return s=!0,!0}));n.sel.contains(t.from,t.to)>-1&&me(e);Oi(n,t,r,on(e)),e.options.lineWrapping||(n.iter(a,o.line+t.text.length,function(e){var t=Kt(e);t>i.maxLineLength&&(i.maxLine=e,i.maxLineLength=t,i.maxLineChanged=!0,s=!1)}),s&&(e.curOp.updateMaxLine=!0));(function(e,t){if(e.modeFrontier=Math.min(e.modeFrontier,t),!(e.highlightFrontierr;n--){var i=Xe(e,n).stateAfter;if(i&&(!(i instanceof ut)||n+i.lookAhead1||!(this.children[0]instanceof vo))){var s=[];this.collapse(s),this.children=[new vo(s)],this.children[0].parent=this}},collapse:function(e){for(var t=0;t50){for(var l=i.lines.length%25+25,s=l;s10);e.parent.maybeSpill()}},iterN:function(e,t,r){for(var n=0;n0||0==l&&!1!==o.clearWhenEmpty)return o;if(o.replacedWith&&(o.collapsed=!0,o.widgetNode=A("span",[o.replacedWith],"CodeMirror-widget"),n.handleMouseEvents||o.widgetNode.setAttribute("cm-ignore-events","true"),n.insertLeft&&(o.widgetNode.insertLeft=!0)),o.collapsed){if(It(e,t.line,t,r,o)||t.line!=r.line&&It(e,r.line,t,r,o))throw new Error("Inserting collapsed marker partially overlapping an existing one");Ct=!0}o.addToHistory&&Ei(e,{from:t,to:r,origin:"markText"},e.sel,NaN);var s,a=t.line,u=e.cm;if(e.iter(a,r.line+1,function(e){u&&o.collapsed&&!u.options.lineWrapping&&zt(e)==u.display.maxLine&&(s=!0),o.collapsed&&a!=t.line&&$e(e,0),function(e,t){e.markedSpans=e.markedSpans?e.markedSpans.concat([t]):[t],t.marker.attachLine(e)}(e,new St(o,a==t.line?t.ch:null,a==r.line?r.ch:null)),++a}),o.collapsed&&e.iter(t.line,r.line+1,function(t){Gt(e,t)&&$e(t,0)}),o.clearOnEnter&&fe(o,"beforeCursorEnter",function(){return o.clear()}),o.readOnly&&(xt=!0,(e.history.done.length||e.history.undone.length)&&e.clearHistory()),o.collapsed&&(o.id=++wo,o.atomic=!0),u){if(s&&(u.curOp.updateMaxLine=!0),o.collapsed)un(u,t.line,r.line+1);else if(o.className||o.startStyle||o.endStyle||o.css||o.attributes||o.title)for(var c=t.line;c<=r.line;c++)cn(u,c,"text");o.atomic&&Qi(u.doc),sr(u,"markerAdded",u,o)}return o}xo.prototype.clear=function(){if(!this.explicitlyCleared){var e=this.doc.cm,t=e&&!e.curOp;if(t&&Kn(e),ye(this,"clear")){var r=this.find();r&&sr(this,"clear",r.from,r.to)}for(var n=null,i=null,o=0;oe.display.maxLineLength&&(e.display.maxLine=u,e.display.maxLineLength=c,e.display.maxLineChanged=!0)}null!=n&&e&&this.collapsed&&un(e,n,i+1),this.lines.length=0,this.explicitlyCleared=!0,this.atomic&&this.doc.cantEdit&&(this.doc.cantEdit=!1,e&&Qi(e.doc)),e&&sr(e,"markerCleared",e,this,n,i),t&&jn(e),this.parent&&this.parent.clear()}},xo.prototype.find=function(e,t){var r,n;null==e&&"bookmark"==this.type&&(e=1);for(var i=0;i=0;a--)oo(this,n[a]);s?_i(this,s):this.cm&&On(this.cm)}),undo:Jn(function(){so(this,"undo")}),redo:Jn(function(){so(this,"redo")}),undoSelection:Jn(function(){so(this,"undo",!0)}),redoSelection:Jn(function(){so(this,"redo",!0)}),setExtending:function(e){this.extend=e},getExtending:function(){return this.extend},historySize:function(){for(var e=this.history,t=0,r=0,n=0;n=e.ch)&&t.push(i.marker.parent||i.marker)}return t},findMarks:function(e,t,r){e=st(this,e),t=st(this,t);var n=[],i=e.line;return this.iter(e.line,t.line+1,function(o){var l=o.markedSpans;if(l)for(var s=0;s=a.to||null==a.from&&i!=e.line||null!=a.from&&i==t.line&&a.from>=t.ch||r&&!r(a.marker)||n.push(a.marker.parent||a.marker)}++i}),n},getAllMarks:function(){var e=[];return this.iter(function(t){var r=t.markedSpans;if(r)for(var n=0;ne)return t=e,!0;e-=o,++r}),st(this,et(r,t))},indexFromPos:function(e){var t=(e=st(this,e)).ch;if(e.linet&&(t=e.from),null!=e.to&&e.to-1)return t.state.draggingText(e),void setTimeout(function(){return t.display.input.focus()},20);try{var c=e.dataTransfer.getData("Text");if(c){var h;if(t.state.draggingText&&!t.state.draggingText.copy&&(h=t.listSelections()),qi(t.doc,xi(r,r)),h)for(var f=0;f=0;t--)co(e.doc,"",n[t].from,n[t].to,"+delete");On(e)})}function _o(e,t,r){var n=oe(e.text,t+r,r);return n<0||n>e.text.length?null:n}function $o(e,t,r){var n=_o(e,t.ch,r);return null==n?null:new et(t.line,n,r<0?"after":"before")}function qo(e,t,r,n,i){if(e){var o=ce(r,t.doc.direction);if(o){var l,s=i<0?$(o):o[0],a=i<0==(1==s.level)?"after":"before";if(s.level>0||"rtl"==t.doc.direction){var u=Dr(t,r);l=i<0?r.text.length-1:0;var c=Wr(t,u,l).top;l=le(function(e){return Wr(t,u,e).top==c},i<0==(1==s.level)?s.from:s.to-1,l),"before"==a&&(l=_o(r,l,1))}else l=i<0?s.to:s.from;return new et(n,l,a)}}return new et(n,i<0?r.text.length:0,i<0?"before":"after")}Ro.basic={Left:"goCharLeft",Right:"goCharRight",Up:"goLineUp",Down:"goLineDown",End:"goLineEnd",Home:"goLineStartSmart",PageUp:"goPageUp",PageDown:"goPageDown",Delete:"delCharAfter",Backspace:"delCharBefore","Shift-Backspace":"delCharBefore",Tab:"defaultTab","Shift-Tab":"indentAuto",Enter:"newlineAndIndent",Insert:"toggleOverwrite",Esc:"singleSelection"},Ro.pcDefault={"Ctrl-A":"selectAll","Ctrl-D":"deleteLine","Ctrl-Z":"undo","Shift-Ctrl-Z":"redo","Ctrl-Y":"redo","Ctrl-Home":"goDocStart","Ctrl-End":"goDocEnd","Ctrl-Up":"goLineUp","Ctrl-Down":"goLineDown","Ctrl-Left":"goGroupLeft","Ctrl-Right":"goGroupRight","Alt-Left":"goLineStart","Alt-Right":"goLineEnd","Ctrl-Backspace":"delGroupBefore","Ctrl-Delete":"delGroupAfter","Ctrl-S":"save","Ctrl-F":"find","Ctrl-G":"findNext","Shift-Ctrl-G":"findPrev","Shift-Ctrl-F":"replace","Shift-Ctrl-R":"replaceAll","Ctrl-[":"indentLess","Ctrl-]":"indentMore","Ctrl-U":"undoSelection","Shift-Ctrl-U":"redoSelection","Alt-U":"redoSelection",fallthrough:"basic"},Ro.emacsy={"Ctrl-F":"goCharRight","Ctrl-B":"goCharLeft","Ctrl-P":"goLineUp","Ctrl-N":"goLineDown","Alt-F":"goWordRight","Alt-B":"goWordLeft","Ctrl-A":"goLineStart","Ctrl-E":"goLineEnd","Ctrl-V":"goPageDown","Shift-Ctrl-V":"goPageUp","Ctrl-D":"delCharAfter","Ctrl-H":"delCharBefore","Alt-D":"delWordAfter","Alt-Backspace":"delWordBefore","Ctrl-K":"killLine","Ctrl-T":"transposeChars","Ctrl-O":"openLine"},Ro.macDefault={"Cmd-A":"selectAll","Cmd-D":"deleteLine","Cmd-Z":"undo","Shift-Cmd-Z":"redo","Cmd-Y":"redo","Cmd-Home":"goDocStart","Cmd-Up":"goDocStart","Cmd-End":"goDocEnd","Cmd-Down":"goDocEnd","Alt-Left":"goGroupLeft","Alt-Right":"goGroupRight","Cmd-Left":"goLineLeft","Cmd-Right":"goLineRight","Alt-Backspace":"delGroupBefore","Ctrl-Alt-Backspace":"delGroupAfter","Alt-Delete":"delGroupAfter","Cmd-S":"save","Cmd-F":"find","Cmd-G":"findNext","Shift-Cmd-G":"findPrev","Cmd-Alt-F":"replace","Shift-Cmd-Alt-F":"replaceAll","Cmd-[":"indentLess","Cmd-]":"indentMore","Cmd-Backspace":"delWrappedLineLeft","Cmd-Delete":"delWrappedLineRight","Cmd-U":"undoSelection","Shift-Cmd-U":"redoSelection","Ctrl-Up":"goDocStart","Ctrl-Down":"goDocEnd",fallthrough:["basic","emacsy"]},Ro.default=y?Ro.macDefault:Ro.pcDefault;var Zo={selectAll:no,singleSelection:function(e){return e.setSelection(e.getCursor("anchor"),e.getCursor("head"),V)},killLine:function(e){return Yo(e,function(t){if(t.empty()){var r=Xe(e.doc,t.head.line).text.length;return t.head.ch==r&&t.head.line0)i=new et(i.line,i.ch+1),e.replaceRange(o.charAt(i.ch-1)+o.charAt(i.ch-2),et(i.line,i.ch-2),i,"+transpose");else if(i.line>e.doc.first){var l=Xe(e.doc,i.line-1).text;l&&(i=new et(i.line,1),e.replaceRange(o.charAt(0)+e.doc.lineSeparator()+l.charAt(l.length-1),et(i.line-1,l.length-1),i,"+transpose"))}r.push(new bi(i,i))}e.setSelections(r)})},newlineAndIndent:function(e){return qn(e,function(){for(var t=e.listSelections(),r=t.length-1;r>=0;r--)e.replaceRange(e.doc.lineSeparator(),t[r].anchor,t[r].head,"+input");t=e.listSelections();for(var n=0;n-1&&(tt((i=u.ranges[i]).from(),t)<0||t.xRel>0)&&(tt(i.to(),t)>0||t.xRel<0)?function(e,t,r,n){var i=e.display,o=!1,u=Zn(e,function(t){a&&(i.scroller.draggable=!1),e.state.draggingText=!1,pe(i.wrapper.ownerDocument,"mouseup",u),pe(i.wrapper.ownerDocument,"mousemove",c),pe(i.scroller,"dragstart",h),pe(i.scroller,"drop",u),o||(we(t),n.addNew||Ki(e.doc,r,null,null,n.extend),a||l&&9==s?setTimeout(function(){i.wrapper.ownerDocument.body.focus(),i.input.focus()},20):i.input.focus())}),c=function(e){o=o||Math.abs(t.clientX-e.clientX)+Math.abs(t.clientY-e.clientY)>=10},h=function(){return o=!0};a&&(i.scroller.draggable=!0);e.state.draggingText=u,u.copy=!n.moveOnDrag,i.scroller.dragDrop&&i.scroller.dragDrop();fe(i.wrapper.ownerDocument,"mouseup",u),fe(i.wrapper.ownerDocument,"mousemove",c),fe(i.scroller,"dragstart",h),fe(i.scroller,"drop",u),xn(e),setTimeout(function(){return i.input.focus()},20)}(e,n,t,o):function(e,t,r,n){var i=e.display,o=e.doc;we(t);var l,s,a=o.sel,u=a.ranges;n.addNew&&!n.extend?(s=o.sel.contains(r),l=s>-1?u[s]:new bi(r,r)):(l=o.sel.primary(),s=o.sel.primIndex);if("rectangle"==n.unit)n.addNew||(l=new bi(r,r)),r=sn(e,t,!0,!0),s=-1;else{var c=dl(e,r,n.unit);l=n.extend?Vi(l,c.anchor,c.head,n.extend):c}n.addNew?-1==s?(s=u.length,$i(o,wi(e,u.concat([l]),s),{scroll:!1,origin:"*mouse"})):u.length>1&&u[s].empty()&&"char"==n.unit&&!n.extend?($i(o,wi(e,u.slice(0,s).concat(u.slice(s+1)),0),{scroll:!1,origin:"*mouse"}),a=o.sel):Xi(o,s,l,K):(s=0,$i(o,new yi([l],0),K),a=o.sel);var h=r;function f(t){if(0!=tt(h,t))if(h=t,"rectangle"==n.unit){for(var i=[],u=e.options.tabSize,c=z(Xe(o,r.line).text,r.ch,u),f=z(Xe(o,t.line).text,t.ch,u),d=Math.min(c,f),p=Math.max(c,f),g=Math.min(r.line,t.line),v=Math.min(e.lastLine(),Math.max(r.line,t.line));g<=v;g++){var m=Xe(o,g).text,y=X(m,d,u);d==p?i.push(new bi(et(g,y),et(g,y))):m.length>y&&i.push(new bi(et(g,y),et(g,X(m,p,u))))}i.length||i.push(new bi(r,r)),$i(o,wi(e,a.ranges.slice(0,s).concat(i),s),{origin:"*mouse",scroll:!1}),e.scrollIntoView(t)}else{var b,w=l,x=dl(e,t,n.unit),C=w.anchor;tt(x.anchor,C)>0?(b=x.head,C=ot(w.from(),x.anchor)):(b=x.anchor,C=it(w.to(),x.head));var S=a.ranges.slice(0);S[s]=function(e,t){var r=t.anchor,n=t.head,i=Xe(e.doc,r.line);if(0==tt(r,n)&&r.sticky==n.sticky)return t;var o=ce(i);if(!o)return t;var l=ae(o,r.ch,r.sticky),s=o[l];if(s.from!=r.ch&&s.to!=r.ch)return t;var a,u=l+(s.from==r.ch==(1!=s.level)?0:1);if(0==u||u==o.length)return t;if(n.line!=r.line)a=(n.line-r.line)*("ltr"==e.doc.direction?1:-1)>0;else{var c=ae(o,n.ch,n.sticky),h=c-l||(n.ch-r.ch)*(1==s.level?-1:1);a=c==u-1||c==u?h<0:h>0}var f=o[u+(a?-1:0)],d=a==(1==f.level),p=d?f.from:f.to,g=d?"after":"before";return r.ch==p&&r.sticky==g?t:new bi(new et(r.line,p,g),n)}(e,new bi(st(o,C),b)),$i(o,wi(e,S,s),K)}}var d=i.wrapper.getBoundingClientRect(),p=0;function g(t){e.state.selectingText=!1,p=1/0,t&&(we(t),i.input.focus()),pe(i.wrapper.ownerDocument,"mousemove",v),pe(i.wrapper.ownerDocument,"mouseup",m),o.history.lastSelOrigin=null}var v=Zn(e,function(t){0!==t.buttons&&ke(t)?function t(r){var l=++p;var s=sn(e,r,!0,"rectangle"==n.unit);if(!s)return;if(0!=tt(s,h)){e.curOp.focus=W(),f(s);var a=Tn(i,o);(s.line>=a.to||s.lined.bottom?20:0;u&&setTimeout(Zn(e,function(){p==l&&(i.scroller.scrollTop+=u,t(r))}),50)}}(t):g(t)}),m=Zn(e,g);e.state.selectingText=m,fe(i.wrapper.ownerDocument,"mousemove",v),fe(i.wrapper.ownerDocument,"mouseup",m)}(e,n,t,o)}(t,n,o,e):Le(e)==r.scroller&&we(e):2==i?(n&&Ki(t.doc,n),setTimeout(function(){return r.input.focus()},20)):3==i&&(S?t.display.input.onContextMenu(e):xn(t)))}}function dl(e,t,r){if("char"==r)return new bi(t,t);if("word"==r)return e.findWordAt(t);if("line"==r)return new bi(et(t.line,0),st(e.doc,et(t.line+1,0)));var n=r(e,t);return new bi(n.from,n.to)}function pl(e,t,r,n){var i,o;if(t.touches)i=t.touches[0].clientX,o=t.touches[0].clientY;else try{i=t.clientX,o=t.clientY}catch(t){return!1}if(i>=Math.floor(e.display.gutters.getBoundingClientRect().right))return!1;n&&we(t);var l=e.display,s=l.lineDiv.getBoundingClientRect();if(o>s.bottom||!ye(e,r))return Ce(t);o-=s.top-l.viewOffset;for(var a=0;a=i)return ge(e,r,e,Ze(e.doc,o),e.display.gutterSpecs[a].className,t),Ce(t)}}function gl(e,t){return pl(e,t,"gutterClick",!0)}function vl(e,t){xr(e.display,t)||function(e,t){if(!ye(e,"gutterContextMenu"))return!1;return pl(e,t,"gutterContextMenu",!1)}(e,t)||ve(e,t,"contextmenu")||S||e.display.input.onContextMenu(t)}function ml(e){e.display.wrapper.className=e.display.wrapper.className.replace(/\s*cm-s-\S+/g,"")+e.options.theme.replace(/(^|\s)\s*/g," cm-s-"),Rr(e)}hl.prototype.compare=function(e,t,r){return this.time+400>e&&0==tt(t,this.pos)&&r==this.button};var yl={toString:function(){return"CodeMirror.Init"}},bl={},wl={};function xl(e,t,r){if(!t!=!(r&&r!=yl)){var n=e.display.dragFunctions,i=t?fe:pe;i(e.display.scroller,"dragstart",n.start),i(e.display.scroller,"dragenter",n.enter),i(e.display.scroller,"dragover",n.over),i(e.display.scroller,"dragleave",n.leave),i(e.display.scroller,"drop",n.drop)}}function Cl(e){e.options.lineWrapping?(H(e.display.wrapper,"CodeMirror-wrap"),e.display.sizer.style.minWidth="",e.display.sizerWidth=null):(T(e.display.wrapper,"CodeMirror-wrap"),jt(e)),ln(e),un(e),Rr(e),setTimeout(function(){return Rn(e)},100)}function Sl(e,t){var n=this;if(!(this instanceof Sl))return new Sl(e,t);this.options=t=t?I(t):{},I(bl,t,!1);var i=t.value;"string"==typeof i?i=new Mo(i,t.mode,null,t.lineSeparator,t.direction):t.mode&&(i.modeOption=t.mode),this.doc=i;var o=new Sl.inputStyles[t.inputStyle](this),u=this.display=new function(e,t,n,i){var o=this;this.input=n,o.scrollbarFiller=O("div",null,"CodeMirror-scrollbar-filler"),o.scrollbarFiller.setAttribute("cm-not-content","true"),o.gutterFiller=O("div",null,"CodeMirror-gutter-filler"),o.gutterFiller.setAttribute("cm-not-content","true"),o.lineDiv=A("div",null,"CodeMirror-code"),o.selectionDiv=O("div",null,null,"position: relative; z-index: 1"),o.cursorDiv=O("div",null,"CodeMirror-cursors"),o.measure=O("div",null,"CodeMirror-measure"),o.lineMeasure=O("div",null,"CodeMirror-measure"),o.lineSpace=A("div",[o.measure,o.lineMeasure,o.selectionDiv,o.cursorDiv,o.lineDiv],null,"position: relative; outline: none");var u=A("div",[o.lineSpace],"CodeMirror-lines");o.mover=O("div",[u],null,"position: relative"),o.sizer=O("div",[o.mover],"CodeMirror-sizer"),o.sizerWidth=null,o.heightForcer=O("div",null,null,"position: absolute; height: "+G+"px; width: 1px;"),o.gutters=O("div",null,"CodeMirror-gutters"),o.lineGutter=null,o.scroller=O("div",[o.sizer,o.heightForcer,o.gutters],"CodeMirror-scroll"),o.scroller.setAttribute("tabIndex","-1"),o.wrapper=O("div",[o.scrollbarFiller,o.gutterFiller,o.scroller],"CodeMirror"),l&&s<8&&(o.gutters.style.zIndex=-1,o.scroller.style.paddingRight=0),a||r&&m||(o.scroller.draggable=!0),e&&(e.appendChild?e.appendChild(o.wrapper):e(o.wrapper)),o.viewFrom=o.viewTo=t.first,o.reportedViewFrom=o.reportedViewTo=t.first,o.view=[],o.renderedView=null,o.externalMeasured=null,o.viewOffset=0,o.lastWrapHeight=o.lastWrapWidth=0,o.updateLineNumbers=null,o.nativeBarWidth=o.barHeight=o.barWidth=0,o.scrollbarsClipped=!1,o.lineNumWidth=o.lineNumInnerWidth=o.lineNumChars=null,o.alignWidgets=!1,o.cachedCharWidth=o.cachedTextHeight=o.cachedPaddingH=null,o.maxLine=null,o.maxLineLength=0,o.maxLineChanged=!1,o.wheelDX=o.wheelDY=o.wheelStartX=o.wheelStartY=null,o.shift=!1,o.selForContextMenu=null,o.activeTouch=null,o.gutterSpecs=ci(i.gutters,i.lineNumbers),hi(o),n.init(o)}(e,i,o,t);for(var c in u.wrapper.CodeMirror=this,ml(this),t.lineWrapping&&(this.display.wrapper.className+=" CodeMirror-wrap"),Un(this),this.state={keyMaps:[],overlays:[],modeGen:0,overwrite:!1,delayingBlurEvent:!1,focused:!1,suppressEdits:!1,pasteIncoming:-1,cutIncoming:-1,selectingText:!1,draggingText:!1,highlight:new R,keySeq:null,specialChars:null},t.autofocus&&!m&&u.input.focus(),l&&s<11&&setTimeout(function(){return n.display.input.reset(!0)},20),function(e){var t=e.display;fe(t.scroller,"mousedown",Zn(e,fl)),fe(t.scroller,"dblclick",l&&s<11?Zn(e,function(t){if(!ve(e,t)){var r=sn(e,t);if(r&&!gl(e,t)&&!xr(e.display,t)){we(t);var n=e.findWordAt(r);Ki(e.doc,n.anchor,n.head)}}}):function(t){return ve(e,t)||we(t)});fe(t.scroller,"contextmenu",function(t){return vl(e,t)});var r,n={end:0};function i(){t.activeTouch&&(r=setTimeout(function(){return t.activeTouch=null},1e3),(n=t.activeTouch).end=+new Date)}function o(e,t){if(null==t.left)return!0;var r=t.left-e.left,n=t.top-e.top;return r*r+n*n>400}fe(t.scroller,"touchstart",function(i){if(!ve(e,i)&&!function(e){if(1!=e.touches.length)return!1;var t=e.touches[0];return t.radiusX<=1&&t.radiusY<=1}(i)&&!gl(e,i)){t.input.ensurePolled(),clearTimeout(r);var o=+new Date;t.activeTouch={start:o,moved:!1,prev:o-n.end<=300?n:null},1==i.touches.length&&(t.activeTouch.left=i.touches[0].pageX,t.activeTouch.top=i.touches[0].pageY)}}),fe(t.scroller,"touchmove",function(){t.activeTouch&&(t.activeTouch.moved=!0)}),fe(t.scroller,"touchend",function(r){var n=t.activeTouch;if(n&&!xr(t,r)&&null!=n.left&&!n.moved&&new Date-n.start<300){var l,s=e.coordsChar(t.activeTouch,"page");l=!n.prev||o(n,n.prev)?new bi(s,s):!n.prev.prev||o(n,n.prev.prev)?e.findWordAt(s):new bi(et(s.line,0),st(e.doc,et(s.line+1,0))),e.setSelection(l.anchor,l.head),e.focus(),we(r)}i()}),fe(t.scroller,"touchcancel",i),fe(t.scroller,"scroll",function(){t.scroller.clientHeight&&(Hn(e,t.scroller.scrollTop),Pn(e,t.scroller.scrollLeft,!0),ge(e,"scroll",e))}),fe(t.scroller,"mousewheel",function(t){return mi(e,t)}),fe(t.scroller,"DOMMouseScroll",function(t){return mi(e,t)}),fe(t.wrapper,"scroll",function(){return t.wrapper.scrollTop=t.wrapper.scrollLeft=0}),t.dragFunctions={enter:function(t){ve(e,t)||Se(t)},over:function(t){ve(e,t)||(!function(e,t){var r=sn(e,t);if(r){var n=document.createDocumentFragment();vn(e,r,n),e.display.dragCursor||(e.display.dragCursor=O("div",null,"CodeMirror-cursors CodeMirror-dragcursors"),e.display.lineSpace.insertBefore(e.display.dragCursor,e.display.cursorDiv)),N(e.display.dragCursor,n)}}(e,t),Se(t))},start:function(t){return function(e,t){if(l&&(!e.state.draggingText||+new Date-No<100))Se(t);else if(!ve(e,t)&&!xr(e.display,t)&&(t.dataTransfer.setData("Text",e.getSelection()),t.dataTransfer.effectAllowed="copyMove",t.dataTransfer.setDragImage&&!f)){var r=O("img",null,null,"position: fixed; left: 0; top: 0;");r.src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==",h&&(r.width=r.height=1,e.display.wrapper.appendChild(r),r._top=r.offsetTop),t.dataTransfer.setDragImage(r,0,0),h&&r.parentNode.removeChild(r)}}(e,t)},drop:Zn(e,Oo),leave:function(t){ve(e,t)||Ao(e)}};var a=t.input.getField();fe(a,"keyup",function(t){return sl.call(e,t)}),fe(a,"keydown",Zn(e,ll)),fe(a,"keypress",Zn(e,al)),fe(a,"focus",function(t){return Cn(e,t)}),fe(a,"blur",function(t){return Sn(e,t)})}(this),Ho(),Kn(this),this.curOp.forceUpdate=!0,Di(this,i),t.autofocus&&!m||this.hasFocus()?setTimeout(E(Cn,this),20):Sn(this),wl)wl.hasOwnProperty(c)&&wl[c](n,t[c],yl);ui(this),t.finishInit&&t.finishInit(this);for(var d=0;d150)){if(!n)return;r="prev"}}else u=0,r="not";"prev"==r?u=t>o.first?z(Xe(o,t-1).text,null,l):0:"add"==r?u=a+e.options.indentUnit:"subtract"==r?u=a-e.options.indentUnit:"number"==typeof r&&(u=a+r),u=Math.max(0,u);var h="",f=0;if(e.options.indentWithTabs)for(var d=Math.floor(u/l);d;--d)f+=l,h+="\t";if(fl,a=We(t),u=null;if(s&&n.ranges.length>1)if(Tl&&Tl.text.join("\n")==t){if(n.ranges.length%Tl.text.length==0){u=[];for(var c=0;c=0;f--){var d=n.ranges[f],p=d.from(),g=d.to();d.empty()&&(r&&r>0?p=et(p.line,p.ch-r):e.state.overwrite&&!s?g=et(g.line,Math.min(Xe(o,g.line).text.length,g.ch+$(a).length)):s&&Tl&&Tl.lineWise&&Tl.text.join("\n")==t&&(p=g=et(p.line,0)));var v={from:p,to:g,text:u?u[f%u.length]:a,origin:i||(s?"paste":e.state.cutIncoming>l?"cut":"+input")};oo(e.doc,v),sr(e,"inputRead",e,v)}t&&!s&&Al(e,t),On(e),e.curOp.updateInput<2&&(e.curOp.updateInput=h),e.curOp.typing=!0,e.state.pasteIncoming=e.state.cutIncoming=-1}function Ol(e,t){var r=e.clipboardData&&e.clipboardData.getData("Text");if(r)return e.preventDefault(),t.isReadOnly()||t.options.disableInput||qn(t,function(){return Nl(t,r,0,null,"paste")}),!0}function Al(e,t){if(e.options.electricChars&&e.options.smartIndent)for(var r=e.doc.sel,n=r.ranges.length-1;n>=0;n--){var i=r.ranges[n];if(!(i.head.ch>100||n&&r.ranges[n-1].head.line==i.head.line)){var o=e.getModeAt(i.head),l=!1;if(o.electricChars){for(var s=0;s-1){l=kl(e,i.head.line,"smart");break}}else o.electricInput&&o.electricInput.test(Xe(e.doc,i.head.line).text.slice(0,i.head.ch))&&(l=kl(e,i.head.line,"smart"));l&&sr(e,"electricInput",e,i.head.line)}}}function Dl(e){for(var t=[],r=[],n=0;n=t.text.length?(r.ch=t.text.length,r.sticky="before"):r.ch<=0&&(r.ch=0,r.sticky="after");var o=ae(i,r.ch,r.sticky),l=i[o];if("ltr"==e.doc.direction&&l.level%2==0&&(n>0?l.to>r.ch:l.from=l.from&&f>=c.begin)){var d=h?"before":"after";return new et(r.line,f,d)}}var p=function(e,t,n){for(var o=function(e,t){return t?new et(r.line,a(e,1),"before"):new et(r.line,e,"after")};e>=0&&e0==(1!=l.level),u=s?n.begin:a(n.end,-1);if(l.from<=u&&u0?c.end:a(c.begin,-1);return null==v||n>0&&v==t.text.length||!(g=p(n>0?0:i.length-1,n,u(v)))?null:g}(e.cm,s,t,r):$o(s,t,r))){if(n||(l=t.line+r)=e.first+e.size||(t=new et(l,t.ch,t.sticky),!(s=Xe(e,l))))return!1;t=qo(i,e.cm,s,t.line,r)}else t=o;return!0}if("char"==n)a();else if("column"==n)a(!0);else if("word"==n||"group"==n)for(var u=null,c="group"==n,h=e.cm&&e.cm.getHelper(t,"wordChars"),f=!0;!(r<0)||a(!f);f=!1){var d=s.text.charAt(t.ch)||"\n",p=te(d,h)?"w":c&&"\n"==d?"n":!c||/\s/.test(d)?null:"p";if(!c||f||p||(p="s"),u&&u!=p){r<0&&(r=1,a(),t.sticky="after");break}if(p&&(u=p),r>0&&!a(!f))break}var g=to(e,t,o,l,!0);return rt(o,g)&&(g.hitSide=!0),g}function Pl(e,t,r,n){var i,o,l=e.doc,s=t.left;if("page"==n){var a=Math.min(e.display.wrapper.clientHeight,window.innerHeight||document.documentElement.clientHeight),u=Math.max(a-.5*en(e.display),3);i=(r>0?t.bottom:t.top)+r*u}else"line"==n&&(i=r>0?t.bottom+3:t.top-3);for(;(o=$r(e,s,i)).outside;){if(r<0?i<=0:i>=l.height){o.hitSide=!0;break}i+=5*r}return o}var El=function(e){this.cm=e,this.lastAnchorNode=this.lastAnchorOffset=this.lastFocusNode=this.lastFocusOffset=null,this.polling=new R,this.composing=null,this.gracePeriod=!1,this.readDOMTimeout=null};function Il(e,t){var r=Ar(e,t.line);if(!r||r.hidden)return null;var n=Xe(e.doc,t.line),i=Nr(r,n,t.line),o=ce(n,e.doc.direction),l="left";o&&(l=ae(o,t.ch)%2?"right":"left");var s=Pr(i.map,t.ch,l);return s.offset="right"==s.collapse?s.end:s.start,s}function zl(e,t){return t&&(e.bad=!0),e}function Rl(e,t,r){var n;if(t==e.display.lineDiv){if(!(n=e.display.lineDiv.childNodes[r]))return zl(e.clipPos(et(e.display.viewTo-1)),!0);t=null,r=0}else for(n=t;;n=n.parentNode){if(!n||n==e.display.lineDiv)return null;if(n.parentNode&&n.parentNode==e.display.lineDiv)break}for(var i=0;i=t.display.viewTo||o.line=t.display.viewFrom&&Il(t,i)||{node:a[0].measure.map[2],offset:0},c=o.linen.firstLine()&&(l=et(l.line-1,Xe(n.doc,l.line-1).length)),s.ch==Xe(n.doc,s.line).text.length&&s.linei.viewTo-1)return!1;l.line==i.viewFrom||0==(e=an(n,l.line))?(t=qe(i.view[0].line),r=i.view[0].node):(t=qe(i.view[e].line),r=i.view[e-1].node.nextSibling);var a,u,c=an(n,s.line);if(c==i.view.length-1?(a=i.viewTo-1,u=i.lineDiv.lastChild):(a=qe(i.view[c+1].line)-1,u=i.view[c+1].node.previousSibling),!r)return!1;for(var h=n.doc.splitLines(function(e,t,r,n,i){var o="",l=!1,s=e.doc.lineSeparator(),a=!1;function u(){l&&(o+=s,a&&(o+=s),l=a=!1)}function c(e){e&&(u(),o+=e)}function h(t){if(1==t.nodeType){var r=t.getAttribute("cm-text");if(r)return void c(r);var o,f=t.getAttribute("cm-marker");if(f){var d=e.findMarks(et(n,0),et(i+1,0),(v=+f,function(e){return e.id==v}));return void(d.length&&(o=d[0].find(0))&&c(Ye(e.doc,o.from,o.to).join(s)))}if("false"==t.getAttribute("contenteditable"))return;var p=/^(pre|div|p|li|table|br)$/i.test(t.nodeName);if(!/^br$/i.test(t.nodeName)&&0==t.textContent.length)return;p&&u();for(var g=0;g1&&f.length>1;)if($(h)==$(f))h.pop(),f.pop(),a--;else{if(h[0]!=f[0])break;h.shift(),f.shift(),t++}for(var d=0,p=0,g=h[0],v=f[0],m=Math.min(g.length,v.length);dl.ch&&y.charCodeAt(y.length-p-1)==b.charCodeAt(b.length-p-1);)d--,p++;h[h.length-1]=y.slice(0,y.length-p).replace(/^\u200b+/,""),h[0]=h[0].slice(d).replace(/\u200b+$/,"");var x=et(t,d),C=et(a,f.length?$(f).length-p:0);return h.length>1||h[0]||tt(x,C)?(co(n.doc,h,x,C,"+input"),!0):void 0},El.prototype.ensurePolled=function(){this.forceCompositionEnd()},El.prototype.reset=function(){this.forceCompositionEnd()},El.prototype.forceCompositionEnd=function(){this.composing&&(clearTimeout(this.readDOMTimeout),this.composing=null,this.updateFromDOM(),this.div.blur(),this.div.focus())},El.prototype.readFromDOMSoon=function(){var e=this;null==this.readDOMTimeout&&(this.readDOMTimeout=setTimeout(function(){if(e.readDOMTimeout=null,e.composing){if(!e.composing.done)return;e.composing=null}e.updateFromDOM()},80))},El.prototype.updateFromDOM=function(){var e=this;!this.cm.isReadOnly()&&this.pollContent()||qn(this.cm,function(){return un(e.cm)})},El.prototype.setUneditable=function(e){e.contentEditable="false"},El.prototype.onKeyPress=function(e){0==e.charCode||this.composing||(e.preventDefault(),this.cm.isReadOnly()||Zn(this.cm,Nl)(this.cm,String.fromCharCode(null==e.charCode?e.keyCode:e.charCode),0))},El.prototype.readOnlyChanged=function(e){this.div.contentEditable=String("nocursor"!=e)},El.prototype.onContextMenu=function(){},El.prototype.resetPosition=function(){},El.prototype.needsContentAttribute=!0;var Gl=function(e){this.cm=e,this.prevInput="",this.pollingFast=!1,this.polling=new R,this.hasSelection=!1,this.composing=null};Gl.prototype.init=function(e){var t=this,r=this,n=this.cm;this.createField(e);var i=this.textarea;function o(e){if(!ve(n,e)){if(n.somethingSelected())Ml({lineWise:!1,text:n.getSelections()});else{if(!n.options.lineWiseCopyCut)return;var t=Dl(n);Ml({lineWise:!0,text:t.text}),"cut"==e.type?n.setSelections(t.ranges,null,V):(r.prevInput="",i.value=t.text.join("\n"),P(i))}"cut"==e.type&&(n.state.cutIncoming=+new Date)}}e.wrapper.insertBefore(this.wrapper,e.wrapper.firstChild),g&&(i.style.width="0px"),fe(i,"input",function(){l&&s>=9&&t.hasSelection&&(t.hasSelection=null),r.poll()}),fe(i,"paste",function(e){ve(n,e)||Ol(e,n)||(n.state.pasteIncoming=+new Date,r.fastPoll())}),fe(i,"cut",o),fe(i,"copy",o),fe(e.scroller,"paste",function(t){if(!xr(e,t)&&!ve(n,t)){if(!i.dispatchEvent)return n.state.pasteIncoming=+new Date,void r.focus();var o=new Event("paste");o.clipboardData=t.clipboardData,i.dispatchEvent(o)}}),fe(e.lineSpace,"selectstart",function(t){xr(e,t)||we(t)}),fe(i,"compositionstart",function(){var e=n.getCursor("from");r.composing&&r.composing.range.clear(),r.composing={start:e,range:n.markText(e,n.getCursor("to"),{className:"CodeMirror-composing"})}}),fe(i,"compositionend",function(){r.composing&&(r.poll(),r.composing.range.clear(),r.composing=null)})},Gl.prototype.createField=function(e){this.wrapper=Hl(),this.textarea=this.wrapper.firstChild},Gl.prototype.prepareSelection=function(){var e=this.cm,t=e.display,r=e.doc,n=gn(e);if(e.options.moveInputWithCursor){var i=Xr(e,r.sel.primary().head,"div"),o=t.wrapper.getBoundingClientRect(),l=t.lineDiv.getBoundingClientRect();n.teTop=Math.max(0,Math.min(t.wrapper.clientHeight-10,i.top+l.top-o.top)),n.teLeft=Math.max(0,Math.min(t.wrapper.clientWidth-10,i.left+l.left-o.left))}return n},Gl.prototype.showSelection=function(e){var t=this.cm.display;N(t.cursorDiv,e.cursors),N(t.selectionDiv,e.selection),null!=e.teTop&&(this.wrapper.style.top=e.teTop+"px",this.wrapper.style.left=e.teLeft+"px")},Gl.prototype.reset=function(e){if(!this.contextMenuPending&&!this.composing){var t=this.cm;if(t.somethingSelected()){this.prevInput="";var r=t.getSelection();this.textarea.value=r,t.state.focused&&P(this.textarea),l&&s>=9&&(this.hasSelection=r)}else e||(this.prevInput=this.textarea.value="",l&&s>=9&&(this.hasSelection=null))}},Gl.prototype.getField=function(){return this.textarea},Gl.prototype.supportsTouch=function(){return!1},Gl.prototype.focus=function(){if("nocursor"!=this.cm.options.readOnly&&(!m||W()!=this.textarea))try{this.textarea.focus()}catch(e){}},Gl.prototype.blur=function(){this.textarea.blur()},Gl.prototype.resetPosition=function(){this.wrapper.style.top=this.wrapper.style.left=0},Gl.prototype.receivedFocus=function(){this.slowPoll()},Gl.prototype.slowPoll=function(){var e=this;this.pollingFast||this.polling.set(this.cm.options.pollInterval,function(){e.poll(),e.cm.state.focused&&e.slowPoll()})},Gl.prototype.fastPoll=function(){var e=!1,t=this;t.pollingFast=!0,t.polling.set(20,function r(){t.poll()||e?(t.pollingFast=!1,t.slowPoll()):(e=!0,t.polling.set(60,r))})},Gl.prototype.poll=function(){var e=this,t=this.cm,r=this.textarea,n=this.prevInput;if(this.contextMenuPending||!t.state.focused||He(r)&&!n&&!this.composing||t.isReadOnly()||t.options.disableInput||t.state.keySeq)return!1;var i=r.value;if(i==n&&!t.somethingSelected())return!1;if(l&&s>=9&&this.hasSelection===i||y&&/[\uf700-\uf7ff]/.test(i))return t.display.input.reset(),!1;if(t.doc.sel==t.display.selForContextMenu){var o=i.charCodeAt(0);if(8203!=o||n||(n="​"),8666==o)return this.reset(),this.cm.execCommand("undo")}for(var a=0,u=Math.min(n.length,i.length);a1e3||i.indexOf("\n")>-1?r.value=e.prevInput="":e.prevInput=i,e.composing&&(e.composing.range.clear(),e.composing.range=t.markText(e.composing.start,t.getCursor("to"),{className:"CodeMirror-composing"}))}),!0},Gl.prototype.ensurePolled=function(){this.pollingFast&&this.poll()&&(this.pollingFast=!1)},Gl.prototype.onKeyPress=function(){l&&s>=9&&(this.hasSelection=null),this.fastPoll()},Gl.prototype.onContextMenu=function(e){var t=this,r=t.cm,n=r.display,i=t.textarea;t.contextMenuPending&&t.contextMenuPending();var o=sn(r,e),u=n.scroller.scrollTop;if(o&&!h){r.options.resetSelectionOnContextMenu&&-1==r.doc.sel.contains(o)&&Zn(r,$i)(r.doc,xi(o),V);var c,f=i.style.cssText,d=t.wrapper.style.cssText,p=t.wrapper.offsetParent.getBoundingClientRect();if(t.wrapper.style.cssText="position: static",i.style.cssText="position: absolute; width: 30px; height: 30px;\n top: "+(e.clientY-p.top-5)+"px; left: "+(e.clientX-p.left-5)+"px;\n z-index: 1000; background: "+(l?"rgba(255, 255, 255, .05)":"transparent")+";\n outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);",a&&(c=window.scrollY),n.input.focus(),a&&window.scrollTo(null,c),n.input.reset(),r.somethingSelected()||(i.value=t.prevInput=" "),t.contextMenuPending=m,n.selForContextMenu=r.doc.sel,clearTimeout(n.detectingSelectAll),l&&s>=9&&v(),S){Se(e);var g=function(){pe(window,"mouseup",g),setTimeout(m,20)};fe(window,"mouseup",g)}else setTimeout(m,50)}function v(){if(null!=i.selectionStart){var e=r.somethingSelected(),o="​"+(e?i.value:"");i.value="⇚",i.value=o,t.prevInput=e?"":"​",i.selectionStart=1,i.selectionEnd=o.length,n.selForContextMenu=r.doc.sel}}function m(){if(t.contextMenuPending==m&&(t.contextMenuPending=!1,t.wrapper.style.cssText=d,i.style.cssText=f,l&&s<9&&n.scrollbars.setScrollTop(n.scroller.scrollTop=u),null!=i.selectionStart)){(!l||l&&s<9)&&v();var e=0,o=function(){n.selForContextMenu==r.doc.sel&&0==i.selectionStart&&i.selectionEnd>0&&"​"==t.prevInput?Zn(r,no)(r):e++<10?n.detectingSelectAll=setTimeout(o,500):(n.selForContextMenu=null,n.input.reset())};n.detectingSelectAll=setTimeout(o,200)}}},Gl.prototype.readOnlyChanged=function(e){e||this.reset(),this.textarea.disabled="nocursor"==e},Gl.prototype.setUneditable=function(){},Gl.prototype.needsContentAttribute=!1,function(e){var t=e.optionHandlers;function r(r,n,i,o){e.defaults[r]=n,i&&(t[r]=o?function(e,t,r){r!=yl&&i(e,t,r)}:i)}e.defineOption=r,e.Init=yl,r("value","",function(e,t){return e.setValue(t)},!0),r("mode",null,function(e,t){e.doc.modeOption=t,Ti(e)},!0),r("indentUnit",2,Ti,!0),r("indentWithTabs",!1),r("smartIndent",!0),r("tabSize",4,function(e){Mi(e),Rr(e),un(e)},!0),r("lineSeparator",null,function(e,t){if(e.doc.lineSep=t,t){var r=[],n=e.doc.first;e.doc.iter(function(e){for(var i=0;;){var o=e.text.indexOf(t,i);if(-1==o)break;i=o+t.length,r.push(et(n,o))}n++});for(var i=r.length-1;i>=0;i--)co(e.doc,t,r[i],et(r[i].line,r[i].ch+t.length))}}),r("specialChars",/[\u0000-\u001f\u007f-\u009f\u00ad\u061c\u200b-\u200f\u2028\u2029\ufeff\ufff9-\ufffc]/g,function(e,t,r){e.state.specialChars=new RegExp(t.source+(t.test("\t")?"":"|\t"),"g"),r!=yl&&e.refresh()}),r("specialCharPlaceholder",Qt,function(e){return e.refresh()},!0),r("electricChars",!0),r("inputStyle",m?"contenteditable":"textarea",function(){throw new Error("inputStyle can not (yet) be changed in a running editor")},!0),r("spellcheck",!1,function(e,t){return e.getInputField().spellcheck=t},!0),r("autocorrect",!1,function(e,t){return e.getInputField().autocorrect=t},!0),r("autocapitalize",!1,function(e,t){return e.getInputField().autocapitalize=t},!0),r("rtlMoveVisually",!w),r("wholeLineUpdateBefore",!0),r("theme","default",function(e){ml(e),fi(e)},!0),r("keyMap","default",function(e,t,r){var n=Xo(t),i=r!=yl&&Xo(r);i&&i.detach&&i.detach(e,n),n.attach&&n.attach(e,i||null)}),r("extraKeys",null),r("configureMouse",null),r("lineWrapping",!1,Cl,!0),r("gutters",[],function(e,t){e.display.gutterSpecs=ci(t,e.options.lineNumbers),fi(e)},!0),r("fixedGutter",!0,function(e,t){e.display.gutters.style.left=t?nn(e.display)+"px":"0",e.refresh()},!0),r("coverGutterNextToScrollbar",!1,function(e){return Rn(e)},!0),r("scrollbarStyle","native",function(e){Un(e),Rn(e),e.display.scrollbars.setScrollTop(e.doc.scrollTop),e.display.scrollbars.setScrollLeft(e.doc.scrollLeft)},!0),r("lineNumbers",!1,function(e,t){e.display.gutterSpecs=ci(e.options.gutters,t),fi(e)},!0),r("firstLineNumber",1,fi,!0),r("lineNumberFormatter",function(e){return e},fi,!0),r("showCursorWhenSelecting",!1,pn,!0),r("resetSelectionOnContextMenu",!0),r("lineWiseCopyCut",!0),r("pasteLinesPerSelection",!0),r("selectionsMayTouch",!1),r("readOnly",!1,function(e,t){"nocursor"==t&&(Sn(e),e.display.input.blur()),e.display.input.readOnlyChanged(t)}),r("disableInput",!1,function(e,t){t||e.display.input.reset()},!0),r("dragDrop",!0,xl),r("allowDropFileTypes",null),r("cursorBlinkRate",530),r("cursorScrollMargin",0),r("cursorHeight",1,pn,!0),r("singleCursorHeightPerLine",!0,pn,!0),r("workTime",100),r("workDelay",100),r("flattenSpans",!0,Mi,!0),r("addModeClass",!1,Mi,!0),r("pollInterval",100),r("undoDepth",200,function(e,t){return e.doc.history.undoDepth=t}),r("historyEventDelay",1250),r("viewportMargin",10,function(e){return e.refresh()},!0),r("maxHighlightLength",1e4,Mi,!0),r("moveInputWithCursor",!0,function(e,t){t||e.display.input.resetPosition()}),r("tabindex",null,function(e,t){return e.display.input.getField().tabIndex=t||""}),r("autofocus",null),r("direction","ltr",function(e,t){return e.doc.setDirection(t)},!0),r("phrases",null)}(Sl),function(e){var t=e.optionHandlers,r=e.helpers={};e.prototype={constructor:e,focus:function(){window.focus(),this.display.input.focus()},setOption:function(e,r){var n=this.options,i=n[e];n[e]==r&&"mode"!=e||(n[e]=r,t.hasOwnProperty(e)&&Zn(this,t[e])(this,r,i),ge(this,"optionChange",this,e))},getOption:function(e){return this.options[e]},getDoc:function(){return this.doc},addKeyMap:function(e,t){this.state.keyMaps[t?"push":"unshift"](Xo(e))},removeKeyMap:function(e){for(var t=this.state.keyMaps,r=0;rr&&(kl(this,i.head.line,e,!0),r=i.head.line,n==this.doc.sel.primIndex&&On(this));else{var o=i.from(),l=i.to(),s=Math.max(r,o.line);r=Math.min(this.lastLine(),l.line-(l.ch?0:1))+1;for(var a=s;a0&&Xi(this.doc,n,new bi(o,u[n].to()),V)}}}),getTokenAt:function(e,t){return yt(this,e,t)},getLineTokens:function(e,t){return yt(this,et(e),t,!0)},getTokenTypeAt:function(e){e=st(this.doc,e);var t,r=ft(this,Xe(this.doc,e.line)),n=0,i=(r.length-1)/2,o=e.ch;if(0==o)t=r[2];else for(;;){var l=n+i>>1;if((l?r[2*l-1]:0)>=o)i=l;else{if(!(r[2*l+1]o&&(e=o,i=!0),n=Xe(this.doc,e)}else n=e;return Vr(this,n,{top:0,left:0},t||"page",r||i).top+(i?this.doc.height-Vt(n):0)},defaultTextHeight:function(){return en(this.display)},defaultCharWidth:function(){return tn(this.display)},getViewport:function(){return{from:this.display.viewFrom,to:this.display.viewTo}},addWidget:function(e,t,r,n,i){var o,l,s,a=this.display,u=(e=Xr(this,st(this.doc,e))).bottom,c=e.left;if(t.style.position="absolute",t.setAttribute("cm-ignore-events","true"),this.display.input.setUneditable(t),a.sizer.appendChild(t),"over"==n)u=e.top;else if("above"==n||"near"==n){var h=Math.max(a.wrapper.clientHeight,this.doc.height),f=Math.max(a.sizer.clientWidth,a.lineSpace.clientWidth);("above"==n||e.bottom+t.offsetHeight>h)&&e.top>t.offsetHeight?u=e.top-t.offsetHeight:e.bottom+t.offsetHeight<=h&&(u=e.bottom),c+t.offsetWidth>f&&(c=f-t.offsetWidth)}t.style.top=u+"px",t.style.left=t.style.right="","right"==i?(c=a.sizer.clientWidth-t.offsetWidth,t.style.right="0px"):("left"==i?c=0:"middle"==i&&(c=(a.sizer.clientWidth-t.offsetWidth)/2),t.style.left=c+"px"),r&&(o=this,l={left:c,top:u,right:c+t.offsetWidth,bottom:u+t.offsetHeight},null!=(s=Mn(o,l)).scrollTop&&Hn(o,s.scrollTop),null!=s.scrollLeft&&Pn(o,s.scrollLeft))},triggerOnKeyDown:Qn(ll),triggerOnKeyPress:Qn(al),triggerOnKeyUp:sl,triggerOnMouseDown:Qn(fl),execCommand:function(e){if(Zo.hasOwnProperty(e))return Zo[e].call(null,this)},triggerElectric:Qn(function(e){Al(this,e)}),findPosH:function(e,t,r,n){var i=1;t<0&&(i=-1,t=-t);for(var o=st(this.doc,e),l=0;l0&&l(t.charAt(r-1));)--r;for(;n.5)&&ln(this),ge(this,"refresh",this)}),swapDoc:Qn(function(e){var t=this.doc;return t.cm=null,this.state.selectingText&&this.state.selectingText(),Di(this,e),Rr(this),this.display.input.reset(),An(this,e.scrollLeft,e.scrollTop),this.curOp.forceScroll=!0,sr(this,"swapDoc",this,t),t}),phrase:function(e){var t=this.options.phrases;return t&&Object.prototype.hasOwnProperty.call(t,e)?t[e]:e},getInputField:function(){return this.display.input.getField()},getWrapperElement:function(){return this.display.wrapper},getScrollerElement:function(){return this.display.scroller},getGutterElement:function(){return this.display.gutters}},be(e),e.registerHelper=function(t,n,i){r.hasOwnProperty(t)||(r[t]=e[t]={_global:[]}),r[t][n]=i},e.registerGlobalHelper=function(t,n,i,o){e.registerHelper(t,n,o),r[t]._global.push({pred:i,val:o})}}(Sl);var Ul="iter insert remove copy getEditor constructor".split(" ");for(var Vl in Mo.prototype)Mo.prototype.hasOwnProperty(Vl)&&B(Ul,Vl)<0&&(Sl.prototype[Vl]=function(e){return function(){return e.apply(this.doc,arguments)}}(Mo.prototype[Vl]));return be(Mo),Sl.inputStyles={textarea:Gl,contenteditable:El},Sl.defineMode=function(e){Sl.defaults.mode||"null"==e||(Sl.defaults.mode=e),function(e,t){arguments.length>2&&(t.dependencies=Array.prototype.slice.call(arguments,2)),Ee[e]=t}.apply(this,arguments)},Sl.defineMIME=function(e,t){Ie[e]=t},Sl.defineMode("null",function(){return{token:function(e){return e.skipToEnd()}}}),Sl.defineMIME("text/plain","null"),Sl.defineExtension=function(e,t){Sl.prototype[e]=t},Sl.defineDocExtension=function(e,t){Mo.prototype[e]=t},Sl.fromTextArea=function(e,t){if((t=t?I(t):{}).value=e.value,!t.tabindex&&e.tabIndex&&(t.tabindex=e.tabIndex),!t.placeholder&&e.placeholder&&(t.placeholder=e.placeholder),null==t.autofocus){var r=W();t.autofocus=r==e||null!=e.getAttribute("autofocus")&&r==document.body}function n(){e.value=s.getValue()}var i;if(e.form&&(fe(e.form,"submit",n),!t.leaveSubmitMethodAlone)){var o=e.form;i=o.submit;try{var l=o.submit=function(){n(),o.submit=i,o.submit(),o.submit=l}}catch(e){}}t.finishInit=function(r){r.save=n,r.getTextArea=function(){return e},r.toTextArea=function(){r.toTextArea=isNaN,n(),e.parentNode.removeChild(r.getWrapperElement()),e.style.display="",e.form&&(pe(e.form,"submit",n),t.leaveSubmitMethodAlone||"function"!=typeof e.form.submit||(e.form.submit=i))}},e.style.display="none";var s=Sl(function(t){return e.parentNode.insertBefore(t,e.nextSibling)},t);return s},function(e){e.off=pe,e.on=fe,e.wheelEventPixels=vi,e.Doc=Mo,e.splitLines=We,e.countColumn=z,e.findColumn=X,e.isWordChar=ee,e.Pass=U,e.signal=ge,e.Line=Xt,e.changeEnd=Ci,e.scrollbarModel=Gn,e.Pos=et,e.cmpPos=tt,e.modes=Ee,e.mimeModes=Ie,e.resolveMode=ze,e.getMode=Re,e.modeExtensions=Be,e.extendMode=Ge,e.copyState=Ue,e.startState=Ke,e.innerMode=Ve,e.commands=Zo,e.keyMap=Ro,e.keyName=jo,e.isModifierKey=Vo,e.lookupKey=Uo,e.normalizeKeyMap=Go,e.StringStream=je,e.SharedTextMarker=So,e.TextMarker=xo,e.LineWidget=yo,e.e_preventDefault=we,e.e_stopPropagation=xe,e.e_stop=Se,e.addClass=H,e.contains=D,e.rmClass=T,e.keyNames=Po}(Sl),Sl.version="5.49.2",Sl}); \ No newline at end of file diff --git a/luci-app-adguardhome/root/www/luci-static/resources/codemirror/mode/yaml/yaml.js b/luci-app-adguardhome/root/www/luci-static/resources/codemirror/mode/yaml/yaml.js deleted file mode 100755 index 4a5e499bf..000000000 --- a/luci-app-adguardhome/root/www/luci-static/resources/codemirror/mode/yaml/yaml.js +++ /dev/null @@ -1 +0,0 @@ -!function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],e):e(CodeMirror)}(function(e){"use strict";e.defineMode("yaml",function(){var e=new RegExp("\\b(("+["true","false","on","off","yes","no"].join(")|(")+"))$","i");return{token:function(i,t){var r=i.peek(),n=t.escaped;if(t.escaped=!1,"#"==r&&(0==i.pos||/\s/.test(i.string.charAt(i.pos-1))))return i.skipToEnd(),"comment";if(i.match(/^('([^']|\\.)*'?|"([^"]|\\.)*"?)/))return"string";if(t.literal&&i.indentation()>t.keyCol)return i.skipToEnd(),"string";if(t.literal&&(t.literal=!1),i.sol()){if(t.keyCol=0,t.pair=!1,t.pairStart=!1,i.match(/---/))return"def";if(i.match(/\.\.\./))return"def";if(i.match(/\s*-\s+/))return"meta"}if(i.match(/^(\{|\}|\[|\])/))return"{"==r?t.inlinePairs++:"}"==r?t.inlinePairs--:"["==r?t.inlineList++:t.inlineList--,"meta";if(t.inlineList>0&&!n&&","==r)return i.next(),"meta";if(t.inlinePairs>0&&!n&&","==r)return t.keyCol=0,t.pair=!1,t.pairStart=!1,i.next(),"meta";if(t.pairStart){if(i.match(/^\s*(\||\>)\s*/))return t.literal=!0,"meta";if(i.match(/^\s*(\&|\*)[a-z0-9\._-]+\b/i))return"variable-2";if(0==t.inlinePairs&&i.match(/^\s*-?[0-9\.\,]+\s?$/))return"number";if(t.inlinePairs>0&&i.match(/^\s*-?[0-9\.\,]+\s?(?=(,|}))/))return"number";if(i.match(e))return"keyword"}return!t.pair&&i.match(/^\s*(?:[,\[\]{}&*!|>'"%@`][^\s'":]|[^,\[\]{}#&*!|>'"%@`])[^#]*?(?=\s*:($|\s))/)?(t.pair=!0,t.keyCol=i.indentation(),"atom"):t.pair&&i.match(/^:\s*/)?(t.pairStart=!0,"meta"):(t.pairStart=!1,t.escaped="\\"==r,i.next(),null)},startState:function(){return{pair:!1,pairStart:!1,keyCol:0,inlinePairs:0,inlineList:0,literal:!1,escaped:!1}},lineComment:"#",fold:"indent"}}),e.defineMIME("text/x-yaml","yaml"),e.defineMIME("text/yaml","yaml")}); \ No newline at end of file diff --git a/luci-app-adguardhome/root/www/luci-static/resources/codemirror/theme/dracula.css b/luci-app-adguardhome/root/www/luci-static/resources/codemirror/theme/dracula.css deleted file mode 100755 index 6c708c010..000000000 --- a/luci-app-adguardhome/root/www/luci-static/resources/codemirror/theme/dracula.css +++ /dev/null @@ -1 +0,0 @@ -.cm-s-dracula.CodeMirror,.cm-s-dracula .CodeMirror-gutters{background-color:#282a36 !important;color:#f8f8f2 !important;border:0}.cm-s-dracula .CodeMirror-gutters{color:#282a36}.cm-s-dracula .CodeMirror-cursor{border-left:solid thin #f8f8f0}.cm-s-dracula .CodeMirror-linenumber{color:#6d8a88}.cm-s-dracula .CodeMirror-selected{background:rgba(255,255,255,0.10)}.cm-s-dracula .CodeMirror-line::selection,.cm-s-dracula .CodeMirror-line>span::selection,.cm-s-dracula .CodeMirror-line>span>span::selection{background:rgba(255,255,255,0.10)}.cm-s-dracula .CodeMirror-line::-moz-selection,.cm-s-dracula .CodeMirror-line>span::-moz-selection,.cm-s-dracula .CodeMirror-line>span>span::-moz-selection{background:rgba(255,255,255,0.10)}.cm-s-dracula span.cm-comment{color:#6272a4}.cm-s-dracula span.cm-string,.cm-s-dracula span.cm-string-2{color:#f1fa8c}.cm-s-dracula span.cm-number{color:#bd93f9}.cm-s-dracula span.cm-variable{color:#50fa7b}.cm-s-dracula span.cm-variable-2{color:white}.cm-s-dracula span.cm-def{color:#50fa7b}.cm-s-dracula span.cm-operator{color:#ff79c6}.cm-s-dracula span.cm-keyword{color:#ff79c6}.cm-s-dracula span.cm-atom{color:#bd93f9}.cm-s-dracula span.cm-meta{color:#f8f8f2}.cm-s-dracula span.cm-tag{color:#ff79c6}.cm-s-dracula span.cm-attribute{color:#50fa7b}.cm-s-dracula span.cm-qualifier{color:#50fa7b}.cm-s-dracula span.cm-property{color:#66d9ef}.cm-s-dracula span.cm-builtin{color:#50fa7b}.cm-s-dracula span.cm-variable-3,.cm-s-dracula span.cm-type{color:#ffb86c}.cm-s-dracula .CodeMirror-activeline-background{background:rgba(255,255,255,0.1)}.cm-s-dracula .CodeMirror-matchingbracket{text-decoration:underline;color:white !important} diff --git a/luci-app-adguardhome/root/www/luci-static/resources/twin-bcrypt.min.js b/luci-app-adguardhome/root/www/luci-static/resources/twin-bcrypt.min.js deleted file mode 100755 index 6284357c6..000000000 --- a/luci-app-adguardhome/root/www/luci-static/resources/twin-bcrypt.min.js +++ /dev/null @@ -1,7 +0,0 @@ -/* @license - * Twin-Bcrypt 2.2.0 - * https://github.com/fpirsch/twin-bcrypt - * Licence: BSD-3-Clause - */ -!function(r,n){"use strict";function e(r){return y[g]=t.apply(n,r),g++}function t(r){var e=[].slice.call(arguments,1);return function(){"function"==typeof r?r.apply(n,e):new Function(""+r)()}}function o(r){if(m)setTimeout(t(o,r),0);else{var n=y[r];if(n){m=!0;try{n()}finally{a(r),m=!1}}}}function a(r){delete y[r]}function i(){p=function(){var r=e(arguments);return process.nextTick(t(o,r)),r}}function u(){if(r.postMessage&&!r.importScripts){var n=!0,e=r.onmessage;return r.onmessage=function(){n=!1},r.postMessage("","*"),r.onmessage=e,n}}function f(){var n="setImmediate$"+Math.random()+"$",t=function(e){e.source===r&&"string"==typeof e.data&&0===e.data.indexOf(n)&&o(+e.data.slice(n.length))};r.addEventListener?r.addEventListener("message",t,!1):r.attachEvent("onmessage",t),p=function(){var t=e(arguments);return r.postMessage(n+t,"*"),t}}function c(){var r=new MessageChannel;r.port1.onmessage=function(r){var n=r.data;o(n)},p=function(){var n=e(arguments);return r.port2.postMessage(n),n}}function s(){var r=v.documentElement;p=function(){var n=e(arguments),t=v.createElement("script");return t.onreadystatechange=function(){o(n),t.onreadystatechange=null,r.removeChild(t),t=null},r.appendChild(t),n}}function l(){p=function(){var r=e(arguments);return setTimeout(t(o,r),0),r}}if(!r.setImmediate){var p,g=1,y={},m=!1,v=r.document,d=Object.getPrototypeOf&&Object.getPrototypeOf(r);d=d&&d.setTimeout?d:r,"[object process]"==={}.toString.call(r.process)?i():u()?f():r.MessageChannel?c():v&&"onreadystatechange"in v.createElement("script")?s():l(),d.setImmediate=p,d.clearImmediate=a}}(new Function("return this")()),function(r){"object"==typeof exports?r(exports,require("crypto")):r(self.TwinBcrypt={},self.crypto||self.msCrypto)}(function(r,n){"use strict";function e(r){for(var n=unescape(encodeURIComponent(r)),e=n.length,t=new Array(e),o=0;e>o;o++)t[o]=n.charCodeAt(o);return t}function t(r){for(var n=r.length,e=new Array(n),t=0;n>t;t++)e[t]=r.charCodeAt(t);return e}function o(r,n){for(var e,t,o=0,a="";n>o;){if(e=255&r[o++],a+=B[e>>2],e=(3&e)<<4,o>=n){a+=B[e];break}if(t=255&r[o++],e|=t>>4,a+=B[e],e=(15&t)<<2,o>=n){a+=B[e];break}t=255&r[o++],e|=t>>6,a+=B[e],a+=B[63&t]}return a}function a(r){for(var n,e,t=new Array(16),o=0,a=0;;){if(n=D[r.charCodeAt(o++)-46],e=D[r.charCodeAt(o++)-46],t[a++]=255&(n<<2|e>>4),22===o)break;n=e<<4,e=D[r.charCodeAt(o++)-46],t[a++]=255&(n|e>>2),n=e<<6,e=D[r.charCodeAt(o++)-46],t[a++]=255&(n|e)}return t}function i(r){for(var n=r.length,e=new Array(72),t=0,o=0;72>o;)e[o++]=r[t++],t===n&&(t=0);return e}function u(r,n,e){for(var t=0,o=e>>2;tt;)r[n++]=e[t++]<<24|e[t++]<<16|e[t++]<<8|e[t++]}function c(r){function n(n){for(var e=r,t=G>>2,o=t|O,f=n>>2,c=e[f]^e[t],s=e[1|f];o>t;)s^=(e[c>>>24]+e[a|c>>>16&255]^e[i|c>>>8&255])+e[u|255&c]^e[++t],c^=(e[s>>>24]+e[a|s>>>16&255]^e[i|s>>>8&255])+e[u|255&s]^e[++t];e[f]=s^e[S>>2],e[1|f]=c}function e(n){var e;for(r[L>>2]=0,r[L+4>>2]=0,e=0;M>e;e++)r[G>>2|e]^=r[(n>>2)+e];var t,o,f,c,s,l=r;for(e=0;M>e;e+=2){for(t=G>>2,o=t|O,f=L>>2,c=l[f]^l[t],s=l[1|f];o>t;)s^=(l[c>>>24]+l[a|c>>>16&255]^l[i|c>>>8&255])+l[u|255&c]^l[++t],c^=(l[s>>>24]+l[a|s>>>16&255]^l[i|s>>>8&255])+l[u|255&s]^l[++t];l[f]=s^l[S>>2],l[1|f]=c,r[G>>2|e]=l[f],r[G>>2|e+1]=c}for(e=0;T>e;e+=2){for(t=G>>2,o=t|O,f=L>>2,c=l[f]^l[t],s=l[1|f];o>t;)s^=(l[c>>>24]+l[a|c>>>16&255]^l[i|c>>>8&255])+l[u|255&c]^l[++t],c^=(l[s>>>24]+l[a|s>>>16&255]^l[i|s>>>8&255])+l[u|255&s]^l[++t];l[f]=s^l[S>>2],l[1|f]=c,r[e]=l[f],r[1|e]=c}}function t(r,n,t){for(var o=0;t>=o&&!(r>n);o++)e(R),e(j),r++;return r}var o=k>>2,a=o+256|0,i=a+256|0,u=i+256|0;return{encrypt:n,expandLoop:t}}function s(stdlib, foreign, heap) {"use asm";var HEAP32=new stdlib.Uint32Array(heap);var BLOWFISH_NUM_ROUNDS=16;var S_offset=0x0000;var S1_offset=0x0400;var S2_offset=0x0800;var S3_offset=0x0C00;var P_offset=0x1000;var P_last_offset=0x1044;var crypt_ciphertext_offset=0x1048;var LR_offset=0x01060;var password_offset=0x1068;var salt_offset=0x10b0;var P_LEN=18;var S_LEN=1024;function encrypt(offset) {offset=offset|0;var i=0;var n=0;var L=0;var R=0;var imax=0;imax=P_offset|BLOWFISH_NUM_ROUNDS<<2;L=HEAP32[offset>>2]|0;R=HEAP32[offset+4>>2]|0;L=L^HEAP32[P_offset>>2];for (i=P_offset; (i|0)<(imax|0);) {i=(i+4)>>>0;R=R^(((HEAP32[(L>>>22)>>2]>>>0) +(HEAP32[(S1_offset|(L>>>14&0x3ff))>>2]>>>0) ^(HEAP32[(S2_offset|(L>>>6&0x3ff))>>2])) +(HEAP32[(S3_offset|(L<<2&0x3ff))>>2]>>>0))^HEAP32[i>>2];i=(i+4)>>>0;L=L^(((HEAP32[(R>>>22)>>2]>>>0) +(HEAP32[(S1_offset|(R>>>14&0x3ff))>>2]>>>0) ^(HEAP32[(S2_offset|(R>>>6&0x3ff))>>2])) +(HEAP32[(S3_offset|(R<<2&0x3ff))>>2]>>>0))^HEAP32[i>>2];}HEAP32[offset>>2]=R^HEAP32[P_last_offset>>2];HEAP32[(offset+4)>>2]=L;}function expandKey(offset) {offset=offset|0;var i=0;var off=0;off=P_offset|0;for (i=0; (i|0)<(P_LEN|0); i=(i+1)|0) {HEAP32[off>>2]=HEAP32[off>>2]^HEAP32[offset>>2];offset=(offset+4)|0;off=(off+4)|0;}HEAP32[LR_offset>>2]=0;HEAP32[LR_offset+4>>2]=0;off=P_offset;for (i=0; (i|0)<(P_LEN|0); i=(i+2)|0) {encrypt(LR_offset);HEAP32[off>>2]=HEAP32[LR_offset>>2];HEAP32[off+4>>2]=HEAP32[LR_offset+4>>2];off=(off+8)|0;}off=S_offset;for (i=0; (i|0)<(S_LEN|0); i=(i+2)|0) {encrypt(LR_offset);HEAP32[off>>2]=HEAP32[LR_offset>>2];HEAP32[off+4>>2]=HEAP32[LR_offset+4>>2];off=(off+8)|0;}}function expandLoop(i, counterEnd, maxIterations) {i=i|0;counterEnd=counterEnd|0;maxIterations=maxIterations|0;var j=0;for (j=0; (j|0) <= (maxIterations|0); j=(j+1)|0) {if ((i>>>0)>(counterEnd>>>0)) break;expandKey(password_offset);expandKey(salt_offset);i=(i+1)>>>0;}return i|0;}return {encrypt: encrypt,expandLoop: expandLoop};} -function l(r,n,e,t){var o,a,i,u=L>>2,f=u+1;for(t[u]=0,t[f]=0,a=0,o=0;M>o;o++)i=n[a++]<<24|n[a++]<<16|n[a++]<<8|n[a++],t[G>>2|o]^=i;for(a=0,o=0;M>o;o+=2)i=r[a++]<<24|r[a++]<<16|r[a++]<<8|r[a++],a&=65295,t[u]^=i,i=r[a++]<<24|r[a++]<<16|r[a++]<<8|r[a++],a&=65295,t[f]^=i,e.encrypt(L),t[G>>2|o]=t[u],t[G>>2|o+1]=t[f];var c=k>>2;for(o=0;T>o;o+=2)i=r[a++]<<24|r[a++]<<16|r[a++]<<8|r[a++],a&=65295,t[u]^=i,i=r[a++]<<24|r[a++]<<16|r[a++]<<8|r[a++],a&=65295,t[f]^=i,e.encrypt(L),t[c|o]=t[u],t[c|o+1]=t[f]}function p(r,n,e,t,o,a,i){for(var u=e;t>=u;){if(u=r.expandLoop(u,t,o),a){var f=a(u/(t+1));if(f===!1)return}if(u>t){if(i)return void setImmediate(g.bind(null,r,n,i));return}if(i)return void setImmediate(p.bind(null,r,n,u,t,o,a,i))}}function g(r,n,e){u(n,x,F);var t;for(t=0;64>t;t++)r.encrypt(F+0),r.encrypt(F+8),r.encrypt(F+16);var o,a=0,i=x.length,f=new Array(4*i);for(t=0;i>t;t++)o=n[(F>>2)+t],f[a++]=o>>24,f[a++]=o>>16&255,f[a++]=o>>8&255,f[a++]=255&o;return e&&e(f),f}function y(r,n){return r+o(n,23)}function m(n,o,m,v){var d,h=o.substr(0,29),w=+o.substr(4,2),A=o.substr(7,22);if("string"==typeof n)d=r.encodingMode===r.ENCODING_UTF8?e(n):t(n);else if(Array.isArray(n))d=n.map(function(r){return 255&r});else{if(!(n instanceof Uint8Array))throw new Error("Incorrect arguments");d=Array.prototype.slice.call(n)}d.push(0);var b,E,N=a(A,C),O=31>w?1<>2,N),f(b,R>>2,d),l(N,d,E,b),v?void p(E,b,0,M,T,m,function(r){v(y(h,r))}):(p(E,b,0,M,T,m),y(h,g(E,b)))}function v(r){if(!b)throw new Error("No cryptographically secure pseudorandom number generator available.");if(null==r&&(r=N),r=0|+r,isNaN(r)||4>r||r>31)throw new Error("Invalid cost parameter.");var n="$2y$";return 10>r&&(n+="0"),n+=r+"$",n+=o(b(C),C)}function d(r,n,e){if(n&&"number"!=typeof n){if("string"!=typeof n||!z.test(n))throw new Error("Invalid salt")}else n=v(n);return m(r,n,e)}function h(r,n,e,t){if(arguments.length<2)throw new Error("Incorrect arguments");if(2===arguments.length?(t=n,n=e=null):3===arguments.length&&(t=e,e=null,"function"==typeof n&&(e=n,n=null)),n&&"number"!=typeof n){if("string"!=typeof n||!z.test(n))throw new Error("Invalid salt")}else n=v(n);if(!t||"function"!=typeof t)throw new Error("No callback function was given.");m(r,n,e,t)}function w(r,n){if("string"!=typeof n||!Z.test(n))throw new Error("Incorrect arguments");var e=n.substr(0,n.length-31),t=d(r,e);return t===n}function A(r,n,e,t){if("string"!=typeof n||!Z.test(n))throw new Error("Incorrect arguments");if(t||(t=e,e=null),!t||"function"!=typeof t)throw new Error("No callback function was given.");var o=n.substr(0,n.length-31);h(r,o,e,function(r){t(r===n)})}var b,E="undefined"!=typeof InstallTrigger,I=E;n&&(b=n.randomBytes,n.getRandomValues&&(b=function(r){var e=new Uint8Array(r);return n.getRandomValues(e)}));var C=16,N=10,O=16,$=[608135816,2242054355,320440878,57701188,2752067618,698298832,137296536,3964562569,1160258022,953160567,3193202383,887688300,3232508343,3380367581,1065670069,3041331479,2450970073,2306472731],U=[3509652390,2564797868,805139163,3491422135,3101798381,1780907670,3128725573,4046225305,614570311,3012652279,134345442,2240740374,1667834072,1901547113,2757295779,4103290238,227898511,1921955416,1904987480,2182433518,2069144605,3260701109,2620446009,720527379,3318853667,677414384,3393288472,3101374703,2390351024,1614419982,1822297739,2954791486,3608508353,3174124327,2024746970,1432378464,3864339955,2857741204,1464375394,1676153920,1439316330,715854006,3033291828,289532110,2706671279,2087905683,3018724369,1668267050,732546397,1947742710,3462151702,2609353502,2950085171,1814351708,2050118529,680887927,999245976,1800124847,3300911131,1713906067,1641548236,4213287313,1216130144,1575780402,4018429277,3917837745,3693486850,3949271944,596196993,3549867205,258830323,2213823033,772490370,2760122372,1774776394,2652871518,566650946,4142492826,1728879713,2882767088,1783734482,3629395816,2517608232,2874225571,1861159788,326777828,3124490320,2130389656,2716951837,967770486,1724537150,2185432712,2364442137,1164943284,2105845187,998989502,3765401048,2244026483,1075463327,1455516326,1322494562,910128902,469688178,1117454909,936433444,3490320968,3675253459,1240580251,122909385,2157517691,634681816,4142456567,3825094682,3061402683,2540495037,79693498,3249098678,1084186820,1583128258,426386531,1761308591,1047286709,322548459,995290223,1845252383,2603652396,3431023940,2942221577,3202600964,3727903485,1712269319,422464435,3234572375,1170764815,3523960633,3117677531,1434042557,442511882,3600875718,1076654713,1738483198,4213154764,2393238008,3677496056,1014306527,4251020053,793779912,2902807211,842905082,4246964064,1395751752,1040244610,2656851899,3396308128,445077038,3742853595,3577915638,679411651,2892444358,2354009459,1767581616,3150600392,3791627101,3102740896,284835224,4246832056,1258075500,768725851,2589189241,3069724005,3532540348,1274779536,3789419226,2764799539,1660621633,3471099624,4011903706,913787905,3497959166,737222580,2514213453,2928710040,3937242737,1804850592,3499020752,2949064160,2386320175,2390070455,2415321851,4061277028,2290661394,2416832540,1336762016,1754252060,3520065937,3014181293,791618072,3188594551,3933548030,2332172193,3852520463,3043980520,413987798,3465142937,3030929376,4245938359,2093235073,3534596313,375366246,2157278981,2479649556,555357303,3870105701,2008414854,3344188149,4221384143,3956125452,2067696032,3594591187,2921233993,2428461,544322398,577241275,1471733935,610547355,4027169054,1432588573,1507829418,2025931657,3646575487,545086370,48609733,2200306550,1653985193,298326376,1316178497,3007786442,2064951626,458293330,2589141269,3591329599,3164325604,727753846,2179363840,146436021,1461446943,4069977195,705550613,3059967265,3887724982,4281599278,3313849956,1404054877,2845806497,146425753,1854211946,1266315497,3048417604,3681880366,3289982499,290971e4,1235738493,2632868024,2414719590,3970600049,1771706367,1449415276,3266420449,422970021,1963543593,2690192192,3826793022,1062508698,1531092325,1804592342,2583117782,2714934279,4024971509,1294809318,4028980673,1289560198,2221992742,1669523910,35572830,157838143,1052438473,1016535060,1802137761,1753167236,1386275462,3080475397,2857371447,1040679964,2145300060,2390574316,1461121720,2956646967,4031777805,4028374788,33600511,2920084762,1018524850,629373528,3691585981,3515945977,2091462646,2486323059,586499841,988145025,935516892,3367335476,2599673255,2839830854,265290510,3972581182,2759138881,3795373465,1005194799,847297441,406762289,1314163512,1332590856,1866599683,4127851711,750260880,613907577,1450815602,3165620655,3734664991,3650291728,3012275730,3704569646,1427272223,778793252,1343938022,2676280711,2052605720,1946737175,3164576444,3914038668,3967478842,3682934266,1661551462,3294938066,4011595847,840292616,3712170807,616741398,312560963,711312465,1351876610,322626781,1910503582,271666773,2175563734,1594956187,70604529,3617834859,1007753275,1495573769,4069517037,2549218298,2663038764,504708206,2263041392,3941167025,2249088522,1514023603,1998579484,1312622330,694541497,2582060303,2151582166,1382467621,776784248,2618340202,3323268794,2497899128,2784771155,503983604,4076293799,907881277,423175695,432175456,1378068232,4145222326,3954048622,3938656102,3820766613,2793130115,2977904593,26017576,3274890735,3194772133,1700274565,1756076034,4006520079,3677328699,720338349,1533947780,354530856,688349552,3973924725,1637815568,332179504,3949051286,53804574,2852348879,3044236432,1282449977,3583942155,3416972820,4006381244,1617046695,2628476075,3002303598,1686838959,431878346,2686675385,1700445008,1080580658,1009431731,832498133,3223435511,2605976345,2271191193,2516031870,1648197032,4164389018,2548247927,300782431,375919233,238389289,3353747414,2531188641,2019080857,1475708069,455242339,2609103871,448939670,3451063019,1395535956,2413381860,1841049896,1491858159,885456874,4264095073,4001119347,1565136089,3898914787,1108368660,540939232,1173283510,2745871338,3681308437,4207628240,3343053890,4016749493,1699691293,1103962373,3625875870,2256883143,3830138730,1031889488,3479347698,1535977030,4236805024,3251091107,2132092099,1774941330,1199868427,1452454533,157007616,2904115357,342012276,595725824,1480756522,206960106,497939518,591360097,863170706,2375253569,3596610801,1814182875,2094937945,3421402208,1082520231,3463918190,2785509508,435703966,3908032597,1641649973,2842273706,3305899714,1510255612,2148256476,2655287854,3276092548,4258621189,236887753,3681803219,274041037,1734335097,3815195456,3317970021,1899903192,1026095262,4050517792,356393447,2410691914,3873677099,3682840055,3913112168,2491498743,4132185628,2489919796,1091903735,1979897079,3170134830,3567386728,3557303409,857797738,1136121015,1342202287,507115054,2535736646,337727348,3213592640,1301675037,2528481711,1895095763,1721773893,3216771564,62756741,2142006736,835421444,2531993523,1442658625,3659876326,2882144922,676362277,1392781812,170690266,3921047035,1759253602,3611846912,1745797284,664899054,1329594018,3901205900,3045908486,2062866102,2865634940,3543621612,3464012697,1080764994,553557557,3656615353,3996768171,991055499,499776247,1265440854,648242737,3940784050,980351604,3713745714,1749149687,3396870395,4211799374,3640570775,1161844396,3125318951,1431517754,545492359,4268468663,3499529547,1437099964,2702547544,3433638243,2581715763,2787789398,1060185593,1593081372,2418618748,4260947970,69676912,2159744348,86519011,2512459080,3838209314,1220612927,3339683548,133810670,1090789135,1078426020,1569222167,845107691,3583754449,4072456591,1091646820,628848692,1613405280,3757631651,526609435,236106946,48312990,2942717905,3402727701,1797494240,859738849,992217954,4005476642,2243076622,3870952857,3732016268,765654824,3490871365,2511836413,1685915746,3888969200,1414112111,2273134842,3281911079,4080962846,172450625,2569994100,980381355,4109958455,2819808352,2716589560,2568741196,3681446669,3329971472,1835478071,660984891,3704678404,4045999559,3422617507,3040415634,1762651403,1719377915,3470491036,2693910283,3642056355,3138596744,1364962596,2073328063,1983633131,926494387,3423689081,2150032023,4096667949,1749200295,3328846651,309677260,2016342300,1779581495,3079819751,111262694,1274766160,443224088,298511866,1025883608,3806446537,1145181785,168956806,3641502830,3584813610,1689216846,3666258015,3200248200,1692713982,2646376535,4042768518,1618508792,1610833997,3523052358,4130873264,2001055236,3610705100,2202168115,4028541809,2961195399,1006657119,2006996926,3186142756,1430667929,3210227297,1314452623,4074634658,4101304120,2273951170,1399257539,3367210612,3027628629,1190975929,2062231137,2333990788,2221543033,2438960610,1181637006,548689776,2362791313,3372408396,3104550113,3145860560,296247880,1970579870,3078560182,3769228297,1714227617,3291629107,3898220290,166772364,1251581989,493813264,448347421,195405023,2709975567,677966185,3703036547,1463355134,2715995803,1338867538,1343315457,2802222074,2684532164,233230375,2599980071,2000651841,3277868038,1638401717,4028070440,3237316320,6314154,819756386,300326615,590932579,1405279636,3267499572,3150704214,2428286686,3959192993,3461946742,1862657033,1266418056,963775037,2089974820,2263052895,1917689273,448879540,3550394620,3981727096,150775221,3627908307,1303187396,508620638,2975983352,2726630617,1817252668,1876281319,1457606340,908771278,3720792119,3617206836,2455994898,1729034894,1080033504,976866871,3556439503,2881648439,1522871579,1555064734,1336096578,3548522304,2579274686,3574697629,3205460757,3593280638,3338716283,3079412587,564236357,2993598910,1781952180,1464380207,3163844217,3332601554,1699332808,1393555694,1183702653,3581086237,1288719814,691649499,2847557200,2895455976,3193889540,2717570544,1781354906,1676643554,2592534050,3230253752,1126444790,2770207658,2633158820,2210423226,2615765581,2414155088,3127139286,673620729,2805611233,1269405062,4015350505,3341807571,4149409754,1057255273,2012875353,2162469141,2276492801,2601117357,993977747,3918593370,2654263191,753973209,36408145,2530585658,25011837,3520020182,2088578344,530523599,2918365339,1524020338,1518925132,3760827505,3759777254,1202760957,3985898139,3906192525,674977740,4174734889,2031300136,2019492241,3983892565,4153806404,3822280332,352677332,2297720250,60907813,90501309,3286998549,1016092578,2535922412,2839152426,457141659,509813237,4120667899,652014361,1966332200,2975202805,55981186,2327461051,676427537,3255491064,2882294119,3433927263,1307055953,942726286,933058658,2468411793,3933900994,4215176142,1361170020,2001714738,2830558078,3274259782,1222529897,1679025792,2729314320,3714953764,1770335741,151462246,3013232138,1682292957,1483529935,471910574,1539241949,458788160,3436315007,1807016891,3718408830,978976581,1043663428,3165965781,1927990952,4200891579,2372276910,3208408903,3533431907,1412390302,2931980059,4132332400,1947078029,3881505623,4168226417,2941484381,1077988104,1320477388,886195818,18198404,3786409e3,2509781533,112762804,3463356488,1866414978,891333506,18488651,661792760,1628790961,3885187036,3141171499,876946877,2693282273,1372485963,791857591,2686433993,3759982718,3167212022,3472953795,2716379847,445679433,3561995674,3504004811,3574258232,54117162,3331405415,2381918588,3769707343,4154350007,1140177722,4074052095,668550556,3214352940,367459370,261225585,2610173221,4209349473,3468074219,3265815641,314222801,3066103646,3808782860,282218597,3406013506,3773591054,379116347,1285071038,846784868,2669647154,3771962079,3550491691,2305946142,453669953,1268987020,3317592352,3279303384,3744833421,2610507566,3859509063,266596637,3847019092,517658769,3462560207,3443424879,370717030,4247526661,2224018117,4143653529,4112773975,2788324899,2477274417,1456262402,2901442914,1517677493,1846949527,2295493580,3734397586,2176403920,1280348187,1908823572,3871786941,846861322,1172426758,3287448474,3383383037,1655181056,3139813346,901632758,1897031941,2986607138,3066810236,3447102507,1393639104,373351379,950779232,625454576,3124240540,4148612726,2007998917,544563296,2244738638,2330496472,2058025392,1291430526,424198748,50039436,29584100,3605783033,2429876329,2791104160,1057563949,3255363231,3075367218,3463963227,1469046755,985887462],M=$.length,T=U.length,x=[1332899944,1700884034,1701343084,1684370003,1668446532,1869963892],k=0,G=4096,S=4164,F=4168,L=4192,R=4200,j=4272,B="./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",D=[0,1,54,55,56,57,58,59,60,61,62,63,-1,-1,-1,-1,-1,-1,-1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,-1,-1,-1,-1,-1,-1,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,-1,-1,-1,-1,-1],z=/^\$2[ay]\$(0[4-9]|[12][0-9]|3[01])\$[.\/A-Za-z0-9]{21}[.Oeu]/,Z=/^\$2[ay]\$(0[4-9]|[12][0-9]|3[01])\$[.\/A-Za-z0-9]{21}[.Oeu][.\/A-Za-z0-9]{30}[.CGKOSWaeimquy26]$/;r.genSalt=v,r.hashSync=d,r.hash=h,r.compareSync=w,r.compare=A,r.ENCODING_UTF8=0,r.ENCODING_RAW=1,r.encodingMode=r.ENCODING_UTF8,r.cryptoRNG=!!b,r.randomBytes=b,r.defaultCost=N,r.version="2.2.0"}); \ No newline at end of file diff --git a/luci-app-diskman/Makefile b/luci-app-diskman/Makefile deleted file mode 100755 index fa6c46357..000000000 --- a/luci-app-diskman/Makefile +++ /dev/null @@ -1,51 +0,0 @@ -include $(TOPDIR)/rules.mk - -PKG_NAME:=luci-app-diskman - -PKG_MAINTAINER:=lisaac -PKG_LICENSE:=AGPL-3.0 - -LUCI_TITLE:=Disk Manager interface for LuCI -LUCI_DEPENDS:=+blkid +e2fsprogs +parted +smartmontools \ - +PACKAGE_$(PKG_NAME)_INCLUDE_btrfs_progs:btrfs-progs \ - +PACKAGE_$(PKG_NAME)_INCLUDE_lsblk:lsblk \ - +PACKAGE_$(PKG_NAME)_INCLUDE_mdadm:mdadm \ - +PACKAGE_$(PKG_NAME)_INCLUDE_kmod_md_raid456:mdadm \ - +PACKAGE_$(PKG_NAME)_INCLUDE_kmod_md_raid456:kmod-md-raid456 \ - +PACKAGE_$(PKG_NAME)_INCLUDE_kmod_md_linears:mdadm \ - +PACKAGE_$(PKG_NAME)_INCLUDE_kmod_md_linears:kmod-md-linear - -include $(INCLUDE_DIR)/package.mk - -define Package/$(PKG_NAME)/config -config PACKAGE_$(PKG_NAME)_INCLUDE_btrfs_progs - bool "Include btrfs-progs" - default n - -config PACKAGE_$(PKG_NAME)_INCLUDE_lsblk - bool "Include lsblk" - default n - -config PACKAGE_$(PKG_NAME)_INCLUDE_mdadm - bool "Include mdadm" - default n - -config PACKAGE_$(PKG_NAME)_INCLUDE_kmod_md_raid456 - depends on PACKAGE_$(PKG_NAME)_INCLUDE_mdadm - bool "Include kmod-md-raid456" - default n - -config PACKAGE_$(PKG_NAME)_INCLUDE_kmod_md_linear - depends on PACKAGE_$(PKG_NAME)_INCLUDE_mdadm - bool "Include kmod-md-linear" - default n -endef - -define Package/$(PKG_NAME)/postinst -#!/bin/sh -rm -fr /tmp/luci-indexcache /tmp/luci-modulecache -endef - -include $(TOPDIR)/feeds/luci/luci.mk - -# call BuildPackage - OpenWrt buildroot signature diff --git a/luci-app-diskman/luasrc/controller/diskman.lua b/luci-app-diskman/luasrc/controller/diskman.lua deleted file mode 100755 index 258120430..000000000 --- a/luci-app-diskman/luasrc/controller/diskman.lua +++ /dev/null @@ -1,155 +0,0 @@ ---[[ -LuCI - Lua Configuration Interface -Copyright 2019 lisaac -]]-- - -require "luci.util" -module("luci.controller.diskman",package.seeall) - -function index() - -- check all used executables in disk management are existed - local CMD = {"parted", "blkid", "smartctl"} - local executables_all_existed = true - for _, cmd in ipairs(CMD) do - local command = luci.sys.exec("/usr/bin/which " .. cmd) - if not command:match(cmd) then - executables_all_existed = false - break - end - end - - if not executables_all_existed then return end - -- entry(path, target, title, order) - -- set leaf attr to true to pass argument throughe url (e.g. admin/system/disk/partition/sda) - entry({"admin", "system", "diskman"}, alias("admin", "system", "diskman", "disks"), _("Disk Man"), 55) - entry({"admin", "system", "diskman", "disks"}, form("diskman/disks"), nil).leaf = true - entry({"admin", "system", "diskman", "partition"}, form("diskman/partition"), nil).leaf = true - entry({"admin", "system", "diskman", "btrfs"}, form("diskman/btrfs"), nil).leaf = true - entry({"admin", "system", "diskman", "format_partition"}, call("format_partition"), nil).leaf = true - entry({"admin", "system", "diskman", "get_disk_info"}, call("get_disk_info"), nil).leaf = true - entry({"admin", "system", "diskman", "mk_p_table"}, call("mk_p_table"), nil).leaf = true - entry({"admin", "system", "diskman", "smartdetail"}, call("smart_detail"), nil).leaf = true - entry({"admin", "system", "diskman", "smartattr"}, call("smart_attr"), nil).leaf = true -end - -function format_partition() - local partation_name = luci.http.formvalue("partation_name") - local fs = luci.http.formvalue("file_system") - if not partation_name then - luci.http.status(500, "Partition NOT found!") - luci.http.write_json("Partition NOT found!") - return - elseif not nixio.fs.access("/dev/"..partation_name) then - luci.http.status(500, "Partition NOT found!") - luci.http.write_json("Partition NOT found!") - return - elseif not fs then - luci.http.status(500, "no file system") - luci.http.write_json("no file system") - return - end - local dm = require "luci.model.diskman" - code, msg = dm.format_partition(partation_name, fs) - luci.http.status(code, msg) - luci.http.write_json(msg) -end - -function get_disk_info(dev) - if not dev then - luci.http.status(500, "no device") - luci.http.write_json("no device") - return - elseif not nixio.fs.access("/dev/"..dev) then - luci.http.status(500, "no device") - luci.http.write_json("no device") - return - end - local dm = require "luci.model.diskman" - local device_info = dm.get_disk_info(dev) - luci.http.status(200, "ok") - luci.http.prepare_content("application/json") - luci.http.write_json(device_info) -end - -function mk_p_table() - local p_table = luci.http.formvalue("p_table") - local dev = luci.http.formvalue("dev") - if not dev then - luci.http.status(500, "no device") - luci.http.write_json("no device") - return - elseif not nixio.fs.access("/dev/"..dev) then - luci.http.status(500, "no device") - luci.http.write_json("no device") - return - end - local dm = require "luci.model.diskman" - if p_table == "GPT" or p_table == "MBR" then - p_table = p_table == "MBR" and "msdos" or "gpt" - local res = luci.sys.call(dm.command.parted .. " -s /dev/" .. dev .. " mktable ".. p_table) - if res == 0 then - luci.http.status(200, "ok") - else - luci.http.status(500, "command exec error") - end - luci.http.prepare_content("application/json") - luci.http.write_json({code=res}) - else - luci.http.status(404, "not support") - luci.http.prepare_content("application/json") - luci.http.write_json({code="1"}) - end -end - -function smart_detail(dev) - luci.template.render("diskman/smart_detail", {dev=dev}) -end - -function smart_attr(dev) - local dm = require "luci.model.diskman" - local cmd = io.popen(dm.command.smartctl .. " -H -A -i /dev/%s" % dev) - if cmd then - local attr = { } - if cmd:match("NVMe Version:")then - while true do - local ln = cmd:read("*l") - if not ln then - break - elseif ln:match("^(.-):%s+(.+)") then - local key, value = ln:match("^(.-):%s+(.+)") - attr[#attr+1]= { - key = key, - value = value - } - end - end - else - while true do - local ln = cmd:read("*l") - if not ln then - break - elseif ln:match("^.*%d+%s+.+%s+.+%s+.+%s+.+%s+.+%s+.+%s+.+%s+.+%s+.+") then - local id,attrbute,flag,value,worst,thresh,type,updated,raw = ln:match("^%s*(%d+)%s+([%a%p]+)%s+(%w+)%s+(%d+)%s+(%d+)%s+(%d+)%s+([%a%p]+)%s+(%a+)%s+[%w%p]+%s+(.+)") - id= "%x" % id - if not id:match("^%w%w") then - id = "0%s" % id - end - attr[#attr+1]= { - id = id:upper(), - attrbute = attrbute, - flag = flag, - value = value, - worst = worst, - thresh = thresh, - type = type, - updated = updated, - raw = raw - } - end - end - end - cmd:close() - luci.http.prepare_content("application/json") - luci.http.write_json(attr) - end -end diff --git a/luci-app-diskman/luasrc/model/cbi/diskman/btrfs.lua b/luci-app-diskman/luasrc/model/cbi/diskman/btrfs.lua deleted file mode 100755 index 006007853..000000000 --- a/luci-app-diskman/luasrc/model/cbi/diskman/btrfs.lua +++ /dev/null @@ -1,210 +0,0 @@ ---[[ -LuCI - Lua Configuration Interface -Copyright 2019 lisaac -]]-- - -require "luci.util" -require("luci.tools.webadmin") -local dm = require "luci.model.diskman" -local uuid = arg[1] - -if not uuid then luci.http.redirect(luci.dispatcher.build_url("admin/system/diskman")) end - --- mount subv=/ to tempfs -mount_point = "/tmp/.btrfs_tmp" -nixio.fs.mkdirr(mount_point) -luci.util.exec(dm.command.umount .. " "..mount_point .. " >/dev/null 2>&1") -luci.util.exec(dm.command.mount .. " -t btrfs -o subvol=/ UUID="..uuid.." "..mount_point) - -m = SimpleForm("btrfs", translate("Btrfs"), translate("Manage Btrfs")) -m.template = "diskman/cbi/xsimpleform" -m.redirect = luci.dispatcher.build_url("admin/system/diskman") -m.submit = false -m.reset = false - --- info -local btrfs_info = dm.get_btrfs_info(mount_point) -local table_btrfs_info = m:section(Table, {btrfs_info}, translate("Btrfs Info")) -table_btrfs_info:option(DummyValue, "uuid", translate("UUID")) -table_btrfs_info:option(DummyValue, "members", translate("Members")) -table_btrfs_info:option(DummyValue, "data_raid_level", translate("Data")) -table_btrfs_info:option(DummyValue, "metadata_raid_lavel", translate("Metadata")) -table_btrfs_info:option(DummyValue, "size_formated", translate("Size")) -table_btrfs_info:option(DummyValue, "used_formated", translate("Used")) -table_btrfs_info:option(DummyValue, "free_formated", translate("Free Space")) -table_btrfs_info:option(DummyValue, "usage", translate("Usage")) -local v_btrfs_label = table_btrfs_info:option(Value, "label", translate("Label")) -local value_btrfs_label = "" -v_btrfs_label.write = function(self, section, value) - value_btrfs_label = value or "" -end -local btn_update_label = table_btrfs_info:option(Button, "_update_label") -btn_update_label.inputtitle = translate("Update") -btn_update_label.inputstyle = "edit" -btn_update_label.write = function(self, section, value) - local cmd = dm.command.btrfs .. " filesystem label " .. mount_point .. " " .. value_btrfs_label - local res = luci.util.exec(cmd) - luci.http.redirect(luci.dispatcher.build_url("admin/system/diskman/btrfs/" .. uuid)) -end --- subvolume -local subvolume_list = dm.get_btrfs_subv(mount_point) -subvolume_list["_"] = { ID = 0 } -table_subvolume = m:section(Table, subvolume_list, translate("SubVolumes")) -table_subvolume:option(DummyValue, "id", translate("ID")) -table_subvolume:option(DummyValue, "top_level", translate("Top Level")) -table_subvolume:option(DummyValue, "uuid", translate("UUID")) -table_subvolume:option(DummyValue, "otime", translate("Otime")) -table_subvolume:option(DummyValue, "snapshots", translate("Snapshots")) -local v_path = table_subvolume:option(Value, "path", translate("Path")) -v_path.forcewrite = true -v_path.render = function(self, section, scope) - if subvolume_list[section].ID == 0 then - self.template = "cbi/value" - self.placeholder = "/my_subvolume" - self.forcewrite = true - Value.render(self, section, scope) - else - self.template = "cbi/dvalue" - DummyValue.render(self, section, scope) - end -end -local value_path -v_path.write = function(self, section, value) - value_path = value -end -local btn_set_default = table_subvolume:option(Button, "_subv_set_default", translate("Set Default")) -btn_set_default.forcewrite = true -btn_set_default.inputstyle = "edit" -btn_set_default.template = "diskman/cbi/disabled_button" -btn_set_default.render = function(self, section, scope) - if subvolume_list[section].default_subvolume then - self.view_disabled = true - self.inputtitle = translate("Set Default") - elseif subvolume_list[section].ID == 0 then - self.template = "cbi/dvalue" - else - self.inputtitle = translate("Set Default") - self.view_disabled = false - end - Button.render(self, section, scope) -end -btn_set_default.write = function(self, section, value) - local cmd - if value == translate("Set Default") then - cmd = dm.command.btrfs .. " subvolume set-default " .. mount_point..subvolume_list[section].path - else - cmd = dm.command.btrfs .. " subvolume set-default " .. mount_point.."/" - end - local res = luci.util.exec(cmd.. " 2>&1") - if res and (res:match("ERR") or res:match("not enough arguments")) then - m.errmessage = res - else - luci.http.redirect(luci.dispatcher.build_url("admin/system/diskman/btrfs/" .. uuid)) - end -end -local btn_remove = table_subvolume:option(Button, "_subv_remove") -btn_remove.template = "diskman/cbi/disabled_button" -btn_remove.forcewrite = true -btn_remove.render = function(self, section, scope) - if subvolume_list[section].ID == 0 then - btn_remove.inputtitle = translate("Create") - btn_remove.inputstyle = "add" - self.view_disabled = false - elseif subvolume_list[section].path == "/" or subvolume_list[section].default_subvolume then - btn_remove.inputtitle = translate("Delete") - btn_remove.inputstyle = "remove" - self.view_disabled = true - else - btn_remove.inputtitle = translate("Delete") - btn_remove.inputstyle = "remove" - self.view_disabled = false - end - Button.render(self, section, scope) -end - -btn_remove.write = function(self, section, value) - local cmd - if value == translate("Delete") then - cmd = dm.command.btrfs .. " subvolume delete " .. mount_point .. subvolume_list[section].path - elseif value == translate("Create") then - if value_path and value_path:match("^/") then - cmd = dm.command.btrfs .. " subvolume create " .. mount_point .. value_path - else - m.errmessage = translate("Please input Subvolume Path, Subvolume must start with '/'") - return - end - end - local res = luci.util.exec(cmd.. " 2>&1") - if res and (res:match("ERR") or res:match("not enough arguments")) then - m.errmessage = luci.util.pcdata(res) - else - luci.http.redirect(luci.dispatcher.build_url("admin/system/diskman/btrfs/" .. uuid)) - end -end --- snapshot --- local snapshot_list = dm.get_btrfs_subv(mount_point, 1) --- table_snapshot = m:section(Table, snapshot_list, translate("Snapshots")) --- table_snapshot:option(DummyValue, "id", translate("ID")) --- table_snapshot:option(DummyValue, "top_level", translate("Top Level")) --- table_snapshot:option(DummyValue, "uuid", translate("UUID")) --- table_snapshot:option(DummyValue, "otime", translate("Otime")) --- table_snapshot:option(DummyValue, "path", translate("Path")) --- local snp_remove = table_snapshot:option(Button, "_snp_remove") --- snp_remove.inputtitle = translate("Delete") --- snp_remove.inputstyle = "remove" --- snp_remove.write = function(self, section, value) --- local cmd = dm.command.btrfs .. " subvolume delete " .. mount_point .. snapshot_list[section].path --- local res = luci.util.exec(cmd.. " 2>&1") --- if res and (res:match("ERR") or res:match("not enough arguments")) then --- m.errmessage = luci.util.pcdata(res) --- else --- luci.http.redirect(luci.dispatcher.build_url("admin/system/diskman/btrfs/" .. uuid)) --- end --- end - --- new snapshots -local s_snapshot = m:section(SimpleSection, translate("New Snapshot")) -local value_sorce, value_dest, value_readonly -local v_sorce = s_snapshot:option(Value, "_source", translate("Source Path"), translate("The source path for create the snapshot")) -v_sorce.placeholder = "/data" -v_sorce.forcewrite = true -v_sorce.write = function(self, section, value) - value_sorce = value -end - -local v_readonly = s_snapshot:option(Flag, "_readonly", translate("Readonly"), translate("The path where you want to store the snapshot")) -v_readonly.forcewrite = true -v_readonly.rmempty = false -v_readonly.disabled = 0 -v_readonly.enabled = 1 -v_readonly.default = 1 -v_readonly.write = function(self, section, value) - value_readonly = value -end -local v_dest = s_snapshot:option(Value, "_dest", translate("Destination Path (optional)")) -v_dest.forcewrite = true -v_dest.placeholder = "/.snapshot/202002051538" -v_dest.write = function(self, section, value) - value_dest = value -end -local btn_snp_create = s_snapshot:option(Button, "_snp_create") -btn_snp_create.title = " " -btn_snp_create.inputtitle = translate("New Snapshot") -btn_snp_create.inputstyle = "add" -btn_snp_create.write = function(self, section, value) - if value_sorce and value_sorce:match("^/") then - if not value_dest then value_dest = "/.snapshot"..value_sorce.."/"..os.date("%Y%m%d%H%M%S") end - nixio.fs.mkdirr(mount_point..value_dest:match("(.-)[^/]+$")) - local cmd = dm.command.btrfs .. " subvolume snapshot" .. (value_readonly == 1 and " -r " or " ") .. mount_point..value_sorce .. " " .. mount_point..value_dest - local res = luci.util.exec(cmd .. " 2>&1") - if res and (res:match("ERR") or res:match("not enough arguments")) then - m.errmessage = luci.util.pcdata(res) - else - luci.http.redirect(luci.dispatcher.build_url("admin/system/diskman/btrfs/" .. uuid)) - end - else - m.errmessage = translate("Please input Source Path of snapshot, Source Path must start with '/'") - end -end - -return m diff --git a/luci-app-diskman/luasrc/model/cbi/diskman/disks.lua b/luci-app-diskman/luasrc/model/cbi/diskman/disks.lua deleted file mode 100755 index c209df0aa..000000000 --- a/luci-app-diskman/luasrc/model/cbi/diskman/disks.lua +++ /dev/null @@ -1,327 +0,0 @@ ---[[ -LuCI - Lua Configuration Interface -Copyright 2019 lisaac -]]-- - -require "luci.util" -require("luci.tools.webadmin") -local dm = require "luci.model.diskman" - --- Use (non-UCI) SimpleForm since we have no related config file -m = SimpleForm("diskman", translate("DiskMan"), translate("Manage Disks over LuCI.")) -m.template = "diskman/cbi/xsimpleform" -m:append(Template("diskman/disk_info")) --- disable submit and reset button -m.submit = false -m.reset = false --- rescan disks -rescan = m:section(SimpleSection) -rescan_button = rescan:option(Button, "_rescan") -rescan_button.inputtitle= translate("Rescan Disks") -rescan_button.template = "diskman/cbi/inlinebutton" -rescan_button.inputstyle = "add" -rescan_button.forcewrite = true -rescan_button.write = function(self, section, value) - luci.util.exec("echo '- - -' | tee /sys/class/scsi_host/host*/scan > /dev/null") - if dm.command.mdadm then - luci.util.exec(dm.command.mdadm .. " --assemble --scan") - end - luci.http.redirect(luci.dispatcher.build_url("admin/system/diskman")) -end - --- disks -local disks = dm.list_devices() -d = m:section(Table, disks, translate("Disks")) -d.config = "disk" --- option(type, id(key of table), text) -d:option(DummyValue, "path", translate("Path")) -d:option(DummyValue, "model", translate("Model")) -d:option(DummyValue, "sn", translate("Serial Number")) -d:option(DummyValue, "size_formated", translate("Size")) -d:option(DummyValue, "temp", translate("Temp")) --- d:option(DummyValue, "sec_size", translate("Sector Size ")) -d:option(DummyValue, "p_table", translate("Partition Table")) -d:option(DummyValue, "sata_ver", translate("SATA Version")) --- d:option(DummyValue, "rota_rate", translate("Rotation Rate")) -d:option(DummyValue, "health", translate("Health")) -d:option(DummyValue, "status", translate("Status")) - -d.extedit = luci.dispatcher.build_url("admin/system/diskman/partition/%s") - --- raid devices -if dm.command.mdadm then - local raid_devices = dm.list_raid_devices() - -- raid_devices = diskmanager.getRAIDdevices() - if next(raid_devices) ~= nil then - local r = m:section(Table, raid_devices, translate("RAID Devices")) - r.config = "_raid" - r:option(DummyValue, "path", translate("Path")) - r:option(DummyValue, "level", translate("RAID mode")) - r:option(DummyValue, "size_formated", translate("Size")) - r:option(DummyValue, "p_table", translate("Partition Table")) - r:option(DummyValue, "status", translate("Status")) - r:option(DummyValue, "members_str", translate("Members")) - r:option(DummyValue, "active", translate("Active")) - r.extedit = luci.dispatcher.build_url("admin/system/diskman/partition/%s") - end -end - --- btrfs devices -if dm.command.btrfs then - btrfs_devices = dm.list_btrfs_devices() - if next(btrfs_devices) ~= nil then - local table_btrfs = m:section(Table, btrfs_devices, translate("Btrfs")) - table_btrfs:option(DummyValue, "uuid", translate("UUID")) - table_btrfs:option(DummyValue, "label", translate("Label")) - table_btrfs:option(DummyValue, "members", translate("Members")) - -- sieze is error, since there is RAID - -- table_btrfs:option(DummyValue, "size_formated", translate("Size")) - table_btrfs:option(DummyValue, "used_formated", translate("Usage")) - table_btrfs.extedit = luci.dispatcher.build_url("admin/system/diskman/btrfs/%s") - end -end - --- mount point -local mount_point = dm.get_mount_points() -local _mount_point = {} -table.insert( mount_point, { device = 0 } ) -local table_mp = m:section(Table, mount_point, translate("Mount Point")) -local v_device = table_mp:option(Value, "device", translate("Device")) -v_device.render = function(self, section, scope) - if mount_point[section].device == 0 then - self.template = "cbi/value" - self.forcewrite = true - for dev, info in pairs(disks) do - for i, v in ipairs(info.partitions) do - self:value("/dev/".. v.name, "/dev/".. v.name .. " ".. v.size_formated) - end - end - Value.render(self, section, scope) - else - self.template = "cbi/dvalue" - DummyValue.render(self, section, scope) - end -end -v_device.write = function(self, section, value) - _mount_point.device = value and value:gsub("%s+", "") or "" -end -local v_fs = table_mp:option(Value, "fs", translate("File System")) -v_fs.render = function(self, section, scope) - if mount_point[section].device == 0 then - self.template = "cbi/value" - self:value("auto", "auto") - self.default = "auto" - self.forcewrite = true - Value.render(self, section, scope) - else - self.template = "cbi/dvalue" - DummyValue.render(self, section, scope) - end -end -v_fs.write = function(self, section, value) - _mount_point.fs = value and value:gsub("%s+", "") or "" -end -local v_mount_option = table_mp:option(Value, "mount_options", translate("Mount Options")) -v_mount_option.render = function(self, section, scope) - if mount_point[section].device == 0 then - self.template = "cbi/value" - self.placeholder = "rw,noauto" - self.forcewrite = true - Value.render(self, section, scope) - else - self.template = "cbi/dvalue" - local mp = mount_point[section].mount_options - mount_point[section].mount_options = nil - local length = 0 - for k in mp:gmatch("([^,]+)") do - mount_point[section].mount_options = mount_point[section].mount_options and (mount_point[section].mount_options .. ",") or "" - if length > 20 then - mount_point[section].mount_options = mount_point[section].mount_options.. "
" - length = 0 - end - mount_point[section].mount_options = mount_point[section].mount_options .. k - length = length + #k - end - self.rawhtml = true - -- mount_point[section].mount_options = #mount_point[section].mount_options > 50 and mount_point[section].mount_options:sub(1,50) .. "..." or mount_point[section].mount_options - DummyValue.render(self, section, scope) - end -end -v_mount_option.write = function(self, section, value) - _mount_point.mount_options = value and value:gsub("%s+", "") or "" -end -local v_mount_point = table_mp:option(Value, "mount_point", translate("Mount Point")) -v_mount_point.render = function(self, section, scope) - if mount_point[section].device == 0 then - self.template = "cbi/value" - self.placeholder = "/media/diskX" - self.forcewrite = true - Value.render(self, section, scope) - else - self.template = "cbi/dvalue" - local new_mp = "" - local v_mp_d - for v_mp_d in self["section"]["data"][section]["mount_point"]:gmatch('[^/]+') do - if #v_mp_d > 12 then - new_mp = new_mp .. "/" .. v_mp_d:sub(1,7) .. ".." .. v_mp_d:sub(-4) - else - new_mp = new_mp .."/".. v_mp_d - end - end - self["section"]["data"][section]["mount_point"] = ''..new_mp..'' - self.rawhtml = true - DummyValue.render(self, section, scope) - end -end -v_mount_point.write = function(self, section, value) - _mount_point.mount_point = value -end -local btn_umount = table_mp:option(Button, "_mount", translate("Mount")) -btn_umount.forcewrite = true -btn_umount.render = function(self, section, scope) - if mount_point[section].device == 0 then - self.inputtitle = translate("Mount") - btn_umount.inputstyle = "add" - else - self.inputtitle = translate("Umount") - btn_umount.inputstyle = "remove" - end - Button.render(self, section, scope) -end -btn_umount.write = function(self, section, value) - local res - if value == translate("Mount") then - if not _mount_point.mount_point or not _mount_point.device then return end - luci.util.exec("mkdir -p ".. _mount_point.mount_point) - res = luci.util.exec(dm.command.mount .. " ".. _mount_point.device .. (_mount_point.fs and (" -t ".. _mount_point.fs )or "") .. (_mount_point.mount_options and (" -o " .. _mount_point.mount_options.. " ") or " ").._mount_point.mount_point .. " 2>&1") - elseif value == translate("Umount") then - res = luci.util.exec(dm.command.umount .. " "..mount_point[section].mount_point .. " 2>&1") - end - if res:match("^mount:") or res:match("^umount:") then - m.errmessage = luci.util.pcdata(res) - else - luci.http.redirect(luci.dispatcher.build_url("admin/system/diskman")) - end -end - -if dm.command.mdadm or dm.command.btrfs then -local creation_section = m:section(TypedSection, "_creation") -creation_section.cfgsections=function() - return {translate("Creation")} -end -creation_section:tab("raid", translate("RAID"), translate("RAID Creation")) -creation_section:tab("btrfs", translate("Btrfs"), translate("Multiple Devices Btrfs Creation")) - --- raid functions -if dm.command.mdadm then - - local rname, rmembers, rlevel - local r_name = creation_section:taboption("raid", Value, "_rname", translate("Raid Name")) - r_name.placeholder = "/dev/md0" - r_name.write = function(self, section, value) - rname = value - end - local r_level = creation_section:taboption("raid", ListValue, "_rlevel", translate("Raid Level")) - local valid_raid = luci.util.exec("lsmod | grep md_mod") - if valid_raid:match("linear") then - r_level:value("linear", "Linear") - end - if valid_raid:match("raid456") then - r_level:value("5", "Raid 5") - r_level:value("6", "Raid 6") - end - if valid_raid:match("raid1") then - r_level:value("1", "Raid 1") - end - if valid_raid:match("raid0") then - r_level:value("0", "Raid 0") - end - if valid_raid:match("raid10") then - r_level:value("10", "Raid 10") - end - r_level.write = function(self, section, value) - rlevel = value - end - local r_member = creation_section:taboption("raid", DynamicList, "_rmember", translate("Raid Member")) - for dev, info in pairs(disks) do - if not info.inuse and #info.partitions == 0 then - r_member:value(info.path, info.path.. " ".. info.size_formated) - end - for i, v in ipairs(info.partitions) do - if not v.inuse then - r_member:value("/dev/".. v.name, "/dev/".. v.name .. " ".. v.size_formated) - end - end - end - r_member.write = function(self, section, value) - rmembers = value - end - local r_create = creation_section:taboption("raid", Button, "_rcreate") - r_create.render = function(self, section, scope) - self.title = " " - self.inputtitle = translate("Create Raid") - self.inputstyle = "add" - Button.render(self, section, scope) - end - r_create.write = function(self, section, value) - -- mdadm --create --verbose /dev/md0 --level=stripe --raid-devices=2 /dev/sdb6 /dev/sdc5 - local res = dm.create_raid(rname, rlevel, rmembers) - if res and res:match("^ERR") then - m.errmessage = luci.util.pcdata(res) - return - end - dm.gen_mdadm_config() - luci.http.redirect(luci.dispatcher.build_url("admin/system/diskman")) - end -end - --- btrfs -if dm.command.btrfs then - local blabel, bmembers, blevel - local btrfs_label = creation_section:taboption("btrfs", Value, "_blabel", translate("Btrfs Label")) - btrfs_label.write = function(self, section, value) - blabel = value - end - local btrfs_level = creation_section:taboption("btrfs", ListValue, "_blevel", translate("Btrfs Raid Level")) - btrfs_level:value("single", "Single") - btrfs_level:value("raid0", "Raid 0") - btrfs_level:value("raid1", "Raid 1") - btrfs_level:value("raid10", "Raid 10") - btrfs_level.write = function(self, section, value) - blevel = value - end - - local btrfs_member = creation_section:taboption("btrfs", DynamicList, "_bmember", translate("Btrfs Member")) - for dev, info in pairs(disks) do - if not info.inuse and #info.partitions == 0 then - btrfs_member:value(info.path, info.path.. " ".. info.size_formated) - end - for i, v in ipairs(info.partitions) do - if not v.inuse then - btrfs_member:value("/dev/".. v.name, "/dev/".. v.name .. " ".. v.size_formated) - end - end - end - btrfs_member.write = function(self, section, value) - bmembers = value - end - local btrfs_create = creation_section:taboption("btrfs", Button, "_bcreate") - btrfs_create.render = function(self, section, scope) - self.title = " " - self.inputtitle = translate("Create Btrfs") - self.inputstyle = "add" - Button.render(self, section, scope) - end - btrfs_create.write = function(self, section, value) - -- mkfs.btrfs -L label -d blevel /dev/sda /dev/sdb - local res = dm.create_btrfs(blabel, blevel, bmembers) - if res and res:match("^ERR") then - m.errmessage = luci.util.pcdata(res) - return - end - luci.http.redirect(luci.dispatcher.build_url("admin/system/diskman")) - end -end -end - -return m diff --git a/luci-app-diskman/luasrc/model/cbi/diskman/partition.lua b/luci-app-diskman/luasrc/model/cbi/diskman/partition.lua deleted file mode 100755 index 1428eb6b2..000000000 --- a/luci-app-diskman/luasrc/model/cbi/diskman/partition.lua +++ /dev/null @@ -1,366 +0,0 @@ ---[[ -LuCI - Lua Configuration Interface -Copyright 2019 lisaac -]]-- - -require "luci.util" -require("luci.tools.webadmin") -local dm = require "luci.model.diskman" -local dev = arg[1] - -if not dev then - luci.http.redirect(luci.dispatcher.build_url("admin/system/diskman")) -elseif not nixio.fs.access("/dev/"..dev) then - luci.http.redirect(luci.dispatcher.build_url("admin/system/diskman")) -end - -m = SimpleForm("partition", translate("Partition Management"), translate("Partition Disk over LuCI.")) -m.template = "diskman/cbi/xsimpleform" -m.redirect = luci.dispatcher.build_url("admin/system/diskman") -m:append(Template("diskman/partition_info")) --- disable submit and reset button -m.submit = false -m.reset = false - -local disk_info = dm.get_disk_info(dev, true) -local format_cmd = dm.get_format_cmd() - -s = m:section(Table, {disk_info}, translate("Device Info")) --- s:option(DummyValue, "key") --- s:option(DummyValue, "value") -s:option(DummyValue, "path", translate("Path")) -s:option(DummyValue, "model", translate("Model")) -s:option(DummyValue, "sn", translate("Serial Number")) -s:option(DummyValue, "size_formated", translate("Size")) -s:option(DummyValue, "sec_size", translate("Sector Size")) -local dv_p_table = s:option(ListValue, "p_table", translate("Partition Table")) -dv_p_table.render = function(self, section, scope) - -- create table only if not used by raid and no partitions on disk - if not disk_info.p_table:match("Raid") and (#disk_info.partitions == 0 or (#disk_info.partitions == 1 and disk_info.partitions[1].number == -1) or (disk_info.p_table:match("LOOP") and not disk_info.partitions[1].inuse)) then - self:value(disk_info.p_table, disk_info.p_table) - self:value("GPT", "GPT") - self:value("MBR", "MBR") - self.default = disk_info.p_table - ListValue.render(self, section, scope) - else - self.template = "cbi/dvalue" - DummyValue.render(self, section, scope) - end -end -if disk_info.type:match("md") then - s:option(DummyValue, "level", translate("Level")) - s:option(DummyValue, "members_str", translate("Members")) -else - s:option(DummyValue, "temp", translate("Temp")) - s:option(DummyValue, "sata_ver", translate("SATA Version")) - s:option(DummyValue, "rota_rate", translate("Rotation Rate")) -end -s:option(DummyValue, "status", translate("Status")) -local btn_health = s:option(Button, "health", translate("Health")) -btn_health.render = function(self, section, scope) - if disk_info.health then - self.inputtitle = disk_info.health - if disk_info.health == "PASSED" then - self.inputstyle = "add" - else - self.inputstyle = "remove" - end - Button.render(self, section, scope) - else - self.template = "cbi/dvalue" - DummyValue.render(self, section, scope) - end -end - -local btn_eject = s:option(Button, "_eject") -btn_eject.template = "diskman/cbi/disabled_button" -btn_eject.inputstyle = "remove" -btn_eject.render = function(self, section, scope) - for i, p in ipairs(disk_info.partitions) do - if p.mount_point ~= "-" then - self.view_disabled = true - break - end - end - if disk_info.p_table:match("Raid") then - self.view_disabled = true - end - if disk_info.type:match("md") then - btn_eject.inputtitle = translate("Remove") - else - btn_eject.inputtitle = translate("Eject") - end - Button.render(self, section, scope) -end -btn_eject.forcewrite = true -btn_eject.write = function(self, section, value) - for i, p in ipairs(disk_info.partitions) do - if p.mount_point ~= "-" then - m.errmessage = p.name .. translate("is in use! please unmount it first!") - return - end - end - if disk_info.type:match("md") then - luci.util.exec(dm.command.mdadm .. " --stop /dev/" .. dev) - luci.util.exec(dm.command.mdadm .. " --remove /dev/" .. dev) - for _, disk in ipairs(disk_info.members) do - luci.util.exec(dm.command.mdadm .. " --zero-superblock " .. disk) - end - dm.gen_mdadm_config() - else - luci.util.exec("echo 1 > /sys/block/" .. dev .. "/device/delete") - end - luci.http.redirect(luci.dispatcher.build_url("admin/system/diskman")) -end --- eject: echo 1 > /sys/block/(device)/device/delete --- rescan: echo '- - -' | tee /sys/class/scsi_host/host*/scan > /dev/null - - --- partitions info -if not disk_info.p_table:match("Raid") then - s_partition_table = m:section(Table, disk_info.partitions, translate("Partitions Info"), translate("Default 2048 sector alignment, support +size{b,k,m,g,t} in End Sector")) - - -- s_partition_table:option(DummyValue, "number", translate("Number")) - s_partition_table:option(DummyValue, "name", translate("Name")) - local val_sec_start = s_partition_table:option(Value, "sec_start", translate("Start Sector")) - val_sec_start.render = function(self, section, scope) - -- could create new partition - if disk_info.partitions[section].number == -1 and disk_info.partitions[section].size > 1 * 1024 * 1024 then - self.template = "cbi/value" - Value.render(self, section, scope) - else - self.template = "cbi/dvalue" - DummyValue.render(self, section, scope) - end - end - local val_sec_end = s_partition_table:option(Value, "sec_end", translate("End Sector")) - val_sec_end.render = function(self, section, scope) - -- could create new partition - if disk_info.partitions[section].number == -1 and disk_info.partitions[section].size > 1 * 1024 * 1024 then - self.template = "cbi/value" - Value.render(self, section, scope) - else - self.template = "cbi/dvalue" - DummyValue.render(self, section, scope) - end - end - val_sec_start.forcewrite = true - val_sec_start.write = function(self, section, value) - disk_info.partitions[section]._sec_start = value - end - val_sec_end.forcewrite = true - val_sec_end.write = function(self, section, value) - disk_info.partitions[section]._sec_end = value - end - s_partition_table:option(DummyValue, "size_formated", translate("Size")) - if disk_info.p_table == "MBR" then - s_partition_table:option(DummyValue, "type", translate("Type")) - end - s_partition_table:option(DummyValue, "used_formated", translate("Used")) - s_partition_table:option(DummyValue, "free_formated", translate("Free Space")) - s_partition_table:option(DummyValue, "usage", translate("Usage")) - local dv_mount_point = s_partition_table:option(DummyValue, "mount_point", translate("Mount Point")) - dv_mount_point.rawhtml = true - dv_mount_point.render = function(self, section, scope) - local new_mp = "" - local v_mp_d - for line in self["section"]["data"][section]["mount_point"]:gmatch("[^%s]+") do - if line == '-' then - new_mp = line - break - end - for v_mp_d in line:gmatch('[^/]+') do - if #v_mp_d > 12 then - new_mp = new_mp .. "/" .. v_mp_d:sub(1,7) .. ".." .. v_mp_d:sub(-4) - else - new_mp = new_mp .."/".. v_mp_d - end - end - new_mp = '' ..new_mp ..'' .. "
" - end - self["section"]["data"][section]["mount_point"] = new_mp - DummyValue.render(self, section, scope) - end - local val_fs = s_partition_table:option(Value, "fs", translate("File System")) - val_fs.forcewrite = true - val_fs.partitions = disk_info.partitions - for k, v in pairs(format_cmd) do - val_fs.format_cmd = val_fs.format_cmd and (val_fs.format_cmd .. "," .. k) or k - end - - val_fs.write = function(self, section, value) - disk_info.partitions[section]._fs = value - end - val_fs.render = function(self, section, scope) - -- use listvalue when partition not mounted - if disk_info.partitions[section].mount_point == "-" and disk_info.partitions[section].number ~= -1 and disk_info.partitions[section].type ~= "extended" then - self.template = "diskman/cbi/format_button" - self.inputstyle = "reset" - self.inputtitle = disk_info.partitions[section].fs == "raw" and translate("Format") or disk_info.partitions[section].fs - Button.render(self, section, scope) - -- self:reset_values() - -- self.keylist = {} - -- self.vallist = {} - -- for k, v in pairs(format_cmd) do - -- self:value(k,k) - -- end - -- self.default = disk_info.partitions[section].fs - else - -- self:reset_values() - -- self.keylist = {} - -- self.vallist = {} - self.template = "cbi/dvalue" - DummyValue.render(self, section, scope) - end - end - -- btn_format = s_partition_table:option(Button, "_format") - -- btn_format.template = "diskman/cbi/format_button" - -- btn_format.partitions = disk_info.partitions - -- btn_format.render = function(self, section, scope) - -- if disk_info.partitions[section].mount_point == "-" and disk_info.partitions[section].number ~= -1 and disk_info.partitions[section].type ~= "extended" then - -- self.inputtitle = translate("Format") - -- self.template = "diskman/cbi/disabled_button" - -- self.view_disabled = false - -- self.inputstyle = "reset" - -- for k, v in pairs(format_cmd) do - -- self:depends("val_fs", "k") - -- end - -- -- elseif disk_info.partitions[section].mount_point ~= "-" and disk_info.partitions[section].number ~= -1 then - -- -- self.inputtitle = "Format" - -- -- self.template = "diskman/cbi/disabled_button" - -- -- self.view_disabled = true - -- -- self.inputstyle = "reset" - -- else - -- self.inputtitle = "" - -- self.template = "cbi/dvalue" - -- end - -- Button.render(self, section, scope) - -- end - -- btn_format.forcewrite = true - -- btn_format.write = function(self, section, value) - -- local partition_name = "/dev/".. disk_info.partitions[section].name - -- if not nixio.fs.access(partition_name) then - -- m.errmessage = translate("Partition NOT found!") - -- return - -- end - -- local fs = disk_info.partitions[section]._fs - -- if not format_cmd[fs] then - -- m.errmessage = translate("Filesystem NOT support!") - -- return - -- end - -- local cmd = format_cmd[fs].cmd .. " " .. format_cmd[fs].option .. " " .. partition_name - -- local res = luci.util.exec(cmd .. " 2>&1") - -- if res and res:lower():match("error+") then - -- m.errmessage = luci.util.pcdata(res) - -- else - -- luci.http.redirect(luci.dispatcher.build_url("admin/system/diskman/partition/" .. dev)) - -- end - -- end - - local btn_action = s_partition_table:option(Button, "_action") - btn_action.forcewrite = true - btn_action.template = "diskman/cbi/disabled_button" - btn_action.render = function(self, section, scope) - -- if partition is mounted or the size < 1mb, then disable the add action - if disk_info.partitions[section].mount_point ~= "-" or (disk_info.partitions[section].type ~= "extended" and disk_info.partitions[section].number == -1 and disk_info.partitions[section].size <= 1 * 1024 * 1024) then - self.view_disabled = true - -- self.inputtitle = "" - -- self.template = "cbi/dvalue" - elseif disk_info.partitions[section].type == "extended" and next(disk_info.partitions[section]["logicals"]) ~= nil then - self.view_disabled = true - else - -- self.template = "diskman/cbi/disabled_button" - self.view_disabled = false - end - if disk_info.partitions[section].number ~= -1 then - self.inputtitle = translate("Remove") - self.inputstyle = "remove" - else - self.inputtitle = translate("New") - self.inputstyle = "add" - end - Button.render(self, section, scope) - end - btn_action.write = function(self, section, value) - if value == translate("New") then - local start_sec = disk_info.partitions[section]._sec_start and tonumber(disk_info.partitions[section]._sec_start) or tonumber(disk_info.partitions[section].sec_start) - local end_sec = disk_info.partitions[section]._sec_end - - if start_sec then - -- for sector alignment - local align = tonumber(disk_info.phy_sec) / tonumber(disk_info.logic_sec) - align = (align < 2048) and 2048 - if start_sec < 2048 then - start_sec = "2048" .. "s" - elseif math.fmod( start_sec, align ) ~= 0 then - start_sec = tostring(start_sec + align - math.fmod( start_sec, align )) .. "s" - else - start_sec = start_sec .. "s" - end - else - m.errmessage = translate("Invalid Start Sector!") - return - end - -- support +size format for End sector - local end_size, end_unit = end_sec:match("^+(%d-)([bkmgtsBKMGTS])$") - if tonumber(end_size) and end_unit then - local unit ={ - B=1, - S=512, - K=1024, - M=1048576, - G=1073741824, - T=1099511627776 - } - end_unit = end_unit:upper() - end_sec = tostring(tonumber(end_size) * unit[end_unit] / unit["S"] + tonumber(start_sec:sub(1,-2)) - 1 ) .. "s" - elseif tonumber(end_sec) then - end_sec = end_sec .. "s" - else - m.errmessage = translate("Invalid End Sector!") - return - end - local part_type = "primary" - - if disk_info.p_table == "MBR" and disk_info["extended_partition_index"] then - if tonumber(disk_info.partitions[disk_info["extended_partition_index"]].sec_start) <= tonumber(start_sec:sub(1,-2)) and tonumber(disk_info.partitions[disk_info["extended_partition_index"]].sec_end) >= tonumber(end_sec:sub(1,-2)) then - part_type = "logical" - if tonumber(start_sec:sub(1,-2)) - tonumber(disk_info.partitions[section].sec_start) < 2048 then - start_sec = tonumber(start_sec:sub(1,-2)) + 2048 - start_sec = start_sec .."s" - end - end - elseif disk_info.p_table == "GPT" then - -- AUTOMATIC FIX GPT PARTITION TABLE - -- Not all of the space available to /dev/sdb appears to be used, you can fix the GPT to use all of the space (an extra 16123870 blocks) or continue with the current setting? - local cmd = ' printf "ok\nfix\n" | parted ---pretend-input-tty /dev/'.. dev ..' print' - luci.util.exec(cmd .. " 2>&1") - end - - -- partiton - local cmd = dm.command.parted .. " -s -a optimal /dev/" .. dev .. " mkpart " .. part_type .." " .. start_sec .. " " .. end_sec - local res = luci.util.exec(cmd .. " 2>&1") - if res and res:lower():match("error+") then - m.errmessage = luci.util.pcdata(res) - else - luci.http.redirect(luci.dispatcher.build_url("admin/system/diskman/partition/" .. dev)) - end - elseif value == translate("Remove") then - -- remove partition - local number = tostring(disk_info.partitions[section].number) - if (not number) or (number == "") then - m.errmessage = translate("Partition not exists!") - return - end - local cmd = dm.command.parted .. " -s /dev/" .. dev .. " rm " .. number - local res = luci.util.exec(cmd .. " 2>&1") - if res and res:lower():match("error+") then - m.errmessage = luci.util.pcdata(res) - else - luci.http.redirect(luci.dispatcher.build_url("admin/system/diskman/partition/" .. dev)) - end - end - end -end - -return m diff --git a/luci-app-diskman/luasrc/model/diskman.lua b/luci-app-diskman/luasrc/model/diskman.lua deleted file mode 100755 index b29308c31..000000000 --- a/luci-app-diskman/luasrc/model/diskman.lua +++ /dev/null @@ -1,738 +0,0 @@ ---[[ -LuCI - Lua Configuration Interface -Copyright 2019 lisaac -]]-- - -require "luci.util" -local ver = require "luci.version" - -local CMD = {"parted", "mdadm", "blkid", "smartctl", "df", "btrfs", "lsblk"} - -local d = {command ={}} -for _, cmd in ipairs(CMD) do - local command = luci.sys.exec("/usr/bin/which " .. cmd) - d.command[cmd] = command:match("^.+"..cmd) or nil -end - -d.command.mount = nixio.fs.access("/usr/bin/mount") and "/usr/bin/mount" or "/bin/mount" -d.command.umount = nixio.fs.access("/usr/bin/umount") and "/usr/bin/umount" or "/bin/umount" - -local proc_mounts = nixio.fs.readfile("/proc/mounts") or "" -local mounts = luci.util.exec(d.command.mount .. " 2>/dev/null") or "" -local swaps = nixio.fs.readfile("/proc/swaps") or "" -local df = luci.sys.exec(d.command.df .. " 2>/dev/null") or "" - -function byte_format(byte) - local suff = {"B", "KB", "MB", "GB", "TB"} - for i=1, 5 do - if byte > 1024 and i < 5 then - byte = byte / 1024 - else - return string.format("%.2f %s", byte, suff[i]) - end - end -end - -local get_smart_info = function(device) - local section - local smart_info = {} - for _, line in ipairs(luci.util.execl(d.command.smartctl .. " -H -A -i -n standby -f brief /dev/" .. device)) do - local attrib, val - if section == 1 then - attrib, val = line:match "^(.-):%s+(.+)" - elseif section == 2 and smart_info.nvme_ver then - attrib, val = line:match("^(.-):%s+(.+)") - if not smart_info.health then smart_info.health = line:match(".-overall%-health.-: (.+)") end - elseif section == 2 then - attrib, val = line:match("^([0-9 ]+)%s+[^ ]+%s+[POSRCK-]+%s+[0-9-]+%s+[0-9-]+%s+[0-9-]+%s+[0-9-]+%s+([0-9-]+)") - if not smart_info.health then smart_info.health = line:match(".-overall%-health.-: (.+)") end - else - attrib = line:match "^=== START OF (.*) SECTION ===" - if attrib and attrib:match("INFORMATION") then - section = 1 - elseif attrib and attrib:match("SMART DATA") then - section = 2 - elseif not smart_info.status then - val = line:match "^Device is in (.*) mode" - if val then smart_info.status = val end - end - end - - if not attrib then - if section ~= 2 then section = 0 end - elseif (attrib == "Power mode is") or - (attrib == "Power mode was") then - smart_info.status = val:match("(%S+)") - -- elseif attrib == "Sector Sizes" then - -- -- 512 bytes logical, 4096 bytes physical - -- smart_info.phy_sec = val:match "([0-9]*) bytes physical" - -- smart_info.logic_sec = val:match "([0-9]*) bytes logical" - -- elseif attrib == "Sector Size" then - -- -- 512 bytes logical/physical - -- smart_info.phy_sec = val:match "([0-9]*)" - -- smart_info.logic_sec = smart_info.phy_sec - elseif attrib == "Serial Number" then - smart_info.sn = val - elseif attrib == "194" or attrib == "Temperature" then - smart_info.temp = val:match("(%d+)") .. "°C" - elseif attrib == "Rotation Rate" then - smart_info.rota_rate = val - elseif attrib == "SATA Version is" then - smart_info.sata_ver = val - elseif attrib == "NVMe Version" then - smart_info.nvme_ver = val - end - end - return smart_info -end - -local parse_parted_info = function(keys, line) - -- parse the output of parted command (machine parseable format) - -- /dev/sda:5860533168s:scsi:512:4096:gpt:ATA ST3000DM001-1ER1:; - -- 1:34s:2047s:2014s:free; - -- 1:2048s:1073743872s:1073741825s:ext4:primary:; - local result = {} - local values = {} - - for value in line:gmatch("(.-)[:;]") do table.insert(values, value) end - for i = 1,#keys do - result[keys[i]] = values[i] or "" - end - return result -end - -local is_raid_member = function(partition) - -- check if inuse as raid member - if nixio.fs.access("/proc/mdstat") then - for _, result in ipairs(luci.util.execl("grep md /proc/mdstat | sed 's/[][]//g'")) do - local md, buf - md, buf = result:match("(md.-):(.+)") - if buf:match(partition) then - return "Raid Member: ".. md - end - end - end - return nil -end - -local get_mount_point = function(partition) - local mount_point - for m in mounts:gmatch("/dev/"..partition.." on ([^ ]*)") do - mount_point = (mount_point and (mount_point .. " ") or "") .. m - end - if mount_point then return mount_point end - -- result = luci.sys.exec('cat /proc/mounts | awk \'{if($1=="/dev/'.. partition ..'") print $2}\'') - -- if result ~= "" then return result end - - if swaps:match("\n/dev/" .. partition .."%s") then return "swap" end - -- result = luci.sys.exec("cat /proc/swaps | grep /dev/" .. partition) - -- if result ~= "" then return "swap" end - - return is_raid_member(partition) - -end - --- return used, free, usage -local get_partition_usage = function(partition) - if not nixio.fs.access("/dev/"..partition) then return false end - local used, free, usage = df:match("\n/dev/" .. partition .. "%s+%d+%s+(%d+)%s+(%d+)%s+(%d+)%%%s-") - - usage = usage and (usage .. "%") or "-" - used = used and (tonumber(used) * 1024) or 0 - free = free and (tonumber(free) * 1024) or 0 - - return used, free, usage -end - -local get_parted_info = function(device) - if not device then return end - local result = {partitions={}} - local DEVICE_INFO_KEYS = { "path", "size", "type", "logic_sec", "phy_sec", "p_table", "model", "flags" } - local PARTITION_INFO_KEYS = { "number", "sec_start", "sec_end", "size", "fs", "tag_name", "flags" } - local partition_temp - local partitions_temp = {} - local disk_temp - - for line in luci.util.execi(d.command.parted .. " -s -m /dev/" .. device .. " unit s print free", "r") do - if line:find("^/dev/"..device..":.+") then - disk_temp = parse_parted_info(DEVICE_INFO_KEYS, line) - disk_temp.partitions = {} - if disk_temp["size"] then - local length = disk_temp["size"]:gsub("^(%d+)s$", "%1") - local newsize = tostring(tonumber(length)*tonumber(disk_temp["logic_sec"])) - disk_temp["size"] = newsize - end - if disk_temp["p_table"] == "msdos" then - disk_temp["p_table"] = "MBR" - else - disk_temp["p_table"] = disk_temp["p_table"]:upper() - end - elseif line:find("^%d-:.+") then - partition_temp = parse_parted_info(PARTITION_INFO_KEYS, line) - -- use human-readable form instead of sector number - if partition_temp["size"] then - local length = partition_temp["size"]:gsub("^(%d+)s$", "%1") - local newsize = (tonumber(length) * tonumber(disk_temp["logic_sec"])) - partition_temp["size"] = newsize - partition_temp["size_formated"] = byte_format(newsize) - end - partition_temp["number"] = tonumber(partition_temp["number"]) or -1 - if partition_temp["fs"] == "free" then - partition_temp["number"] = -1 - partition_temp["fs"] = "Free Space" - partition_temp["name"] = "-" - elseif device:match("sd") or device:match("sata") then - partition_temp["name"] = device..partition_temp["number"] - elseif device:match("mmcblk") or device:match("md") or device:match("nvme") then - partition_temp["name"] = device.."p"..partition_temp["number"] - end - if partition_temp["number"] > 0 and partition_temp["fs"] == "" and d.command.lsblk then - partition_temp["fs"] = luci.util.exec(d.command.lsblk .. " /dev/"..device.. tostring(partition_temp["number"]) .. " -no fstype"):match("([^%s]+)") or "" - end - partition_temp["fs"] = partition_temp["fs"] == "" and "raw" or partition_temp["fs"] - partition_temp["sec_start"] = partition_temp["sec_start"] and partition_temp["sec_start"]:sub(1,-2) - partition_temp["sec_end"] = partition_temp["sec_end"] and partition_temp["sec_end"]:sub(1,-2) - partition_temp["mount_point"] = partition_temp["name"]~="-" and get_mount_point(partition_temp["name"]) or "-" - if partition_temp["mount_point"]~="-" then - partition_temp["used"], partition_temp["free"], partition_temp["usage"] = get_partition_usage(partition_temp["name"]) - partition_temp["used_formated"] = partition_temp["used"] and byte_format(partition_temp["used"]) or "-" - partition_temp["free_formated"] = partition_temp["free"] and byte_format(partition_temp["free"]) or "-" - else - partition_temp["used"], partition_temp["free"], partition_temp["usage"] = 0,0,"-" - partition_temp["used_formated"] = "-" - partition_temp["free_formated"] = "-" - end - -- if disk_temp["p_table"] == "MBR" and (partition_temp["number"] < 4) and (partition_temp["number"] > 0) then - -- local real_size_sec = tonumber(nixio.fs.readfile("/sys/block/"..device.."/"..partition_temp["name"].."/size")) * tonumber(disk_temp.phy_sec) - -- if real_size_sec ~= partition_temp["size"] then - -- disk_temp["extended_partition_index"] = partition_temp["number"] - -- partition_temp["type"] = "extended" - -- partition_temp["size"] = real_size_sec - -- partition_temp["fs"] = "-" - -- partition_temp["logicals"] = {} - -- else - -- partition_temp["type"] = "primary" - -- end - -- end - - table.insert(partitions_temp, partition_temp) - end - end - if disk_temp and disk_temp["p_table"] == "MBR" then - for i, p in ipairs(partitions_temp) do - if disk_temp["extended_partition_index"] and p["number"] > 4 then - if tonumber(p["sec_end"]) <= tonumber(partitions_temp[disk_temp["extended_partition_index"]]["sec_end"]) and tonumber(p["sec_start"]) >= tonumber(partitions_temp[disk_temp["extended_partition_index"]]["sec_start"]) then - p["type"] = "logical" - table.insert(partitions_temp[disk_temp["extended_partition_index"]]["logicals"], i) - end - elseif (p["number"] < 4) and (p["number"] > 0) then - local s = nixio.fs.readfile("/sys/block/"..device.."/"..p["name"].."/size") - if s then - local real_size_sec = tonumber(s) * tonumber(disk_temp.phy_sec) - -- if size not equal, it's an extended - if real_size_sec ~= p["size"] then - disk_temp["extended_partition_index"] = i - p["type"] = "extended" - p["size"] = real_size_sec - p["fs"] = "-" - p["logicals"] = {} - else - p["type"] = "primary" - end - else - -- if not found in "/sys/block" - p["type"] = "primary" - end - end - end - end - result = disk_temp - result.partitions = partitions_temp - - return result -end - -local mddetail = function(mdpath) - local detail = {} - local path = mdpath:match("^/dev/md%d+$") - if path then - local mdadm = io.popen(d.command.mdadm .. " --detail "..path, "r") - for line in mdadm:lines() do - local key, value = line:match("^%s*(.+) : (.+)") - if key then - detail[key] = value - end - end - mdadm:close() - end - return detail -end - --- return {{device="", mount_points="", fs="", mount_options="", dump="", pass=""}..} -d.get_mount_points = function() - local mount - local res = {} - local h ={"device", "mount_point", "fs", "mount_options", "dump", "pass"} - for mount in proc_mounts:gmatch("[^\n]+") do - local device = mount:match("^([^%s]+)%s+.+") - -- only show /dev/xxx device - if device and device:match("/dev/") then - res[#res+1] = {} - local i = 0 - for v in mount:gmatch("[^%s]+") do - i = i + 1 - res[#res][h[i]] = v - end - end - end - return res -end - -d.get_disk_info = function(device, wakeup) - --[[ return: - { - path, model, sn, size, size_mounted, flags, type, temp, p_table, logic_sec, phy_sec, sec_size, sata_ver, rota_rate, status, health, - partitions = { - 1 = { number, name, sec_start, sec_end, size, size_mounted, fs, tag_name, type, flags, mount_point, usage, used, free, used_formated, free_formated}, - 2 = { number, name, sec_start, sec_end, size, size_mounted, fs, tag_name, type, flags, mount_point, usage, used, free, used_formated, free_formated}, - ... - } - --raid devices only - level, members, members_str - } - --]] - if not device then return end - local disk_info - local smart_info = get_smart_info(device) - - -- check if divice is the member of raid - smart_info["p_table"] = is_raid_member(device..'0') - -- if status is not active(standby), only check smart_info. - -- if only weakup == true, weakup the disk and check parted_info. - if smart_info.status ~= "STANDBY" or wakeup or (smart_info["p_table"] and not smart_info["p_table"]:match("Raid")) or device:match("^md") then - disk_info = get_parted_info(device) - disk_info["sec_size"] = disk_info["logic_sec"] .. "/" .. disk_info["phy_sec"] - disk_info["size_formated"] = byte_format(tonumber(disk_info["size"])) - -- if status is standby, after get part info, the disk is weakuped, then get smart_info again for more informations - if smart_info.status ~= "ACTIVE" then smart_info = get_smart_info(device) end - else - disk_info = {} - end - - for k, v in pairs(smart_info) do - disk_info[k] = v - end - - if disk_info.type and disk_info.type:match("md") then - local raid_info = d.list_raid_devices()[disk_info["path"]:match("/dev/(.+)")] - for k, v in pairs(raid_info) do - disk_info[k] = v - end - end - return disk_info -end - -d.list_raid_devices = function() - local fs = require "nixio.fs" - - local raid_devices = {} - if not fs.access("/proc/mdstat") then return raid_devices end - local mdstat = io.open("/proc/mdstat", "r") - for line in mdstat:lines() do - - -- md1 : active raid1 sdb2[1] sda2[0] - -- md127 : active raid5 sdh1[6] sdg1[4] sdf1[3] sde1[2] sdd1[1] sdc1[0] - local device_info = {} - local mdpath, list = line:match("^(md%d+) : (.+)") - if mdpath then - local members = {} - for member in string.gmatch(list, "%S+") do - member_path = member:match("^(%S+)%[%d+%]") - if member_path then - member = '/dev/'..member_path - end - table.insert(members, member) - end - local active = table.remove(members, 1) - local level = "-" - if active == "active" then - level = table.remove(members, 1) - end - - local size = tonumber(fs.readfile(string.format("/sys/class/block/%s/size", mdpath))) - local ss = tonumber(fs.readfile(string.format("/sys/class/block/%s/queue/logical_block_size", mdpath))) - - device_info["path"] = "/dev/"..mdpath - device_info["size"] = size*ss - device_info["size_formated"] = byte_format(size*ss) - device_info["active"] = active:upper() - device_info["level"] = level - device_info["members"] = members - device_info["members_str"] = table.concat(members, ", ") - - -- Get more info from output of mdadm --detail - local detail = mddetail(device_info["path"]) - device_info["status"] = detail["State"]:upper() - - raid_devices[mdpath] = device_info - end - end - mdstat:close() - - return raid_devices -end - --- Collect Devices information - --[[ return: - { - sda={ - path, model, inuse, size_formated, - partitions={ - { name, inuse, size_formated } - ... - } - } - .. - } - --]] -d.list_devices = function() - local fs = require "nixio.fs" - - -- get all device names (sdX and mmcblkX) - local target_devnames = {} - for dev in fs.dir("/dev") do - if dev:match("^sd[a-z]$") - or dev:match("^mmcblk%d+$") - or dev:match("^sata[a-z]$") - or dev:match("^nvme%d+n%d+$") - then - table.insert(target_devnames, dev) - end - end - - local devices = {} - for i, bname in pairs(target_devnames) do - local device_info = {} - local device = "/dev/" .. bname - local size = tonumber(fs.readfile(string.format("/sys/class/block/%s/size", bname)) or "0") - local ss = tonumber(fs.readfile(string.format("/sys/class/block/%s/queue/logical_block_size", bname)) or "0") - local model = fs.readfile(string.format("/sys/class/block/%s/device/model", bname)) - local partitions = {} - for part in nixio.fs.glob("/sys/block/" .. bname .."/" .. bname .. "*") do - local pname = nixio.fs.basename(part) - local psize = byte_format(tonumber(nixio.fs.readfile(part .. "/size"))*ss) - local mount_point = get_mount_point(pname) - if mount_point then device_info["inuse"] = true end - table.insert(partitions, {name = pname, size_formated = psize, inuse = mount_point}) - end - - device_info["path"] = device - device_info["size_formated"] = byte_format(size*ss) - device_info["model"] = model - device_info["partitions"] = partitions - -- true or false - device_info["inuse"] = device_info["inuse"] or get_mount_point(bname) - - local udevinfo = {} - if luci.sys.exec("which udevadm") ~= "" then - local udevadm = io.popen("udevadm info --query=property --name="..device) - for attr in udevadm:lines() do - local k, v = attr:match("(%S+)=(%S+)") - udevinfo[k] = v - end - udevadm:close() - - device_info["info"] = udevinfo - if udevinfo["ID_MODEL"] then device_info["model"] = udevinfo["ID_MODEL"] end - end - devices[bname] = device_info - end - -- luci.util.perror(luci.util.serialize_json(devices)) - return devices -end - --- get formart cmd -d.get_format_cmd = function() - local AVAILABLE_FMTS = { - ext2 = { cmd = "mkfs.ext2", option = "-F -E lazy_itable_init=1" }, - ext3 = { cmd = "mkfs.ext3", option = "-F -E lazy_itable_init=1" }, - ext4 = { cmd = "mkfs.ext4", option = "-F -E lazy_itable_init=1" }, - fat32 = { cmd = "mkfs.vfat", option = "-F" }, - exfat = { cmd = "mkexfat", option = "-f" }, - hfsplus = { cmd = "mkhfs", option = "-f" }, - ntfs = { cmd = "mkntfs", option = "-f" }, - swap = { cmd = "mkswap", option = "" }, - btrfs = { cmd = "mkfs.btrfs", option = "-f" } - } - result = {} - for fmt, obj in pairs(AVAILABLE_FMTS) do - local cmd = luci.sys.exec("/usr/bin/which " .. obj["cmd"]) - if cmd:match(obj["cmd"]) then - result[fmt] = { cmd = cmd:match("^.+"..obj["cmd"]) ,option = obj["option"] } - end - end - return result -end - -d.create_raid = function(rname, rlevel, rmembers) - local mb = {} - for _, v in ipairs(rmembers) do - mb[v]=v - end - rmembers = {} - for _, v in pairs(mb) do - table.insert(rmembers, v) - end - if type(rname) == "string" then - if rname:match("^md%d-%s+") then - rname = "/dev/"..rname:match("^(md%d-)%s+") - elseif rname:match("^/dev/md%d-%s+") then - rname = "/dev/"..rname:match("^(/dev/md%d-)%s+") - elseif not rname:match("/") then - rname = "/dev/md/".. rname - else - return "ERR: Invalid raid name" - end - else - local mdnum = 0 - for num=1,127 do - local md = io.open("/dev/md"..tostring(num), "r") - if md == nil then - mdnum = num - break - else - io.close(md) - end - end - if mdnum == 0 then return "ERR: Cannot find proper md number" end - rname = "/dev/md"..mdnum - end - - if rlevel == "5" or rlevel == "6" then - if #rmembers < 3 then return "ERR: Not enough members" end - end - if rlevel == "10" then - if #rmembers < 4 then return "ERR: Not enough members" end - end - if #rmembers < 2 then return "ERR: Not enough members" end - local cmd = d.command.mdadm .. " --create "..rname.." --run --assume-clean --homehost=any --level=" .. rlevel .. " --raid-devices=" .. #rmembers .. " " .. table.concat(rmembers, " ") - local res = luci.util.exec(cmd) - return res -end - -d.gen_mdadm_config = function() - if not nixio.fs.access("/etc/config/mdadm") then return end - local uci = require "luci.model.uci" - local x = uci.cursor() - -- delete all array sections - x:foreach("mdadm", "array", function(s) x:delete("mdadm",s[".name"]) end) - local cmd = d.command.mdadm .. " -D -s" - --ARRAY /dev/md1 metadata=1.2 name=any:1 UUID=f998ae14:37621b27:5c49e850:051f6813 - --ARRAY /dev/md3 metadata=1.2 name=any:3 UUID=c068c141:4b4232ca:f48cbf96:67d42feb - for _, v in ipairs(luci.util.execl(cmd)) do - local device, uuid = v:match("^ARRAY%s-([^%s]+)%s-[^%s]-%s-[^%s]-%s-UUID=([^%s]+)%s-") - if device and uuid then - local section_name = x:add("mdadm", "array") - x:set("mdadm", section_name, "device", device) - x:set("mdadm", section_name, "uuid", uuid) - end - end - x:commit("mdadm") - -- enable mdadm - luci.util.exec("/etc/init.d/mdadm enable") -end - --- list btrfs filesystem device --- {uuid={uuid, label, members, size, used}...} -d.list_btrfs_devices = function() - local btrfs_device = {} - if not d.command.btrfs then return btrfs_device end - local line, _uuid - for _, line in ipairs(luci.util.execl(d.command.btrfs .. " filesystem show -d --raw")) - do - local label, uuid = line:match("^Label:%s+([^%s]+)%s+uuid:%s+([^%s]+)") - if label and uuid then - _uuid = uuid - local _label = label:match("^'([^']+)'") - btrfs_device[_uuid] = {label = _label or label, uuid = uuid} - -- table.insert(btrfs_device, {label = label, uuid = uuid}) - end - local used = line:match("Total devices[%w%s]+used%s+(%d+)$") - if used then - btrfs_device[_uuid]["used"] = tonumber(used) - btrfs_device[_uuid]["used_formated"] = byte_format(tonumber(used)) - end - local size, device = line:match("devid[%w.%s]+size%s+(%d+)[%w.%s]+path%s+([^%s]+)$") - if size and device then - btrfs_device[_uuid]["size"] = btrfs_device[_uuid]["size"] and btrfs_device[_uuid]["size"] + tonumber(size) or tonumber(size) - btrfs_device[_uuid]["size_formated"] = byte_format(btrfs_device[_uuid]["size"]) - btrfs_device[_uuid]["members"] = btrfs_device[_uuid]["members"] and btrfs_device[_uuid]["members"]..", "..device or device - end - end - return btrfs_device -end - -d.create_btrfs = function(blabel, blevel, bmembers) - -- mkfs.btrfs -L label -d blevel /dev/sda /dev/sdb - if not d.command.btrfs or type(bmembers) ~= "table" or next(bmembers) == nil then return "ERR no btrfs support or no members" end - local label = blabel and " -L " .. blabel or "" - local cmd = "mkfs.btrfs -f " .. label .. " -d " .. blevel .. " " .. table.concat(bmembers, " ") - return luci.util.exec(cmd) -end - --- get btrfs info --- {uuid, label, members, data_raid_level,metadata_raid_lavel, size, used, size_formated, used_formated, free, free_formated, usage} -d.get_btrfs_info = function(m_point) - local btrfs_info = {} - if not m_point or not d.command.btrfs then return btrfs_info end - local cmd = d.command.btrfs .. " filesystem show --raw " .. m_point - local _, line, uuid, _label, members - for _, line in ipairs(luci.util.execl(cmd)) do - if not uuid and not _label then - _label, uuid = line:match("^Label:%s+([^%s]+)%s+uuid:%s+([^s]+)") - else - local mb = line:match("%s+devid.+path%s+([^%s]+)") - if mb then - members = members and (members .. ", ".. mb) or mb - end - end - end - - if not _label or not uuid then return btrfs_info end - local label = _label:match("^'([^']+)'") - cmd = d.command.btrfs .. " filesystem usage -b " .. m_point - local used, free, data_raid_level, metadata_raid_lavel - for _, line in ipairs(luci.util.execl(cmd)) do - if not used then - used = line:match("^%s+Used:%s+(%d+)") - elseif not free then - free = line:match("^%s+Free %(estimated%):%s+(%d+)") - elseif not data_raid_level then - data_raid_level = line:match("^Data,%s-(%w+)") - elseif not metadata_raid_lavel then - metadata_raid_lavel = line:match("^Metadata,%s-(%w+)") - end - end - if used and free and data_raid_level and metadata_raid_lavel then - used = tonumber(used) - free = tonumber(free) - btrfs_info = { - uuid = uuid, - label = label, - data_raid_level = data_raid_level, - metadata_raid_lavel = metadata_raid_lavel, - used = used, - free = free, - size = used + free, - size_formated = byte_format(used + free), - used_formated = byte_format(used), - free_formated = byte_format(free), - members = members, - usage = string.format("%.2f",(used / (free+used) * 100)) .. "%" - } - end - return btrfs_info -end - --- get btrfs subvolume --- {id={id, gen, top_level, path, snapshots, otime, default_subvolume}...} -d.get_btrfs_subv = function(m_point, snapshot) -local subvolume = {} -if not m_point or not d.command.btrfs then return subvolume end - --- get default subvolume -local cmd = d.command.btrfs .. " subvolume get-default " .. m_point -local res = luci.util.exec(cmd) -local default_subvolume_id = res:match("^ID%s+([^%s]+)") - --- get the root subvolume -if not snapshot then - local _, line, section_snap, _uuid, _otime, _id, _snap - cmd = d.command.btrfs .. " subvolume show ".. m_point - for _, line in ipairs(luci.util.execl(cmd)) do - if not section_snap then - if not _uuid then - _uuid = line:match("^%s-UUID:%s+([^%s]+)") - elseif not _otime then - _otime = line:match("^%s+Creation time:%s+(.+)") - elseif not _id then - _id = line:match("^%s+Subvolume ID:%s+([^%s]+)") - elseif line:match("^%s+(Snapshot%(s%):)") then - section_snap = true - end - else - local snapshot = line:match("^%s+(.+)") - if snapshot then - _snap = _snap and (_snap ..", /".. snapshot) or ("/"..snapshot) - end - end - end - if _uuid and _otime and _id then - subvolume["0".._id] = {id = _id , uuid = _uuid, otime = _otime, snapshots = _snap, path = "/"} - if default_subvolume_id == _id then - subvolume["0".._id].default_subvolume = 1 - end - end -end - --- get subvolume of btrfs -cmd = d.command.btrfs .. " subvolume list -gcu" .. (snapshot and "s " or " ") .. m_point -for _, line in ipairs(luci.util.execl(cmd)) do - -- ID 259 gen 11 top level 258 uuid 26ae0c59-199a-cc4d-bd58-644eb4f65d33 path 1a/2b' - local id, gen, top_level, uuid, path, otime, otime2 - if snapshot then - id, gen, top_level, otime, otime2, uuid, path = line:match("^ID%s+([^%s]+)%s+gen%s+([^%s]+)%s+cgen.-top level%s+([^%s]+)%s+otime%s+([^%s]+)%s+([^%s]+)%s+uuid%s+([^%s]+)%s+path%s+([^%s]+)%s-$") - else - id, gen, top_level, uuid, path = line:match("^ID%s+([^%s]+)%s+gen%s+([^%s]+)%s+cgen.-top level%s+([^%s]+)%s+uuid%s+([^%s]+)%s+path%s+([^%s]+)%s-$") - end - if id and gen and top_level and uuid and path then - subvolume[id] = {id = id, gen = gen, top_level = top_level, otime = (otime and otime or "") .." ".. (otime2 and otime2 or ""), uuid = uuid, path = '/'.. path} - if not snapshot then - -- use btrfs subv show to get snapshots - local show_cmd = d.command.btrfs .. " subvolume show "..m_point.."/"..path - local __, line_show, section_snap - for __, line_show in ipairs(luci.util.execl(show_cmd)) do - if not section_snap then - local create_time = line_show:match("^%s+Creation time:%s+(.+)") - if create_time then - subvolume[id]["otime"] = create_time - elseif line_show:match("^%s+(Snapshot%(s%):)") then - section_snap = "true" - end - else - local snapshot = line_show:match("^%s+(.+)") - subvolume[id]["snapshots"] = subvolume[id]["snapshots"] and (subvolume[id]["snapshots"] .. ", /".. snapshot) or ("/"..snapshot) - end - end - end - end -end -if subvolume[default_subvolume_id] then - subvolume[default_subvolume_id].default_subvolume = 1 -end --- if m_point == "/tmp/.btrfs_tmp" then --- luci.util.exec("umount " .. m_point) --- end -return subvolume -end - -d.format_partition = function(partition, fs) - local partition_name = "/dev/".. partition - if not nixio.fs.access(partition_name) then - return 500, "Partition NOT found!" - end - - local format_cmd = d.get_format_cmd() - if not format_cmd[fs] then - return 500, "Filesystem NOT support!" - end - local cmd = format_cmd[fs].cmd .. " " .. format_cmd[fs].option .. " " .. partition_name - local res = luci.util.exec(cmd .. " 2>&1") - if res and res:lower():match("error+") then - return 500, res - else - return 200, "OK" - end -end - -return d diff --git a/luci-app-diskman/luasrc/view/diskman/cbi/disabled_button.htm b/luci-app-diskman/luasrc/view/diskman/cbi/disabled_button.htm deleted file mode 100755 index 1ad4eca3b..000000000 --- a/luci-app-diskman/luasrc/view/diskman/cbi/disabled_button.htm +++ /dev/null @@ -1,7 +0,0 @@ -<%+cbi/valueheader%> - <% if self:cfgvalue(section) ~= false then %> - " type="submit"<%= attr("name", cbid) .. attr("id", cbid) .. attr("value", self.inputtitle or self.title)%> <% if self.view_disabled then %> disabled <% end %>/> - <% else %> - - - <% end %> -<%+cbi/valuefooter%> \ No newline at end of file diff --git a/luci-app-diskman/luasrc/view/diskman/cbi/format_button.htm b/luci-app-diskman/luasrc/view/diskman/cbi/format_button.htm deleted file mode 100755 index 18e306e27..000000000 --- a/luci-app-diskman/luasrc/view/diskman/cbi/format_button.htm +++ /dev/null @@ -1,7 +0,0 @@ -<%+cbi/valueheader%> - <% if self:cfgvalue(section) ~= false then %> - " onclick="event.preventDefault();partition_format('<%=self.partitions[section].name%>', '<%=self.format_cmd%>', '<%=self.inputtitle%>');" type="submit"<%= attr("name", cbid) .. attr("id", cbid) .. attr("value", self.inputtitle or self.title)%> <% if self.view_disabled then %> disabled <% end %>/> - <% else %> - - - <% end %> -<%+cbi/valuefooter%> diff --git a/luci-app-diskman/luasrc/view/diskman/cbi/inlinebutton.htm b/luci-app-diskman/luasrc/view/diskman/cbi/inlinebutton.htm deleted file mode 100755 index b1b193257..000000000 --- a/luci-app-diskman/luasrc/view/diskman/cbi/inlinebutton.htm +++ /dev/null @@ -1,7 +0,0 @@ -
- <% if self:cfgvalue(section) ~= false then %> - " type="submit"" <% if self.disable then %>disabled <% end %><%= attr("name", cbid) .. attr("id", cbid) .. attr("value", self.inputtitle or self.title)%> /> - <% else %> - - - <% end %> -
diff --git a/luci-app-diskman/luasrc/view/diskman/cbi/xnullsection.htm b/luci-app-diskman/luasrc/view/diskman/cbi/xnullsection.htm deleted file mode 100755 index 69aa65e00..000000000 --- a/luci-app-diskman/luasrc/view/diskman/cbi/xnullsection.htm +++ /dev/null @@ -1,37 +0,0 @@ -
- <% if self.title and #self.title > 0 then -%> - <%=self.title%> - <%- end %> - <% if self.description and #self.description > 0 then -%> -
<%=self.description%>
- <%- end %> -
-
- <% self:render_children(1, scope or {}) %> -
- <% if self.error and self.error[1] then -%> -
-
    <% for _, e in ipairs(self.error[1]) do -%> -
  • - <%- if e == "invalid" then -%> - <%:One or more fields contain invalid values!%> - <%- elseif e == "missing" then -%> - <%:One or more required fields have no value!%> - <%- else -%> - <%=pcdata(e)%> - <%- end -%> -
  • - <%- end %>
-
- <%- end %> -
-
-<%- - if type(self.hidden) == "table" then - for k, v in pairs(self.hidden) do --%> - -<%- - end - end -%> \ No newline at end of file diff --git a/luci-app-diskman/luasrc/view/diskman/cbi/xsimpleform.htm b/luci-app-diskman/luasrc/view/diskman/cbi/xsimpleform.htm deleted file mode 100755 index a831bfc77..000000000 --- a/luci-app-diskman/luasrc/view/diskman/cbi/xsimpleform.htm +++ /dev/null @@ -1,88 +0,0 @@ -<% if not self.embedded then %> -
> - - - <% - end - - %>
<% - - if self.title and #self.title > 0 then - %>

<%=self.title%>

<% - end - - if self.description and #self.description > 0 then - %>
<%=self.description%>
<% - end - - self:render_children() - - %>
<% - - if self.message then - %>
<%=self.message%>
<% - end - - if self.errmessage then - %>
<%=self.errmessage%>
<% - end - - if not self.embedded then - if type(self.hidden) == "table" then - local k, v - for k, v in pairs(self.hidden) do - %><% - end - end - - local display_back = (self.redirect) - local display_cancel = (self.cancel ~= false and self.on_cancel) - local display_skip = (self.flow and self.flow.skip) - local display_submit = (self.submit ~= false) - local display_reset = (self.reset ~= false) - - if display_back or display_cancel or display_skip or display_submit or display_reset then - %>
<% - - if display_back then - %> <% - end - - if display_cancel then - local label = pcdata(self.cancel or translate("Cancel")) - %> <% - end - - if display_skip then - %> <% - end - - if display_submit then - local label = pcdata(self.submit or translate("Submit")) - %> <% - end - - if display_reset then - local label = pcdata(self.reset or translate("Reset")) - %> <% - end - - %>
<% - end - - %>
<% - end -%> - - diff --git a/luci-app-diskman/luasrc/view/diskman/disk_info.htm b/luci-app-diskman/luasrc/view/diskman/disk_info.htm deleted file mode 100755 index 118acd50d..000000000 --- a/luci-app-diskman/luasrc/view/diskman/disk_info.htm +++ /dev/null @@ -1,108 +0,0 @@ - diff --git a/luci-app-diskman/luasrc/view/diskman/partition_info.htm b/luci-app-diskman/luasrc/view/diskman/partition_info.htm deleted file mode 100755 index 78f5c1bd7..000000000 --- a/luci-app-diskman/luasrc/view/diskman/partition_info.htm +++ /dev/null @@ -1,129 +0,0 @@ - - \ No newline at end of file diff --git a/luci-app-diskman/luasrc/view/diskman/smart_detail.htm b/luci-app-diskman/luasrc/view/diskman/smart_detail.htm deleted file mode 100755 index 56a9139f0..000000000 --- a/luci-app-diskman/luasrc/view/diskman/smart_detail.htm +++ /dev/null @@ -1,79 +0,0 @@ - - - S.M.A.R.T detail of <%=dev%> - - - - -
-
- <%:S.M.A.R.T Attrbutes%>: /dev/<%=dev%> - - - <% if dev:match("nvme") then %> - - <% else %> - - - - - - - - - - <% end %> - - - - -
<%:ID%><%:Attrbute%><%:Flag%><%:Value%><%:Worst%><%:Thresh%><%:Type%><%:Updated%><%:Raw%>

<%:Collecting data...%>
-
-
- - \ No newline at end of file diff --git a/luci-app-diskman/po/zh-cn/diskman.po b/luci-app-diskman/po/zh-cn/diskman.po deleted file mode 100755 index f380fc586..000000000 --- a/luci-app-diskman/po/zh-cn/diskman.po +++ /dev/null @@ -1,239 +0,0 @@ -msgid "" -msgstr "Content-Type: text/plain; charset=UTF-8\n" - -msgid "DiskMan" -msgstr "DiskMan 磁盘管理" - -msgid "Manage Disks over LuCI." -msgstr "通过 LuCI 管理磁盘" - -msgid "Rescan Disks" -msgstr "重新扫描磁盘" - -msgid "Disks" -msgstr "磁盘" - -msgid "Path" -msgstr "路径" - -msgid "Serial Number" -msgstr "序列号" - -msgid "Temp" -msgstr "温度" - -msgid "Partition Table" -msgstr "分区表" - -msgid "SATA Version" -msgstr "SATA 版本" - -msgid "Health" -msgstr "健康" - -msgid "File System" -msgstr "文件系统" - -msgid "Mount Options" -msgstr "挂载选项" - -msgid "Mount" -msgstr "挂载" - -msgid "Umount" -msgstr "卸载" - -msgid "Eject" -msgstr "弹出" - -msgid "New" -msgstr "创建" - -msgid "Remove" -msgstr "移除" - -msgid "Format" -msgstr "格式化" - -msgid "Start Sector" -msgstr "起始扇区" - -msgid "End Sector" -msgstr "中止扇区" - -msgid "Usage" -msgstr "用量" - -msgid "Used" -msgstr "已使用" - -msgid "Free Space" -msgstr "空闲空间" - -msgid "Model" -msgstr "型号" - -msgid "Size" -msgstr "容量" - -msgid "Status" -msgstr "状态" - -msgid "Mount Point" -msgstr "挂载点" - -msgid "Sector Size" -msgstr "扇区/物理扇区大小" - -msgid "Rotation Rate" -msgstr "转速" - -msgid "RAID Devices" -msgstr "RAID 设备" - -msgid "RAID mode" -msgstr "RAID 模式" - -msgid "Members" -msgstr "成员" - -msgid "Active" -msgstr "活动" - -msgid "RAID Creation" -msgstr "RAID 创建" - -msgid "Raid Name" -msgstr "RAID 名称" - -msgid "Raid Level" -msgstr "RAID 级别" - -msgid "Raid Member" -msgstr "磁盘阵列成员" - -msgid "Create Raid" -msgstr "创建 RAID" - -msgid "Partition Management" -msgstr "分区管理" - -msgid "Partition Disk over LuCI." -msgstr "通过LuCI分区磁盘。" - -msgid "Device Info" -msgstr "设备信息" - -msgid "Disk Man" -msgstr "磁盘管理" - -msgid "Partitions Info" -msgstr "分区信息" - -msgid "Default 2048 sector alignment, support +size{b,k,m,g,t} in End Sector" -msgstr "默认2048扇区对齐,【中止扇区】支持 +容量{b,k,m,g,t} 格式,例:+500m +10g +1t" - -msgid "Multiple Devices Btrfs Creation" -msgstr "Btrfs 阵列创建" - -msgid "Label" -msgstr "卷标" - -msgid "Btrfs Label" -msgstr "Btrfs 卷标" - -msgid "Btrfs Raid Level" -msgstr "Btrfs Raid 级别" - -msgid "Btrfs Member" -msgstr "Btrfs 整列成员" - -msgid "Create Btrfs" -msgstr "创建 Btrfs" - -msgid "New Snapshot" -msgstr "新建快照" - -msgid "SubVolumes" -msgstr "子卷" - -msgid "Top Level" -msgstr "父ID" - -msgid "Manage Btrfs" -msgstr "Btrfs 管理" - -msgid "Otime" -msgstr "创建时间" - -msgid "Snapshots" -msgstr "快照" - -msgid "Set Default" -msgstr "默认子卷" - -msgid "Source Path" -msgstr "源目录" - -msgid "Readonly" -msgstr "只读" - -msgid "Delete" -msgstr "删除" - -msgid "Create" -msgstr "创建" - -msgid "Destination Path (optional)" -msgstr "目标目录(可选)" - -msgid "Metadata" -msgstr "元数据" - -msgid "Data" -msgstr "数据" - -msgid "Btrfs Info" -msgstr "Btrfs 信息" - -msgid "The source path for create the snapshot" -msgstr "创建快照的源数据目录" - -msgid "The path where you want to store the snapshot" -msgstr "存放快照数据目录" - -msgid "Please input Source Path of snapshot, Source Path must start with '/'" -msgstr "请输入快照源路径,源路径必须以'/'开头" - -msgid "Please input Subvolume Path, Subvolume must start with '/'" -msgstr "请输入子卷路径,子卷路径必须以'/'开头" - -msgid "is in use! please unmount it first!" -msgstr "正在被使用!请先卸载!" - -msgid "Partition NOT found!" -msgstr "分区未找到!" - -msgid "Filesystem NOT support!" -msgstr "文件系统不支持!" - -msgid "Invalid Start Sector!" -msgstr "无效的起始扇区!" - -msgid "Invalid End Sector" -msgstr "无效的终止扇区!" - -msgid "Partition not exists!" -msgstr "分区不存在!" - -msgid "Creation" -msgstr "创建" - -msgid "Please select file system!" -msgstr "请选择文件系统!" - -msgid "Format partation:" -msgstr "格式化分区:" - -msgid "Warnning !! \nTHIS WILL OVERWRITE EXISTING PARTITIONS!! \nModify the partition table?" -msgstr "警告!!\n此操作会覆盖现有分区\n确定修改分区表?" diff --git a/luci-app-diskman/po/zh_Hans b/luci-app-diskman/po/zh_Hans deleted file mode 100755 index 41451e4a1..000000000 --- a/luci-app-diskman/po/zh_Hans +++ /dev/null @@ -1 +0,0 @@ -zh-cn \ No newline at end of file diff --git a/luci-app-dockerman/Makefile b/luci-app-dockerman/Makefile deleted file mode 100755 index 51dfa5c09..000000000 --- a/luci-app-dockerman/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -include $(TOPDIR)/rules.mk - -LUCI_TITLE:=LuCI Support for docker -LUCI_DEPENDS:=@(aarch64||arm||x86_64) \ - +luci-compat \ - +luci-lib-docker \ - +luci-lib-ip \ - +docker \ - +dockerd \ - +ttyd -LUCI_PKGARCH:=all - -PKG_LICENSE:=AGPL-3.0 -PKG_MAINTAINER:=lisaac \ - Florian Eckert - -PKG_VERSION:=v0.5.25 - -include $(TOPDIR)/feeds/luci/luci.mk - -# call BuildPackage - OpenWrt buildroot signature diff --git a/luci-app-dockerman/depends.lst b/luci-app-dockerman/depends.lst deleted file mode 100755 index 8a62f6a74..000000000 --- a/luci-app-dockerman/depends.lst +++ /dev/null @@ -1 +0,0 @@ -ttyd docker-cli \ No newline at end of file diff --git a/luci-app-dockerman/htdocs/luci-static/resources/dockerman/containers.svg b/luci-app-dockerman/htdocs/luci-static/resources/dockerman/containers.svg deleted file mode 100755 index 4165f90bd..000000000 --- a/luci-app-dockerman/htdocs/luci-static/resources/dockerman/containers.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - Docker icon - - diff --git a/luci-app-dockerman/htdocs/luci-static/resources/dockerman/file-icon.png b/luci-app-dockerman/htdocs/luci-static/resources/dockerman/file-icon.png deleted file mode 100755 index f156dc1c7ce823b64401a62e249a377a52b20518..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1098 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H3?#oinD~={fiXV7C&U%V9R;)t0gq*U=0MX+ zN`m}?85o(ESyC4w|-+%u4`_J-}sTczTlbWZCV@SoVw>LwB4?74P_~>1@e8=wH z&fU=qckC8l&g%8~Z~JzK84Nd5-}BA*yTAO~_e*zul#cA)^xP@%bNkV}@@1=Sm_nnE zsJyDOVK&^ans!Nao=4-k^E=Evcdue#I_C3e(OiQAVx|XrN*fszgEv38bVX+ZBLk<7 zgTLLX>}*a2RcCnDxd+V)Vr>uTRp^EDZ{YS5zRLWD zX+K+oZ^7&}j0wVDUNLYaA7pxy&DgP{)_cNgRs|`Y0}Vb07X9Dsw#Gcb+lVpm)>U4M z$qW{)40rHDoarZKhfLm@t>etnLD$M)VPGsasI53}8!m{U0}y(IC{&iZ7U@Z(z4w(uZ zdD~j}0zR}v9-Sy-)WBcf^Xq4217k{qqRfJRo(bPOX3BrNq`T>@q1(e(-elb6Mw<&;$T^(=;mp diff --git a/luci-app-dockerman/htdocs/luci-static/resources/dockerman/file-manager.css b/luci-app-dockerman/htdocs/luci-static/resources/dockerman/file-manager.css deleted file mode 100755 index 911693b62..000000000 --- a/luci-app-dockerman/htdocs/luci-static/resources/dockerman/file-manager.css +++ /dev/null @@ -1,91 +0,0 @@ -.fb-container { - margin-top: 1rem; -} -.fb-container .cbi-button { - height: 1.8rem; -} -.fb-container .cbi-input-text { - margin-bottom: 1rem; - width: 100%; -} -.fb-container .panel-title { - padding-bottom: 0; - width: 50%; - border-bottom: none; -} -.fb-container .panel-container { - display: flex; - align-items: center; - justify-content: space-between; - padding-bottom: 1rem; - border-bottom: 1px solid #eee; -} -.fb-container .upload-container { - display: none; - margin: 1rem 0; -} -.fb-container .upload-file { - margin-right: 2rem; -} -.fb-container .cbi-value-field { - text-align: left; -} -.fb-container .parent-icon strong { - margin-left: 1rem; -} -.fb-container td[class$="-icon"] { - cursor: pointer; -} -.fb-container .file-icon, .fb-container .folder-icon, .fb-container .link-icon { - position: relative; -} -.fb-container .file-icon:before, .fb-container .folder-icon:before, .fb-container .link-icon:before { - display: inline-block; - width: 1.5rem; - height: 1.5rem; - content: ''; - background-size: contain; - margin: 0 0.5rem 0 1rem; - vertical-align: middle; -} -.fb-container .file-icon:before { - background-image: url(file-icon.png); -} -.fb-container .folder-icon:before { - background-image: url(folder-icon.png); -} -.fb-container .link-icon:before { - background-image: url(link-icon.png); -} -@media screen and (max-width: 480px) { - .fb-container .upload-file { - width: 14.6rem; - } - .fb-container .cbi-value-owner, - .fb-container .cbi-value-perm { - display: none; - } -} - -.cbi-section-table { - width: 100%; -} - -.cbi-section-table-cell { - text-align: right; -} - -.cbi-button-install { -border-color: #c44; - color: #c44; - margin-left: 3px; -} - -.cbi-value-field { - padding: 10px 0; -} - -.parent-icon { - height: 1.8rem; - padding: 10px 0; -} \ No newline at end of file diff --git a/luci-app-dockerman/htdocs/luci-static/resources/dockerman/folder-icon.png b/luci-app-dockerman/htdocs/luci-static/resources/dockerman/folder-icon.png deleted file mode 100755 index 1370df3ad554fcb4d11aa0a72510dd3011cb816b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1292 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H3?#oinD~={fpJ5CPlzj!I|_zS2>kviS_E`% ze@T#EFaskKGYcy_2PYRdFCV{vkf@Z5tfH!#x`w8fw!Wc}v8kDbjjg?lo4bdnkDq@~ zNLWNlrlO|7@I&aaqIS-d-oqce)9C$^A|5)y?Oio-m(|)^6tj@ffbcxT$swdA#S9dDM(%YwA z=;`}t7X5o_cb4ab+U_%F*2&+yf4uTu`aSv6Ja0aq(Nkn#*l^0gUv=J|pA)vGDNXH| z5%v0TKlc`43d@{VRt#TOUdn344I z@hKL)O`5@Fmn5gzE%#Z_?rWK(J~!oMUO$Ulc&~%n!wIve^Uc&^UG?bc&k5U^ru=(j z@`QzLrH*H?*MqJt41c#ox+Tos!|->br&GfhO@k9=UK}j*vdPWQ;8$FBYF>a>4u(+{}*QfsHlKk>Zp>C@i+ z=-vG8o4>hkyxc=p^WV?EPtm_nYx(`x^Fv|LOMcFc{wo~4#ynGFUisp>jo<(Kx0>Jm zv2ORj?3$<7m1}nIe$U6#pOIMcz^`O^KR5$71pQ;2AX!`B8su&V67Y2Ob6Mw<&;$S{ CYKQCq diff --git a/luci-app-dockerman/htdocs/luci-static/resources/dockerman/images.svg b/luci-app-dockerman/htdocs/luci-static/resources/dockerman/images.svg deleted file mode 100755 index 90ca5a1c7..000000000 --- a/luci-app-dockerman/htdocs/luci-static/resources/dockerman/images.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - diff --git a/luci-app-dockerman/htdocs/luci-static/resources/dockerman/link-icon.png b/luci-app-dockerman/htdocs/luci-static/resources/dockerman/link-icon.png deleted file mode 100755 index 03cc82cdfabae20c1036959e6244ba5039f74697..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1622 zcmV-c2C4apP) zTWB0r7{`CvG(@YF+Ik_0m)2IR7C|eeQV{DEMU;wAE9isZi=a^9kCznM9+=gj%O9~|iA?Ch8G|LvKX zvojMgeDf4=0GI-r5w@eiYrtSt1E87hgb!HSz5)jOD;Wlz+y%TJx`-UC0475hkrF!y z|EbQ~jx;J63Y}aZx_|<#Gy(i^GIRk&FaiAWLFfXCUp~Y|grgsLkMIX~ z;?`HLNi`mIEI~P-w`uS~5@_sDlIxvK}}VL6M_I9?R1z#|E36NA7Z}R<1N{Sh4(!8SZE_Zv$+?YKISw53yv=Fgxz?YfS}b~!eD<6M zUIvzgC^i9NnF#<`1RT!sqAzf}3!@y@68?A#fUP-Rup1cgJrW8T0e&Wu8Q@D{=g)An zg;9=J!fyf$;||)obvywqt6(s+5mWe0fM_pZ#`C~v zpbp_T8^|u;oGv&BT8Vzz&#)Uq{8MH4XMJzb1n|o+)rEhkwO#LbAWQZYKCXyKonflm z=l{g{FW-EBi)aFPpjY8%_>{l|C`qrw&+sLI2~dJi;b-`ezyv5r=qGj$KYod<9td;+`)+|mA@Ccs=$3co8R zz=fy^A54ID)P)ZwK!(cj!2|%s;e!dFI(*PAfco%3uK*T)3ylI;_-$wtpvv$^sag1- zOMoFP{5fb5z`~yg4FXvB3y``17Je5}7Qn(6kg5O{zK|3Ju<&z`ngAAlPErye_V5=2 zdw{79+n)kH0xl}~9=SFI|p1p)eSSG!gf{{8p~KT1*%U@6r+$1wTuAq@fk!ri&!6BXe@8Ui$d&A4Cm>;pC7 zLmC1Ai~;vjUIJC&LplOLc?r~o4`~Si#U)S~KBOlAiUmAeTUO_>isu&|L!c z;X~R2!2A+e_$^Ww0M1J=*82N5Sor^=<(EK?0c&wz$9jL}ex1=U17tL@@aLdO0HXsY zfO1R#<(L4P>u0=T5&T2kj}++9rF zkmTW&Ey!+=+&13^jILY^9HaXf|B6f!uUrnC6BKs_+0Bi{T;4$TA=?qEz)yt*{s1fq zRAXJ)jQlqAdji$S!@>faz+UXMP|9P#zsR3K(DUg(qYwDLOM&fe9Jn(`rS)I{compN zKBilPRNBTS@;x?vm_@O**oj05{{=dgd% - - - - - - - - - - - diff --git a/luci-app-dockerman/htdocs/luci-static/resources/dockerman/tar.min.js b/luci-app-dockerman/htdocs/luci-static/resources/dockerman/tar.min.js deleted file mode 100755 index d9c06667f..000000000 --- a/luci-app-dockerman/htdocs/luci-static/resources/dockerman/tar.min.js +++ /dev/null @@ -1,185 +0,0 @@ -// https://github.com/thiscouldbebetter/TarFileExplorer -class TarFileTypeFlag -{constructor(value,name) -{this.value=value;this.id="_"+this.value;this.name=name;} -static _instances;static Instances() -{if(TarFileTypeFlag._instances==null) -{TarFileTypeFlag._instances=new TarFileTypeFlag_Instances();} -return TarFileTypeFlag._instances;}} -class TarFileTypeFlag_Instances -{constructor() -{this.Normal=new TarFileTypeFlag("0","Normal");this.HardLink=new TarFileTypeFlag("1","Hard Link");this.SymbolicLink=new TarFileTypeFlag("2","Symbolic Link");this.CharacterSpecial=new TarFileTypeFlag("3","Character Special");this.BlockSpecial=new TarFileTypeFlag("4","Block Special");this.Directory=new TarFileTypeFlag("5","Directory");this.FIFO=new TarFileTypeFlag("6","FIFO");this.ContiguousFile=new TarFileTypeFlag("7","Contiguous File");this.LongFilePath=new TarFileTypeFlag("L","././@LongLink");this._All=[this.Normal,this.HardLink,this.SymbolicLink,this.CharacterSpecial,this.BlockSpecial,this.Directory,this.FIFO,this.ContiguousFile,this.LongFilePath,];for(var i=0;ia+=String.fromCharCode(b),"");entryNext.header.fileName=entryNext.header.fileName.replace(/\0/g,"");entries.splice(i,1);i--;}}} -downloadAs(fileNameToSaveAs) -{return FileHelper.saveBytesAsFile -(this.toBytes(),fileNameToSaveAs)} -entriesForDirectories() -{return this.entries.filter(x=>x.header.typeFlag.name==TarFileTypeFlag.Instances().Directory);} -toBytes() -{this.toBytes_PrependLongPathEntriesAsNeeded();var fileAsBytes=[];var entriesAsByteArrays=this.entries.map(x=>x.toBytes());this.consolidateLongPathEntries();for(var i=0;imaxLength) -{var entryFileNameAsBytes=entryFileName.split("").map(x=>x.charCodeAt(0));var entryContainingLongPathToPrepend=TarFileEntry.fileNew -(typeFlagLongPath.name,entryFileNameAsBytes);entryContainingLongPathToPrepend.header.typeFlag=typeFlagLongPath;entryContainingLongPathToPrepend.header.timeModifiedInUnixFormat=entryHeader.timeModifiedInUnixFormat;entryContainingLongPathToPrepend.header.checksumCalculate();entryHeader.fileName=entryFileName.substr(0,maxLength)+String.fromCharCode(0);entries.splice(i,0,entryContainingLongPathToPrepend);i++;}}} -toString() -{var newline="\n";var returnValue="[TarFile]"+newline;for(var i=0;i{var fileLoadedAsBinaryString=fileLoadedEvent.target.result;var fileLoadedAsBytes=ByteHelper.stringUTF8ToBytes(fileLoadedAsBinaryString);callback(fileToLoad.name,fileLoadedAsBytes);} -fileReader.readAsBinaryString(fileToLoad);} -static loadFileAsText(fileToLoad,callback) -{var fileReader=new FileReader();fileReader.onload=(fileLoadedEvent)=>{var textFromFileLoaded=fileLoadedEvent.target.result;callback(fileToLoad.name,textFromFileLoaded);};fileReader.readAsText(fileToLoad);} -static saveBytesAsFile(bytesToWrite,fileNameToSaveAs) -{var bytesToWriteAsArrayBuffer=new ArrayBuffer(bytesToWrite.length);var bytesToWriteAsUIntArray=new Uint8Array(bytesToWriteAsArrayBuffer);for(var i=0;i - - - - - diff --git a/luci-app-dockerman/luasrc/controller/dockerman.lua b/luci-app-dockerman/luasrc/controller/dockerman.lua deleted file mode 100755 index 7aeed56e1..000000000 --- a/luci-app-dockerman/luasrc/controller/dockerman.lua +++ /dev/null @@ -1,614 +0,0 @@ ---[[ -LuCI - Lua Configuration Interface -Copyright 2019 lisaac -]]-- - -local docker = require "luci.model.docker" --- local uci = (require "luci.model.uci").cursor() - -module("luci.controller.dockerman",package.seeall) - -function index() - entry({"admin", "docker"}, - alias("admin", "docker", "config"), - _("Docker"), - 40).acl_depends = { "luci-app-dockerman" } - - entry({"admin", "docker", "config"},cbi("dockerman/configuration"),_("Configuration"), 8).leaf=true - - -- local uci = (require "luci.model.uci").cursor() - -- if uci:get_bool("dockerd", "dockerman", "remote_endpoint") then - -- local host = uci:get("dockerd", "dockerman", "remote_host") - -- local port = uci:get("dockerd", "dockerman", "remote_port") - -- if not host or not port then - -- return - -- end - -- else - -- local socket = uci:get("dockerd", "dockerman", "socket_path") or "/var/run/docker.sock" - -- if socket and not nixio.fs.access(socket) then - -- return - -- end - -- end - - -- if (require "luci.model.docker").new():_ping().code ~= 200 then - -- return - -- end - - entry({"admin", "docker", "overview"}, form("dockerman/overview"),_("Overview"), 2).leaf=true - entry({"admin", "docker", "containers"}, form("dockerman/containers"), _("Containers"), 3).leaf=true - entry({"admin", "docker", "images"}, form("dockerman/images"), _("Images"), 4).leaf=true - entry({"admin", "docker", "networks"}, form("dockerman/networks"), _("Networks"), 5).leaf=true - entry({"admin", "docker", "volumes"}, form("dockerman/volumes"), _("Volumes"), 6).leaf=true - entry({"admin", "docker", "events"}, call("action_events"), _("Events"), 7) - - entry({"admin", "docker", "newcontainer"}, form("dockerman/newcontainer")).leaf=true - entry({"admin", "docker", "newnetwork"}, form("dockerman/newnetwork")).leaf=true - entry({"admin", "docker", "container"}, form("dockerman/container")).leaf=true - - entry({"admin", "docker", "container_stats"}, call("action_get_container_stats")).leaf=true - entry({"admin", "docker", "containers_stats"}, call("action_get_containers_stats")).leaf=true - entry({"admin", "docker", "get_system_df"}, call("action_get_system_df")).leaf=true - entry({"admin", "docker", "container_get_archive"}, call("download_archive")).leaf=true - entry({"admin", "docker", "container_put_archive"}, call("upload_archive")).leaf=true - entry({"admin", "docker", "container_list_file"}, call("list_file")).leaf=true - entry({"admin", "docker", "container_remove_file"}, call("remove_file")).leaf=true - entry({"admin", "docker", "container_rename_file"}, call("rename_file")).leaf=true - entry({"admin", "docker", "container_export"}, call("export_container")).leaf=true - entry({"admin", "docker", "images_save"}, call("save_images")).leaf=true - entry({"admin", "docker", "images_load"}, call("load_images")).leaf=true - entry({"admin", "docker", "images_import"}, call("import_images")).leaf=true - entry({"admin", "docker", "images_get_tags"}, call("get_image_tags")).leaf=true - entry({"admin", "docker", "images_tag"}, call("tag_image")).leaf=true - entry({"admin", "docker", "images_untag"}, call("untag_image")).leaf=true - entry({"admin", "docker", "confirm"}, call("action_confirm")).leaf=true -end - -function action_get_system_df() - local res = docker.new():df() - luci.http.status(res.code, res.message) - luci.http.prepare_content("application/json") - luci.http.write_json(res.body) -end - -function scandir(id, directory) - local cmd_docker = luci.util.exec("command -v docker"):match("^.+docker") or nil - if not cmd_docker or cmd_docker:match("^%s+$") then - return - end - local i, t, popen = 0, {}, io.popen - local uci = (require "luci.model.uci").cursor() - local remote = uci:get_bool("dockerd", "dockerman", "remote_endpoint") - local socket_path = not remote and uci:get("dockerd", "dockerman", "socket_path") or nil - local host = remote and uci:get("dockerd", "dockerman", "remote_host") or nil - local port = remote and uci:get("dockerd", "dockerman", "remote_port") or nil - if remote and host and port then - hosts = "tcp://" .. host .. ':'.. port - elseif socket_path then - hosts = "unix://" .. socket_path - else - return - end - local pfile = popen(cmd_docker .. ' -H "'.. hosts ..'" exec ' ..id .." ls -lh \""..directory.."\" | egrep -v '^total'") - for fileinfo in pfile:lines() do - i = i + 1 - t[i] = fileinfo - end - pfile:close() - return t -end - -function list_response(id, path, success) - luci.http.prepare_content("application/json") - local result - if success then - local rv = scandir(id, path) - result = { - ec = 0, - data = rv - } - else - result = { - ec = 1 - } - end - luci.http.write_json(result) -end - -function list_file(id) - local path = luci.http.formvalue("path") - list_response(id, path, true) -end - -function rename_file(id) - local filepath = luci.http.formvalue("filepath") - local newpath = luci.http.formvalue("newpath") - local cmd_docker = luci.util.exec("command -v docker"):match("^.+docker") or nil - if not cmd_docker or cmd_docker:match("^%s+$") then - return - end - local uci = (require "luci.model.uci").cursor() - local remote = uci:get_bool("dockerd", "dockerman", "remote_endpoint") - local socket_path = not remote and uci:get("dockerd", "dockerman", "socket_path") or nil - local host = remote and uci:get("dockerd", "dockerman", "remote_host") or nil - local port = remote and uci:get("dockerd", "dockerman", "remote_port") or nil - if remote and host and port then - hosts = "tcp://" .. host .. ':'.. port - elseif socket_path then - hosts = "unix://" .. socket_path - else - return - end - local success = os.execute(cmd_docker .. ' -H "'.. hosts ..'" exec '.. id ..' mv "'..filepath..'" "'..newpath..'"') - list_response(nixio.fs.dirname(filepath), success) -end - -function remove_file(id) - local path = luci.http.formvalue("path") - local isdir = luci.http.formvalue("isdir") - local cmd_docker = luci.util.exec("command -v docker"):match("^.+docker") or nil - if not cmd_docker or cmd_docker:match("^%s+$") then - return - end - local uci = (require "luci.model.uci").cursor() - local remote = uci:get_bool("dockerd", "dockerman", "remote_endpoint") - local socket_path = not remote and uci:get("dockerd", "dockerman", "socket_path") or nil - local host = remote and uci:get("dockerd", "dockerman", "remote_host") or nil - local port = remote and uci:get("dockerd", "dockerman", "remote_port") or nil - if remote and host and port then - hosts = "tcp://" .. host .. ':'.. port - elseif socket_path then - hosts = "unix://" .. socket_path - else - return - end - path = path:gsub("<>", "/") - path = path:gsub(" ", "\ ") - local success - if isdir then - success = os.execute(cmd_docker .. ' -H "'.. hosts ..'" exec '.. id ..' rm -r "'..path..'"') - else - success = os.remove(path) - end - list_response(nixio.fs.dirname(path), success) -end - -function action_events() - local logs = "" - local query ={} - - local dk = docker.new() - query["until"] = os.time() - local events = dk:events({query = query}) - - if events.code == 200 then - for _, v in ipairs(events.body) do - local date = "unknown" - if v and v.time then - date = os.date("%Y-%m-%d %H:%M:%S", v.time) - end - - local name = v.Actor.Attributes.name or "unknown" - local action = v.Action or "unknown" - - if v and v.Type == "container" then - local id = v.Actor.ID or "unknown" - logs = logs .. string.format("[%s] %s %s Container ID: %s Container Name: %s\n", date, v.Type, action, id, name) - elseif v.Type == "network" then - local container = v.Actor.Attributes.container or "unknown" - local network = v.Actor.Attributes.type or "unknown" - logs = logs .. string.format("[%s] %s %s Container ID: %s Network Name: %s Network type: %s\n", date, v.Type, action, container, name, network) - elseif v.Type == "image" then - local id = v.Actor.ID or "unknown" - logs = logs .. string.format("[%s] %s %s Image: %s Image name: %s\n", date, v.Type, action, id, name) - end - end - end - - luci.template.render("dockerman/logs", {self={syslog = logs, title="Events"}}) -end - -local calculate_cpu_percent = function(d) - if type(d) ~= "table" then - return - end - - local cpu_count = tonumber(d["cpu_stats"]["online_cpus"]) - local cpu_percent = 0.0 - local cpu_delta = tonumber(d["cpu_stats"]["cpu_usage"]["total_usage"]) - tonumber(d["precpu_stats"]["cpu_usage"]["total_usage"]) - local system_delta = tonumber(d["cpu_stats"]["system_cpu_usage"]) -- tonumber(d["precpu_stats"]["system_cpu_usage"]) - if system_delta > 0.0 then - cpu_percent = string.format("%.2f", cpu_delta / system_delta * 100.0 * cpu_count) - end - - return cpu_percent -end - -local get_memory = function(d) - if type(d) ~= "table" then - return - end - - -- local limit = string.format("%.2f", tonumber(d["memory_stats"]["limit"]) / 1024 / 1024) - -- local usage = string.format("%.2f", (tonumber(d["memory_stats"]["usage"]) - tonumber(d["memory_stats"]["stats"]["total_cache"])) / 1024 / 1024) - -- return usage .. "MB / " .. limit.. "MB" - - local limit =tonumber(d["memory_stats"]["limit"]) - local usage = tonumber(d["memory_stats"]["usage"]) - -- - tonumber(d["memory_stats"]["stats"]["total_cache"]) - - return usage, limit -end - -local get_rx_tx = function(d) - if type(d) ~="table" then - return - end - - local data = {} - if type(d["networks"]) == "table" then - for e, v in pairs(d["networks"]) do - data[e] = { - bw_tx = tonumber(v.tx_bytes), - bw_rx = tonumber(v.rx_bytes) - } - end - end - - return data -end - -local function get_stat(container_id) - if container_id then - local dk = docker.new() - local response = dk.containers:inspect({id = container_id}) - if response.code == 200 and response.body.State.Running then - response = dk.containers:stats({id = container_id, query = {stream = false, ["one-shot"] = true}}) - if response.code == 200 then - local container_stats = response.body - local cpu_percent = calculate_cpu_percent(container_stats) - local mem_useage, mem_limit = get_memory(container_stats) - local bw_rxtx = get_rx_tx(container_stats) - return response.code, response.body.message, { - cpu_percent = cpu_percent, - memory = { - mem_useage = mem_useage, - mem_limit = mem_limit - }, - bw_rxtx = bw_rxtx - } - else - return response.code, response.body.message - end - else - if response.code == 200 then - return 500, "container "..container_id.." not running" - else - return response.code, response.body.message - end - end - else - return 404, "No container name or id" - end -end -function action_get_container_stats(container_id) - local code, msg, res = get_stat(container_id) - luci.http.status(code, msg) - luci.http.prepare_content("application/json") - luci.http.write_json(res) -end - -function action_get_containers_stats() - local res = luci.http.formvalue(containers) or "" - local stats = {} - res = luci.jsonc.parse(res.containers) - if res and type(res) == "table" then - for i, v in ipairs(res) do - _,_,stats[v] = get_stat(v) - end - end - luci.http.status(200, "OK") - luci.http.prepare_content("application/json") - luci.http.write_json(stats) -end - -function action_confirm() - local data = docker:read_status() - if data then - data = data:gsub("\n","
"):gsub(" "," ") - code = 202 - msg = data - else - code = 200 - msg = "finish" - data = "finish" - end - - luci.http.status(code, msg) - luci.http.prepare_content("application/json") - luci.http.write_json({info = data}) -end - -function export_container(id) - local dk = docker.new() - local first - - local cb = function(res, chunk) - if res.code == 200 then - if not first then - first = true - luci.http.header('Content-Disposition', 'inline; filename="'.. id ..'.tar"') - luci.http.header('Content-Type', 'application\/x-tar') - end - luci.ltn12.pump.all(chunk, luci.http.write) - else - if not first then - first = true - luci.http.prepare_content("text/plain") - end - luci.ltn12.pump.all(chunk, luci.http.write) - end - end - - local res = dk.containers:export({id = id}, cb) -end - -function download_archive() - local id = luci.http.formvalue("id") - local path = luci.http.formvalue("path") - local filename = luci.http.formvalue("filename") or "archive" - local dk = docker.new() - local first - - local cb = function(res, chunk) - if res and res.code and res.code == 200 then - if not first then - first = true - luci.http.header('Content-Disposition', 'inline; filename="'.. filename .. '.tar"') - luci.http.header('Content-Type', 'application\/x-tar') - end - luci.ltn12.pump.all(chunk, luci.http.write) - else - if not first then - first = true - luci.http.status(res and res.code or 500, msg or "unknow") - luci.http.prepare_content("text/plain") - end - luci.ltn12.pump.all(chunk, luci.http.write) - end - end - - local res = dk.containers:get_archive({ - id = id, - query = { - path = luci.http.urlencode(path) - } - }, cb) -end - -function upload_archive(container_id) - local path = luci.http.formvalue("upload-path") - local dk = docker.new() - local ltn12 = require "luci.ltn12" - - local rec_send = function(sinkout) - luci.http.setfilehandler(function (meta, chunk, eof) - if chunk then - ltn12.pump.step(ltn12.source.string(chunk), sinkout) - end - end) - end - - local res = dk.containers:put_archive({ - id = container_id, - query = { - path = luci.http.urlencode(path) - }, - body = rec_send - }) - - local msg = res and res.message or res.body and res.body.message or nil - luci.http.status(res and res.code or 500, msg or "unknow") - luci.http.prepare_content("application/json") - luci.http.write_json({message = msg or "unknow"}) -end - --- function save_images() --- local names = luci.http.formvalue("names") --- local dk = docker.new() --- local first - --- local cb = function(res, chunk) --- if res.code == 200 then --- if not first then --- first = true --- luci.http.status(res.code, res.message) --- luci.http.header('Content-Disposition', 'inline; filename="'.. "images" ..'.tar"') --- luci.http.header('Content-Type', 'application\/x-tar') --- end --- luci.ltn12.pump.all(chunk, luci.http.write) --- else --- if not first then --- first = true --- luci.http.prepare_content("text/plain") --- end --- luci.ltn12.pump.all(chunk, luci.http.write) --- end --- end - --- docker:write_status("Images: saving" .. " " .. names .. "...") --- local res = dk.images:get({ --- query = { --- names = luci.http.urlencode(names) --- } --- }, cb) --- docker:clear_status() - --- local msg = res and res.body and res.body.message or nil --- luci.http.status(res.code, msg) --- luci.http.prepare_content("application/json") --- luci.http.write_json({message = msg}) --- end - -function load_images() - local archive = luci.http.formvalue("upload-archive") - local dk = docker.new() - local ltn12 = require "luci.ltn12" - - local rec_send = function(sinkout) - luci.http.setfilehandler(function (meta, chunk, eof) - if chunk then - ltn12.pump.step(ltn12.source.string(chunk), sinkout) - end - end) - end - - docker:write_status("Images: loading...") - local res = dk.images:load({body = rec_send}) - local msg = res and res.body and ( res.body.message or res.body.stream or res.body.error ) or nil - if res and res.code == 200 and msg and msg:match("Loaded image ID") then - docker:clear_status() - else - docker:append_status("code:" .. (res and res.code or "500") .." ".. (msg or "unknow")) - end - - luci.http.status(res and res.code or 500, msg or "unknow") - luci.http.prepare_content("application/json") - luci.http.write_json({message = msg or "unknow"}) -end - -function import_images() - local src = luci.http.formvalue("src") - local itag = luci.http.formvalue("tag") - local dk = docker.new() - local ltn12 = require "luci.ltn12" - - local rec_send = function(sinkout) - luci.http.setfilehandler(function (meta, chunk, eof) - if chunk then - ltn12.pump.step(ltn12.source.string(chunk), sinkout) - end - end) - end - - docker:write_status("Images: importing".. " ".. itag .."...\n") - local repo = itag and itag:match("^([^:]+)") - local tag = itag and itag:match("^[^:]-:([^:]+)") - local res = dk.images:create({ - query = { - fromSrc = luci.http.urlencode(src or "-"), - repo = repo or nil, - tag = tag or nil - }, - body = not src and rec_send or nil - }, docker.import_image_show_status_cb) - - local msg = res and res.body and ( res.body.message )or nil - if not msg and #res.body == 0 then - msg = res.body.status or res.body.error - elseif not msg and #res.body >= 1 then - msg = res.body[#res.body].status or res.body[#res.body].error - end - - if res.code == 200 and msg and msg:match("sha256:") then - docker:clear_status() - else - docker:append_status("code:" .. (res and res.code or "500") .." ".. (msg or "unknow")) - end - - luci.http.status(res and res.code or 500, msg or "unknow") - luci.http.prepare_content("application/json") - luci.http.write_json({message = msg or "unknow"}) -end - -function get_image_tags(image_id) - if not image_id then - luci.http.status(400, "no image id") - luci.http.prepare_content("application/json") - luci.http.write_json({message = "no image id"}) - return - end - - local dk = docker.new() - local res = dk.images:inspect({ - id = image_id - }) - local msg = res and res.body and res.body.message or nil - luci.http.status(res and res.code or 500, msg or "unknow") - luci.http.prepare_content("application/json") - - if res.code == 200 then - local tags = res.body.RepoTags - luci.http.write_json({tags = tags}) - else - local msg = res and res.body and res.body.message or nil - luci.http.write_json({message = msg or "unknow"}) - end -end - -function tag_image(image_id) - local src = luci.http.formvalue("tag") - local image_id = image_id or luci.http.formvalue("id") - - if type(src) ~= "string" or not image_id then - luci.http.status(400, "no image id or tag") - luci.http.prepare_content("application/json") - luci.http.write_json({message = "no image id or tag"}) - return - end - - local repo = src:match("^([^:]+)") - local tag = src:match("^[^:]-:([^:]+)") - local dk = docker.new() - local res = dk.images:tag({ - id = image_id, - query={ - repo=repo, - tag=tag - } - }) - local msg = res and res.body and res.body.message or nil - luci.http.status(res and res.code or 500, msg or "unknow") - luci.http.prepare_content("application/json") - - if res.code == 201 then - local tags = res.body.RepoTags - luci.http.write_json({tags = tags}) - else - local msg = res and res.body and res.body.message or nil - luci.http.write_json({message = msg or "unknow"}) - end -end - -function untag_image(tag) - local tag = tag or luci.http.formvalue("tag") - - if not tag then - luci.http.status(400, "no tag name") - luci.http.prepare_content("application/json") - luci.http.write_json({message = "no tag name"}) - return - end - - local dk = docker.new() - local res = dk.images:inspect({name = tag}) - - if res.code == 200 then - local tags = res.body.RepoTags - if #tags > 1 then - local r = dk.images:remove({name = tag}) - local msg = r and r.body and r.body.message or nil - luci.http.status(r.code, msg) - luci.http.prepare_content("application/json") - luci.http.write_json({message = msg}) - else - luci.http.status(500, "Cannot remove the last tag") - luci.http.prepare_content("application/json") - luci.http.write_json({message = "Cannot remove the last tag"}) - end - else - local msg = res and res.body and res.body.message or nil - luci.http.status(res and res.code or 500, msg or "unknow") - luci.http.prepare_content("application/json") - luci.http.write_json({message = msg or "unknow"}) - end -end diff --git a/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua b/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua deleted file mode 100755 index f62650fe5..000000000 --- a/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua +++ /dev/null @@ -1,152 +0,0 @@ ---[[ -LuCI - Lua Configuration Interface -Copyright 2021 Florian Eckert -Copyright 2021 lisaac -]]-- - -local uci = (require "luci.model.uci").cursor() - -local m, s, o - -m = Map("dockerd", - translate("Docker - Configuration"), - translate("DockerMan is a simple docker manager client for LuCI")) - -if nixio.fs.access("/usr/bin/dockerd") and not m.uci:get_bool("dockerd", "dockerman", "remote_endpoint") then - s = m:section(NamedSection, "globals", "section", translate("Docker Daemon settings")) - - o = s:option(Flag, "auto_start", translate("Auto start")) - o.rmempty = false - o.write = function(self, section, value) - if value == "1" then - luci.util.exec("/etc/init.d/dockerd enable") - else - luci.util.exec("/etc/init.d/dockerd disable") - end - m.uci:set("dockerd", "globals", "auto_start", value) - end - - o = s:option(Value, "data_root", - translate("Docker Root Dir")) - o.placeholder = "/opt/docker/" - o:depends("remote_endpoint", 0) - - o = s:option(Value, "bip", - translate("Default bridge"), - translate("Configure the default bridge network")) - o.placeholder = "172.17.0.1/16" - o.datatype = "ipaddr" - o:depends("remote_endpoint", 0) - - o = s:option(DynamicList, "registry_mirrors", - translate("Registry Mirrors"), - translate("It replaces the daemon registry mirrors with a new set of registry mirrors")) - o:value("https://hub-mirror.c.163.com", "https://hub-mirror.c.163.com") - o:depends("remote_endpoint", 0) - o.forcewrite = true - - o = s:option(ListValue, "log_level", - translate("Log Level"), - translate('Set the logging level')) - o:value("debug", translate("Debug")) - o:value("", translate("Info")) -- This is the default debug level from the deamon is optin is not set - o:value("warn", translate("Warning")) - o:value("error", translate("Error")) - o:value("fatal", translate("Fatal")) - o.rmempty = true - o:depends("remote_endpoint", 0) - - o = s:option(DynamicList, "hosts", - translate("Client connection"), - translate('Specifies where the Docker daemon will listen for client connections (default: unix:///var/run/docker.sock)')) - o:value("unix:///var/run/docker.sock", "unix:///var/run/docker.sock") - o:value("tcp://0.0.0.0:2375", "tcp://0.0.0.0:2375") - o.rmempty = true - o:depends("remote_endpoint", 0) -end - -s = m:section(NamedSection, "dockerman", "section", translate("DockerMan settings")) -s:tab("ac", translate("Access Control")) -s:tab("dockerman", translate("DockerMan")) - -o = s:taboption("dockerman", Flag, "remote_endpoint", - translate("Remote Endpoint"), - translate("Connect to remote docker endpoint")) -o.rmempty = false -o.validate = function(self, value, sid) - local res = luci.http.formvaluetable("cbid.dockerd") - if res["dockerman.remote_endpoint"] == "1" then - if res["dockerman.remote_port"] and res["dockerman.remote_port"] ~= "" and res["dockerman.remote_host"] and res["dockerman.remote_host"] ~= "" then - return 1 - else - return nil, translate("Please input the PORT or HOST IP of remote docker instance!") - end - else - if not res["dockerman.socket_path"] then - return nil, translate("Please input the SOCKET PATH of docker daemon!") - end - end - return 0 -end - -o = s:taboption("dockerman", Value, "socket_path", - translate("Docker Socket Path")) -o.default = "/var/run/docker.sock" -o.placeholder = "/var/run/docker.sock" -o:depends("remote_endpoint", 0) - -o = s:taboption("dockerman", Value, "remote_host", - translate("Remote Host"), - translate("Host or IP Address for the connection to a remote docker instance")) -o.datatype = "host" -o.placeholder = "10.1.1.2" -o:depends("remote_endpoint", 1) - -o = s:taboption("dockerman", Value, "remote_port", - translate("Remote Port")) -o.placeholder = "2375" -o.datatype = "port" -o:depends("remote_endpoint", 1) - --- o = s:taboption("dockerman", Value, "status_path", translate("Action Status Tempfile Path"), translate("Where you want to save the docker status file")) --- o = s:taboption("dockerman", Flag, "debug", translate("Enable Debug"), translate("For debug, It shows all docker API actions of luci-app-dockerman in Debug Tempfile Path")) --- o.enabled="true" --- o.disabled="false" --- o = s:taboption("dockerman", Value, "debug_path", translate("Debug Tempfile Path"), translate("Where you want to save the debug tempfile")) - -if nixio.fs.access("/usr/bin/dockerd") and not m.uci:get_bool("dockerd", "dockerman", "remote_endpoint") then - o = s:taboption("ac", DynamicList, "ac_allowed_interface", translate("Allowed access interfaces"), translate("Which interface(s) can access containers under the bridge network, fill-in Interface Name")) - local interfaces = luci.sys and luci.sys.net and luci.sys.net.devices() or {} - for i, v in ipairs(interfaces) do - o:value(v, v) - end - o = s:taboption("ac", DynamicList, "ac_allowed_ports", translate("Ports allowed to be accessed"), translate("Which Port(s) can be accessed, it's not restricted by the Allowed Access interfaces configuration. Use this configuration with caution!")) - o.placeholder = "8080/tcp" - local docker = require "luci.model.docker" - local containers, res, lost_state - local dk = docker.new() - if dk:_ping().code ~= 200 then - lost_state = true - else - lost_state = false - res = dk.containers:list() - if res and res.code and res.code < 300 then - containers = res.body - end - end - - -- allowed_container.placeholder = "container name_or_id" - if containers then - for i, v in ipairs(containers) do - if v.State == "running" and v.Ports then - for _, port in ipairs(v.Ports) do - if port.PublicPort and port.IP and not string.find(port.IP,":") then - o:value(port.PublicPort.."/"..port.Type, v.Names[1]:sub(2) .. " | " .. port.PublicPort .. " | " .. port.Type) - end - end - end - end - end -end - -return m diff --git a/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua b/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua deleted file mode 100755 index 20220ad8f..000000000 --- a/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua +++ /dev/null @@ -1,810 +0,0 @@ ---[[ -LuCI - Lua Configuration Interface -Copyright 2019 lisaac -]]-- - -require "luci.util" - -local docker = require "luci.model.docker" -local dk = docker.new() - -container_id = arg[1] -local action = arg[2] or "info" - -local m, s, o -local images, networks, container_info, res - -if not container_id then - return -end - -res = dk.containers:inspect({id = container_id}) -if res.code < 300 then - container_info = res.body -else - return -end - -local get_ports = function(d) - local data - - if d.HostConfig and d.HostConfig.PortBindings then - for inter, out in pairs(d.HostConfig.PortBindings) do - data = (data and (data .. "
") or "") .. out[1]["HostPort"] .. ":" .. inter - end - end - - return data -end - -local get_env = function(d) - local data - - if d.Config and d.Config.Env then - for _,v in ipairs(d.Config.Env) do - data = (data and (data .. "
") or "") .. v - end - end - - return data -end - -local get_command = function(d) - local data - - if d.Config and d.Config.Cmd then - for _,v in ipairs(d.Config.Cmd) do - data = (data and (data .. " ") or "") .. v - end - end - - return data -end - -local get_mounts = function(d) - local data - - if d.Mounts then - for _,v in ipairs(d.Mounts) do - local v_sorce_d, v_dest_d - local v_sorce = "" - local v_dest = "" - for v_sorce_d in v["Source"]:gmatch('[^/]+') do - if v_sorce_d and #v_sorce_d > 12 then - v_sorce = v_sorce .. "/" .. v_sorce_d:sub(1,12) .. "..." - else - v_sorce = v_sorce .."/".. v_sorce_d - end - end - for v_dest_d in v["Destination"]:gmatch('[^/]+') do - if v_dest_d and #v_dest_d > 12 then - v_dest = v_dest .. "/" .. v_dest_d:sub(1,12) .. "..." - else - v_dest = v_dest .."/".. v_dest_d - end - end - data = (data and (data .. "
") or "") .. v_sorce .. ":" .. v["Destination"] .. (v["Mode"] ~= "" and (":" .. v["Mode"]) or "") - end - end - - return data -end - -local get_device = function(d) - local data - - if d.HostConfig and d.HostConfig.Devices then - for _,v in ipairs(d.HostConfig.Devices) do - data = (data and (data .. "
") or "") .. v["PathOnHost"] .. ":" .. v["PathInContainer"] .. (v["CgroupPermissions"] ~= "" and (":" .. v["CgroupPermissions"]) or "") - end - end - - return data -end - -local get_links = function(d) - local data - - if d.HostConfig and d.HostConfig.Links then - for _,v in ipairs(d.HostConfig.Links) do - data = (data and (data .. "
") or "") .. v - end - end - - return data -end - -local get_tmpfs = function(d) - local data - - if d.HostConfig and d.HostConfig.Tmpfs then - for k, v in pairs(d.HostConfig.Tmpfs) do - data = (data and (data .. "
") or "") .. k .. (v~="" and ":" or "")..v - end - end - - return data -end - -local get_dns = function(d) - local data - - if d.HostConfig and d.HostConfig.Dns then - for _, v in ipairs(d.HostConfig.Dns) do - data = (data and (data .. "
") or "") .. v - end - end - - return data -end - -local get_sysctl = function(d) - local data - - if d.HostConfig and d.HostConfig.Sysctls then - for k, v in pairs(d.HostConfig.Sysctls) do - data = (data and (data .. "
") or "") .. k..":"..v - end - end - - return data -end - -local get_networks = function(d) - local data={} - - if d.NetworkSettings and d.NetworkSettings.Networks and type(d.NetworkSettings.Networks) == "table" then - for k,v in pairs(d.NetworkSettings.Networks) do - data[k] = v.IPAddress or "" - end - end - - return data -end - - -local start_stop_remove = function(m, cmd) - local res - - docker:clear_status() - docker:append_status("Containers: " .. cmd .. " " .. container_id .. "...") - - if cmd ~= "upgrade" then - res = dk.containers[cmd](dk, {id = container_id}) - else - res = dk.containers_upgrade(dk, {id = container_id}) - end - - if res and res.code >= 300 then - docker:append_status("code:" .. res.code.." ".. (res.body.message and res.body.message or res.message)) - luci.http.redirect(luci.dispatcher.build_url("admin/docker/container/"..container_id)) - else - docker:clear_status() - if cmd ~= "remove" and cmd ~= "upgrade" then - luci.http.redirect(luci.dispatcher.build_url("admin/docker/container/"..container_id)) - else - luci.http.redirect(luci.dispatcher.build_url("admin/docker/containers")) - end - end -end - -m=SimpleForm("docker", - translatef("Docker - Container (%s)", container_info.Name:sub(2)), - translate("On this page, the selected container can be managed.")) -m.redirect = luci.dispatcher.build_url("admin/docker/containers") - -s = m:section(SimpleSection) -s.template = "dockerman/apply_widget" -s.err=docker:read_status() -s.err=s.err and s.err:gsub("\n","
"):gsub(" "," ") -if s.err then - docker:clear_status() -end - -s = m:section(Table,{{}}) -s.notitle=true -s.rowcolors=false -s.template = "cbi/nullsection" - -o = s:option(Button, "_start") -o.template = "dockerman/cbi/inlinebutton" -o.inputtitle=translate("Start") -o.inputstyle = "apply" -o.forcewrite = true -o.write = function(self, section) - start_stop_remove(m,"start") -end - -o = s:option(Button, "_restart") -o.template = "dockerman/cbi/inlinebutton" -o.inputtitle=translate("Restart") -o.inputstyle = "reload" -o.forcewrite = true -o.write = function(self, section) - start_stop_remove(m,"restart") -end - -o = s:option(Button, "_stop") -o.template = "dockerman/cbi/inlinebutton" -o.inputtitle=translate("Stop") -o.inputstyle = "reset" -o.forcewrite = true -o.write = function(self, section) - start_stop_remove(m,"stop") -end - -o = s:option(Button, "_kill") -o.template = "dockerman/cbi/inlinebutton" -o.inputtitle=translate("Kill") -o.inputstyle = "reset" -o.forcewrite = true -o.write = function(self, section) - start_stop_remove(m,"kill") -end - -o = s:option(Button, "_export") -o.template = "dockerman/cbi/inlinebutton" -o.inputtitle=translate("Export") -o.inputstyle = "apply" -o.forcewrite = true -o.write = function(self, section) - luci.http.redirect(luci.dispatcher.build_url("admin/docker/container_export/"..container_id)) -end - -o = s:option(Button, "_upgrade") -o.template = "dockerman/cbi/inlinebutton" -o.inputtitle=translate("Upgrade") -o.inputstyle = "reload" -o.forcewrite = true -o.write = function(self, section) - start_stop_remove(m,"upgrade") -end - -o = s:option(Button, "_duplicate") -o.template = "dockerman/cbi/inlinebutton" -o.inputtitle=translate("Duplicate/Edit") -o.inputstyle = "add" -o.forcewrite = true -o.write = function(self, section) - luci.http.redirect(luci.dispatcher.build_url("admin/docker/newcontainer/duplicate/"..container_id)) -end - -o = s:option(Button, "_remove") -o.template = "dockerman/cbi/inlinebutton" -o.inputtitle=translate("Remove") -o.inputstyle = "remove" -o.forcewrite = true -o.write = function(self, section) - start_stop_remove(m,"remove") -end - -s = m:section(SimpleSection) -s.template = "dockerman/container" - -if action == "info" then - res = dk.networks:list() - if res.code < 300 then - networks = res.body - else - return - end - m.submit = false - m.reset = false - table_info = { - ["01name"] = { - _key = translate("Name"), - _value = container_info.Name:sub(2) or "-", - _button=translate("Update") - }, - ["02id"] = { - _key = translate("ID"), - _value = container_info.Id or "-" - }, - ["03image"] = { - _key = translate("Image"), - _value = container_info.Config.Image .. "
" .. container_info.Image - }, - ["04status"] = { - _key = translate("Status"), - _value = container_info.State and container_info.State.Status or "-" - }, - ["05created"] = { - _key = translate("Created"), - _value = container_info.Created or "-" - }, - } - - if container_info.State.Status == "running" then - table_info["06start"] = { - _key = translate("Start Time"), - _value = container_info.State and container_info.State.StartedAt or "-" - } - else - table_info["06start"] = { - _key = translate("Finish Time"), - _value = container_info.State and container_info.State.FinishedAt or "-" - } - end - - table_info["07healthy"] = { - _key = translate("Healthy"), - _value = container_info.State and container_info.State.Health and container_info.State.Health.Status or "-" - } - table_info["08restart"] = { - _key = translate("Restart Policy"), - _value = container_info.HostConfig and container_info.HostConfig.RestartPolicy and container_info.HostConfig.RestartPolicy.Name or "-", - _button=translate("Update") - } - table_info["081user"] = { - _key = translate("User"), - _value = container_info.Config and (container_info.Config.User ~="" and container_info.Config.User or "-") or "-" - } - table_info["09mount"] = { - _key = translate("Mount/Volume"), - _value = get_mounts(container_info) or "-" - } - table_info["10cmd"] = { - _key = translate("Command"), - _value = get_command(container_info) or "-" - } - table_info["11env"] = { - _key = translate("Env"), - _value = get_env(container_info) or "-" - } - table_info["12ports"] = { - _key = translate("Ports"), - _value = get_ports(container_info) or "-" - } - table_info["13links"] = { - _key = translate("Links"), - _value = get_links(container_info) or "-" - } - table_info["14device"] = { - _key = translate("Device"), - _value = get_device(container_info) or "-" - } - table_info["15tmpfs"] = { - _key = translate("Tmpfs"), - _value = get_tmpfs(container_info) or "-" - } - table_info["16dns"] = { - _key = translate("DNS"), - _value = get_dns(container_info) or "-" - } - table_info["17sysctl"] = { - _key = translate("Sysctl"), - _value = get_sysctl(container_info) or "-" - } - - info_networks = get_networks(container_info) - list_networks = {} - for _, v in ipairs (networks) do - if v and v.Name then - local parent = v.Options and v.Options.parent or nil - local ip = v.IPAM and v.IPAM.Config and v.IPAM.Config[1] and v.IPAM.Config[1].Subnet or nil - ipv6 = v.IPAM and v.IPAM.Config and v.IPAM.Config[2] and v.IPAM.Config[2].Subnet or nil - local network_name = v.Name .. " | " .. v.Driver .. (parent and (" | " .. parent) or "") .. (ip and (" | " .. ip) or "").. (ipv6 and (" | " .. ipv6) or "") - list_networks[v.Name] = network_name - end - end - - if type(info_networks)== "table" then - for k,v in pairs(info_networks) do - table_info["14network"..k] = { - _key = translate("Network"), - _value = k.. (v~="" and (" | ".. v) or ""), - _button=translate("Disconnect") - } - list_networks[k]=nil - end - end - - table_info["15connect"] = { - _key = translate("Connect Network"), - _value = list_networks ,_opts = "", - _button=translate("Connect") - } - - s = m:section(Table,table_info) - s.nodescr=true - s.formvalue=function(self, section) - return table_info - end - - o = s:option(DummyValue, "_key", translate("Info")) - o.width = "20%" - - o = s:option(ListValue, "_value") - o.render = function(self, section, scope) - if table_info[section]._key == translate("Name") then - self:reset_values() - self.template = "cbi/value" - self.size = 30 - self.keylist = {} - self.vallist = {} - self.default=table_info[section]._value - Value.render(self, section, scope) - elseif table_info[section]._key == translate("Restart Policy") then - self.template = "cbi/lvalue" - self:reset_values() - self.size = nil - self:value("no", "No") - self:value("unless-stopped", "Unless stopped") - self:value("always", "Always") - self:value("on-failure", "On failure") - self.default=table_info[section]._value - ListValue.render(self, section, scope) - elseif table_info[section]._key == translate("Connect Network") then - self.template = "cbi/lvalue" - self:reset_values() - self.size = nil - for k,v in pairs(list_networks) do - if k ~= "host" then - self:value(k,v) - end - end - self.default=table_info[section]._value - ListValue.render(self, section, scope) - else - self:reset_values() - self.rawhtml=true - self.template = "cbi/dvalue" - self.default=table_info[section]._value - DummyValue.render(self, section, scope) - end - end - o.forcewrite = true - o.write = function(self, section, value) - table_info[section]._value=value - end - o.validate = function(self, value) - return value - end - - o = s:option(Value, "_opts") - o.forcewrite = true - o.write = function(self, section, value) - table_info[section]._opts=value - end - o.validate = function(self, value) - return value - end - o.render = function(self, section, scope) - if table_info[section]._key==translate("Connect Network") then - self.template = "cbi/value" - self.keylist = {} - self.vallist = {} - self.placeholder = "10.1.1.254" - self.datatype = "ip4addr" - self.default=table_info[section]._opts - Value.render(self, section, scope) - else - self.rawhtml=true - self.template = "cbi/dvalue" - self.default=table_info[section]._opts - DummyValue.render(self, section, scope) - end - end - - o = s:option(Button, "_button") - o.forcewrite = true - o.render = function(self, section, scope) - if table_info[section]._button and table_info[section]._value ~= nil then - self.inputtitle=table_info[section]._button - self.template = "cbi/button" - self.inputstyle = "edit" - Button.render(self, section, scope) - else - self.template = "cbi/dvalue" - self.default="" - DummyValue.render(self, section, scope) - end - end - o.write = function(self, section, value) - local res - - docker:clear_status() - - if section == "01name" then - docker:append_status("Containers: rename " .. container_id .. "...") - local new_name = table_info[section]._value - res = dk.containers:rename({ - id = container_id, - query = { - name=new_name - } - }) - elseif section == "08restart" then - docker:append_status("Containers: update " .. container_id .. "...") - local new_restart = table_info[section]._value - res = dk.containers:update({ - id = container_id, - body = { - RestartPolicy = { - Name = new_restart - } - } - }) - elseif table_info[section]._key == translate("Network") then - local _,_,leave_network - - _, _, leave_network = table_info[section]._value:find("(.-) | .+") - leave_network = leave_network or table_info[section]._value - docker:append_status("Network: disconnect " .. leave_network .. container_id .. "...") - res = dk.networks:disconnect({ - name = leave_network, - body = { - Container = container_id - } - }) - elseif section == "15connect" then - local connect_network = table_info[section]._value - local network_opiton - if connect_network ~= "none" - and connect_network ~= "bridge" - and connect_network ~= "host" then - - network_opiton = table_info[section]._opts ~= "" and { - IPAMConfig={ - IPv4Address=table_info[section]._opts - } - } or nil - end - docker:append_status("Network: connect " .. connect_network .. container_id .. "...") - res = dk.networks:connect({ - name = connect_network, - body = { - Container = container_id, - EndpointConfig= network_opiton - } - }) - end - - if res and res.code > 300 then - docker:append_status("code:" .. res.code.." ".. (res.body.message and res.body.message or res.message)) - else - docker:clear_status() - end - luci.http.redirect(luci.dispatcher.build_url("admin/docker/container/"..container_id.."/info")) - end -elseif action == "resources" then - s = m:section(SimpleSection) - o = s:option( Value, "cpus", - translate("CPUs"), - translate("Number of CPUs. Number is a fractional number. 0.000 means no limit.")) - o.placeholder = "1.5" - o.rmempty = true - o.datatype="ufloat" - o.default = container_info.HostConfig.NanoCpus / (10^9) - - o = s:option(Value, "cpushares", - translate("CPU Shares Weight"), - translate("CPU shares relative weight, if 0 is set, the system will ignore the value and use the default of 1024.")) - o.placeholder = "1024" - o.rmempty = true - o.datatype="uinteger" - o.default = container_info.HostConfig.CpuShares - - o = s:option(Value, "memory", - translate("Memory"), - translate("Memory limit (format: []). Number is a positive integer. Unit can be one of b, k, m, or g. Minimum is 4M.")) - o.placeholder = "128m" - o.rmempty = true - o.default = container_info.HostConfig.Memory ~=0 and ((container_info.HostConfig.Memory / 1024 /1024) .. "M") or 0 - - o = s:option(Value, "blkioweight", - translate("Block IO Weight"), - translate("Block IO weight (relative weight) accepts a weight value between 10 and 1000.")) - o.placeholder = "500" - o.rmempty = true - o.datatype="uinteger" - o.default = container_info.HostConfig.BlkioWeight - - m.handle = function(self, state, data) - if state == FORM_VALID then - local memory = data.memory - if memory and memory ~= 0 then - _,_,n,unit = memory:find("([%d%.]+)([%l%u]+)") - if n then - unit = unit and unit:sub(1,1):upper() or "B" - if unit == "M" then - memory = tonumber(n) * 1024 * 1024 - elseif unit == "G" then - memory = tonumber(n) * 1024 * 1024 * 1024 - elseif unit == "K" then - memory = tonumber(n) * 1024 - else - memory = tonumber(n) - end - end - end - - request_body = { - BlkioWeight = tonumber(data.blkioweight), - NanoCPUs = tonumber(data.cpus)*10^9, - Memory = tonumber(memory), - CpuShares = tonumber(data.cpushares) - } - - docker:write_status("Containers: update " .. container_id .. "...") - local res = dk.containers:update({id = container_id, body = request_body}) - if res and res.code >= 300 then - docker:append_status("code:" .. res.code.." ".. (res.body.message and res.body.message or res.message)) - else - docker:clear_status() - end - luci.http.redirect(luci.dispatcher.build_url("admin/docker/container/"..container_id.."/resources")) - end - end - -elseif action == "file" then - m.submit = false - m.reset = false - s= m:section(SimpleSection) - s.template = "dockerman/container_file_manager" - s.container = container_id - m.redirect = nil -elseif action == "inspect" then - s = m:section(SimpleSection) - s.syslog = luci.jsonc.stringify(container_info, true) - s.title = translate("Container Inspect") - s.template = "dockerman/logs" - m.submit = false - m.reset = false -elseif action == "logs" then - local logs = "" - local query ={ - stdout = 1, - stderr = 1, - tail = 1000 - } - - s = m:section(SimpleSection) - - logs = dk.containers:logs({id = container_id, query = query}) - if logs.code == 200 then - s.syslog=logs.body - else - s.syslog="Get Logs ERROR\n"..logs.code..": "..logs.body - end - - s.title=translate("Container Logs") - s.template = "dockerman/logs" - m.submit = false - m.reset = false -elseif action == "console" then - m.submit = false - m.reset = false - local cmd_docker = luci.util.exec("command -v docker"):match("^.+docker") or nil - local cmd_ttyd = luci.util.exec("command -v ttyd"):match("^.+ttyd") or nil - - if cmd_docker and cmd_ttyd and container_info.State.Status == "running" then - local cmd = "/bin/sh" - local uid - - s = m:section(SimpleSection) - - o = s:option(Value, "command", translate("Command")) - o:value("/bin/sh", "/bin/sh") - o:value("/bin/ash", "/bin/ash") - o:value("/bin/bash", "/bin/bash") - o.default = "/bin/sh" - o.forcewrite = true - o.write = function(self, section, value) - cmd = value - end - - o = s:option(Value, "uid", translate("UID")) - o.forcewrite = true - o.write = function(self, section, value) - uid = value - end - - o = s:option(Button, "connect") - o.render = function(self, section, scope) - self.inputstyle = "add" - self.title = " " - self.inputtitle = translate("Connect") - Button.render(self, section, scope) - end - o.write = function(self, section) - local cmd_docker = luci.util.exec("command -v docker"):match("^.+docker") or nil - local cmd_ttyd = luci.util.exec("command -v ttyd"):match("^.+ttyd") or nil - - if not cmd_docker or not cmd_ttyd or cmd_docker:match("^%s+$") or cmd_ttyd:match("^%s+$") then - return - end - local uci = (require "luci.model.uci").cursor() - - local ttyd_ssl = uci:get("ttyd", "@ttyd[0]", "ssl") - local ttyd_ssl_key = uci:get("ttyd", "@ttyd[0]", "ssl_key") - local ttyd_ssl_cert = uci:get("ttyd", "@ttyd[0]", "ssl_cert") - - if ttyd_ssl == "1" and ttyd_ssl_cert and ttyd_ssl_key then - cmd_ttyd = string.format('%s -S -C %s -K %s', cmd_ttyd, ttyd_ssl_cert, ttyd_ssl_key) - end - - local pid = luci.util.trim(luci.util.exec("netstat -lnpt | grep :7682 | grep ttyd | tr -s ' ' | cut -d ' ' -f7 | cut -d'/' -f1")) - if pid and pid ~= "" then - luci.util.exec("kill -9 " .. pid) - end - - local hosts - local remote = uci:get_bool("dockerd", "dockerman", "remote_endpoint") or false - local host = nil - local port = nil - local socket = nil - - if remote then - host = uci:get("dockerd", "dockerman", "remote_host") or nil - port = uci:get("dockerd", "dockerman", "remote_port") or nil - else - socket = uci:get("dockerd", "dockerman", "socket_path") or "/var/run/docker.sock" - end - - if remote and host and port then - hosts = "tcp://" .. host .. ':'.. port - elseif socket then - hosts = "unix://" .. socket - else - return - end - - if uid and uid ~= "" then - uid = "-u " .. uid - else - uid = "" - end - - local start_cmd = string.format('%s -d 2 --once -p 7682 %s -H "%s" exec -it %s %s %s&', cmd_ttyd, cmd_docker, hosts, uid, container_id, cmd) - - os.execute(start_cmd) - - o = s:option(DummyValue, "console") - o.container_id = container_id - o.template = "dockerman/container_console" - end - end -elseif action == "stats" then - local response = dk.containers:top({id = container_id, query = {ps_args="-aux"}}) - local container_top - - if response.code == 200 then - container_top=response.body - else - response = dk.containers:top({id = container_id}) - if response.code == 200 then - container_top=response.body - end - end - - if type(container_top) == "table" then - s = m:section(SimpleSection) - s.container_id = container_id - s.template = "dockerman/container_stats" - table_stats = { - cpu={ - key=translate("CPU Useage"), - value='-' - }, - memory={ - key=translate("Memory Useage"), - value='-' - } - } - - container_top = response.body - s = m:section(Table, table_stats, translate("Stats")) - s:option(DummyValue, "key", translate("Stats")).width="33%" - s:option(DummyValue, "value") - top_section = m:section(Table, container_top.Processes, translate("TOP")) - for i, v in ipairs(container_top.Titles) do - top_section:option(DummyValue, i, translate(v)) - end - end - - m.submit = false - m.reset = false -end - -return m diff --git a/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua b/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua deleted file mode 100755 index 47f634f8b..000000000 --- a/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua +++ /dev/null @@ -1,284 +0,0 @@ ---[[ -LuCI - Lua Configuration Interface -Copyright 2019 lisaac -]]-- - -local http = require "luci.http" -local docker = require "luci.model.docker" - -local m, s, o -local images, networks, containers, res, lost_state -local urlencode = luci.http.protocol and luci.http.protocol.urlencode or luci.util.urlencode -local dk = docker.new() - -if dk:_ping().code ~= 200 then - lost_state = true -else - res = dk.images:list() - if res and res.code and res.code < 300 then - images = res.body - end - - res = dk.networks:list() - if res and res.code and res.code < 300 then - networks = res.body - end - - res = dk.containers:list({ - query = { - all = true - } - }) - if res and res.code and res.code < 300 then - containers = res.body - end -end - -function get_containers() - local data = {} - if type(containers) ~= "table" then - return nil - end - - for i, v in ipairs(containers) do - local index = (10^12 - v.Created) .. "_id_" .. v.Id - - data[index]={} - data[index]["_selected"] = 0 - data[index]["_id"] = v.Id:sub(1,12) - -- data[index]["name"] = v.Names[1]:sub(2) - data[index]["_status"] = v.Status - - if v.Status:find("^Up") then - data[index]["_name"] = ""..v.Names[1]:sub(2).."" - data[index]["_status"] = "".. data[index]["_status"] .. "" .. "


" - else - data[index]["_name"] = ""..v.Names[1]:sub(2).."" - data[index]["_status"] = ''.. data[index]["_status"] .. "" - end - - if (type(v.NetworkSettings) == "table" and type(v.NetworkSettings.Networks) == "table") then - for networkname, netconfig in pairs(v.NetworkSettings.Networks) do - data[index]["_network"] = (data[index]["_network"] ~= nil and (data[index]["_network"] .." | ") or "").. networkname .. (netconfig.IPAddress ~= "" and (": " .. netconfig.IPAddress) or "") - end - end - - -- networkmode = v.HostConfig.NetworkMode ~= "default" and v.HostConfig.NetworkMode or "bridge" - -- data[index]["_network"] = v.NetworkSettings.Networks[networkmode].IPAddress or nil - -- local _, _, image = v.Image:find("^sha256:(.+)") - -- if image ~= nil then - -- image=image:sub(1,12) - -- end - - if v.Ports and next(v.Ports) ~= nil then - data[index]["_ports"] = nil - local ip = require "luci.ip" - for _,v2 in ipairs(v.Ports) do - -- display ipv4 only - if ip.new(v2.IP or "0.0.0.0"):is4() then - data[index]["_ports"] = (data[index]["_ports"] and (data[index]["_ports"] .. ", ") or "") - .. ((v2.PublicPort and v2.Type and v2.Type == "tcp") and ('') or "") - .. (v2.PublicPort and (v2.PublicPort .. ":") or "") .. (v2.PrivatePort and (v2.PrivatePort .."/") or "") .. (v2.Type and v2.Type or "") - .. ((v2.PublicPort and v2.Type and v2.Type == "tcp")and "" or "") - end - end - end - - for ii,iv in ipairs(images) do - if iv.Id == v.ImageID then - data[index]["_image"] = iv.RepoTags and iv.RepoTags[1] or (iv.RepoDigests[1]:gsub("(.-)@.+", "%1") .. ":<none>") - end - end - data[index]["_id_name"] = ''.. data[index]["_name"] .. "
ID: " .. data[index]["_id"] - .. "

Image: " .. (data[index]["_image"] or "<none>") - .. "
" - - if type(v.Mounts) == "table" and next(v.Mounts) then - for _, v2 in pairs(v.Mounts) do - if v2.Type ~= "volume" then - local v_sorce_d, v_dest_d - local v_sorce = "" - local v_dest = "" - for v_sorce_d in v2["Source"]:gmatch('[^/]+') do - if v_sorce_d and #v_sorce_d > 12 then - v_sorce = v_sorce .. "/" .. v_sorce_d:sub(1,8) .. ".." - else - v_sorce = v_sorce .."/".. v_sorce_d - end - end - for v_dest_d in v2["Destination"]:gmatch('[^/]+') do - if v_dest_d and #v_dest_d > 12 then - v_dest = v_dest .. "/" .. v_dest_d:sub(1,8) .. ".." - else - v_dest = v_dest .."/".. v_dest_d - end - end - data[index]["_mounts"] = (data[index]["_mounts"] and (data[index]["_mounts"] .. "
") or "") .. '' .. v_sorce .. "→" .. v_dest..'' - end - end - end - - data[index]["_image_id"] = v.ImageID:sub(8,20) - data[index]["_command"] = v.Command - end - return data -end - -local container_list = not lost_state and get_containers() or {} - -m = SimpleForm("docker", - translate("Docker - Containers"), - translate("This page displays all containers that have been created on the connected docker host.")) -m.submit=false -m.reset=false -m:append(Template("dockerman/containers_running_stats")) - -s = m:section(SimpleSection) -s.template = "dockerman/apply_widget" -s.err=docker:read_status() -s.err=s.err and s.err:gsub("\n","
"):gsub(" "," ") -if s.err then - docker:clear_status() -end - -s = m:section(Table, container_list, translate("Containers")) -s.nodescr=true -s.config="containers" - -o = s:option(Flag, "_selected","") -o.disabled = 0 -o.enabled = 1 -o.default = 0 -o.width = "1%" -o.write=function(self, section, value) - container_list[section]._selected = value -end - --- o = s:option(DummyValue, "_id", translate("ID")) --- o.width="10%" - --- o = s:option(DummyValue, "_name", translate("Container Name")) --- o.rawhtml = true - -o = s:option(DummyValue, "_id_name", translate("Container Info")) -o.rawhtml = true -o.width="15%" - -o = s:option(DummyValue, "_status", translate("Status")) -o.width="15%" -o.rawhtml=true - -o = s:option(DummyValue, "_network", translate("Network")) -o.width="10%" - -o = s:option(DummyValue, "_ports", translate("Ports")) -o.width="5%" -o.rawhtml = true -o = s:option(DummyValue, "_mounts", translate("Mounts")) -o.width="25%" -o.rawhtml = true - --- o = s:option(DummyValue, "_image", translate("Image")) --- o.width="8%" - -o = s:option(DummyValue, "_command", translate("Command")) -o.width="15%" - -local start_stop_remove = function(m, cmd) - local container_selected = {} - -- 遍历table中sectionid - for k in pairs(container_list) do - -- 得到选中项的名字 - if container_list[k]._selected == 1 then - container_selected[#container_selected + 1] = container_list[k]["_id"] - end - end - if #container_selected > 0 then - local success = true - - docker:clear_status() - for _, cont in ipairs(container_selected) do - docker:append_status("Containers: " .. cmd .. " " .. cont .. "...") - local res = dk.containers[cmd](dk, {id = cont}) - if res and res.code and res.code >= 300 then - success = false - docker:append_status("code:" .. res.code.." ".. (res.body.message and res.body.message or res.message).. "\n") - else - docker:append_status("done\n") - end - end - - if success then - docker:clear_status() - end - - luci.http.redirect(luci.dispatcher.build_url("admin/docker/containers")) - end -end - -s = m:section(Table,{{}}) -s.notitle=true -s.rowcolors=false -s.template="cbi/nullsection" - -o = s:option(Button, "_new") -o.inputtitle = translate("Add") -o.template = "dockerman/cbi/inlinebutton" -o.inputstyle = "add" -o.forcewrite = true -o.write = function(self, section) - luci.http.redirect(luci.dispatcher.build_url("admin/docker/newcontainer")) -end -o.disable = lost_state - -o = s:option(Button, "_start") -o.template = "dockerman/cbi/inlinebutton" -o.inputtitle = translate("Start") -o.inputstyle = "apply" -o.forcewrite = true -o.write = function(self, section) - start_stop_remove(m,"start") -end -o.disable = lost_state - -o = s:option(Button, "_restart") -o.template = "dockerman/cbi/inlinebutton" -o.inputtitle = translate("Restart") -o.inputstyle = "reload" -o.forcewrite = true -o.write = function(self, section) - start_stop_remove(m,"restart") -end -o.disable = lost_state - -o = s:option(Button, "_stop") -o.template = "dockerman/cbi/inlinebutton" -o.inputtitle = translate("Stop") -o.inputstyle = "reset" -o.forcewrite = true -o.write = function(self, section) - start_stop_remove(m,"stop") -end -o.disable = lost_state - -o = s:option(Button, "_kill") -o.template = "dockerman/cbi/inlinebutton" -o.inputtitle = translate("Kill") -o.inputstyle = "reset" -o.forcewrite = true -o.write = function(self, section) - start_stop_remove(m,"kill") -end -o.disable = lost_state - -o = s:option(Button, "_remove") -o.template = "dockerman/cbi/inlinebutton" -o.inputtitle = translate("Remove") -o.inputstyle = "remove" -o.forcewrite = true -o.write = function(self, section) - start_stop_remove(m, "remove") -end -o.disable = lost_state - -return m diff --git a/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua b/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua deleted file mode 100755 index c3d3eab0d..000000000 --- a/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua +++ /dev/null @@ -1,284 +0,0 @@ ---[[ -LuCI - Lua Configuration Interface -Copyright 2019 lisaac -]]-- - -local docker = require "luci.model.docker" -local dk = docker.new() - -local containers, images, res, lost_state -local m, s, o - -if dk:_ping().code ~= 200 then - lost_state = true -else - res = dk.images:list() - if res and res.code and res.code < 300 then - images = res.body - end - - res = dk.containers:list({ query = { all = true } }) - if res and res.code and res.code < 300 then - containers = res.body - end -end - -function get_images() - local data = {} - - for i, v in ipairs(images) do - local index = v.Created .. v.Id - - data[index]={} - data[index]["_selected"] = 0 - data[index]["id"] = v.Id:sub(8) - data[index]["_id"] = '' .. v.Id:sub(8,20) .. '' - - if v.RepoTags and next(v.RepoTags)~=nil then - for i, v1 in ipairs(v.RepoTags) do - data[index]["_tags"] =(data[index]["_tags"] and ( data[index]["_tags"] .. "
" )or "") .. ((v1:match("") or (#v.RepoTags == 1)) and v1 or ('' .. v1 .. '')) - - if not data[index]["tag"] then - data[index]["tag"] = v1 - end - end - else - data[index]["_tags"] = v.RepoDigests[1] and v.RepoDigests[1]:match("^(.-)@.+") - data[index]["_tags"] = (data[index]["_tags"] and data[index]["_tags"] or "" ).. ":" - end - - data[index]["_tags"] = data[index]["_tags"]:gsub("","<none>") - for ci,cv in ipairs(containers) do - if v.Id == cv.ImageID then - data[index]["_containers"] = (data[index]["_containers"] and (data[index]["_containers"] .. " | ") or "").. - ''.. cv.Names[1]:sub(2).."" - end - end - - data[index]["_size"] = string.format("%.2f", tostring(v.Size/1024/1024)).."MB" - data[index]["_created"] = os.date("%Y/%m/%d %H:%M:%S",v.Created) - end - - return data -end - -local image_list = not lost_state and get_images() or {} - -m = SimpleForm("docker", - translate("Docker - Images"), - translate("On this page all images are displayed that are available on the system and with which a container can be created.")) -m.submit=false -m.reset=false - -local pull_value={ - _image_tag_name="", - _registry="index.docker.io" -} - -s = m:section(SimpleSection, - translate("Pull Image"), - translate("By entering a valid image name with the corresponding version, the docker image can be downloaded from the configured registry.")) -s.template="cbi/nullsection" - -o = s:option(Value, "_image_tag_name") -o.template = "dockerman/cbi/inlinevalue" -o.placeholder="lisaac/luci:latest" -o.write = function(self, section, value) - local hastag = value:find(":") - - if not hastag then - value = value .. ":latest" - end - pull_value["_image_tag_name"] = value -end - -o = s:option(Button, "_pull") -o.inputtitle= translate("Pull") -o.template = "dockerman/cbi/inlinebutton" -o.inputstyle = "add" -o.disable = lost_state -o.write = function(self, section) - local tag = pull_value["_image_tag_name"] - local json_stringify = luci.jsonc and luci.jsonc.stringify - - if tag and tag ~= "" then - docker:write_status("Images: " .. "pulling" .. " " .. tag .. "...\n") - local res = dk.images:create({query = {fromImage=tag}}, docker.pull_image_show_status_cb) - - if res and res.code and res.code == 200 and (res.body[#res.body] and not res.body[#res.body].error and res.body[#res.body].status and (res.body[#res.body].status == "Status: Downloaded newer image for ".. tag)) then - docker:clear_status() - else - docker:append_status("code:" .. res.code.." ".. (res.body[#res.body] and res.body[#res.body].error or (res.body.message or res.message)).. "\n") - end - else - docker:append_status("code: 400 please input the name of image name!") - end - - luci.http.redirect(luci.dispatcher.build_url("admin/docker/images")) -end - -s = m:section(SimpleSection, - translate("Import Image"), - translate("When pressing the Import button, both a local image can be loaded onto the system and a valid image tar can be downloaded from remote.")) - -o = s:option(DummyValue, "_image_import") -o.template = "dockerman/images_import" -o.disable = lost_state - -s = m:section(Table, image_list, translate("Images overview")) - -o = s:option(Flag, "_selected","") -o.disabled = 0 -o.enabled = 1 -o.default = 0 -o.write = function(self, section, value) - image_list[section]._selected = value -end - -o = s:option(DummyValue, "_id", translate("ID")) -o.rawhtml = true - -o = s:option(DummyValue, "_tags", translate("RepoTags")) -o.rawhtml = true - -o = s:option(DummyValue, "_containers", translate("Containers")) -o.rawhtml = true - -o = s:option(DummyValue, "_size", translate("Size")) - -o = s:option(DummyValue, "_created", translate("Created")) - -local remove_action = function(force) - local image_selected = {} - - for k in pairs(image_list) do - if image_list[k]._selected == 1 then - image_selected[#image_selected+1] = (image_list[k]["_tags"]:match("
") or image_list[k]["_tags"]:match("<none>")) and image_list[k].id or image_list[k].tag - end - end - - if next(image_selected) ~= nil then - local success = true - - docker:clear_status() - for _, img in ipairs(image_selected) do - local query - docker:append_status("Images: " .. "remove" .. " " .. img .. "...") - - if force then - query = {force = true} - end - - local msg = dk.images:remove({ - id = img, - query = query - }) - if msg and msg.code ~= 200 then - docker:append_status("code:" .. msg.code.." ".. (msg.body.message and msg.body.message or msg.message).. "\n") - success = false - else - docker:append_status("done\n") - end - end - - if success then - docker:clear_status() - end - - luci.http.redirect(luci.dispatcher.build_url("admin/docker/images")) - end -end - -s = m:section(SimpleSection) -s.template = "dockerman/apply_widget" -s.err = docker:read_status() -s.err = s.err and s.err:gsub("\n","
"):gsub(" "," ") -if s.err then - docker:clear_status() -end - -s = m:section(Table,{{}}) -s.notitle=true -s.rowcolors=false -s.template="cbi/nullsection" - -o = s:option(Button, "remove") -o.inputtitle= translate("Remove") -o.template = "dockerman/cbi/inlinebutton" -o.inputstyle = "remove" -o.forcewrite = true -o.write = function(self, section) - remove_action() -end -o.disable = lost_state - -o = s:option(Button, "forceremove") -o.inputtitle= translate("Force Remove") -o.template = "dockerman/cbi/inlinebutton" -o.inputstyle = "remove" -o.forcewrite = true -o.write = function(self, section) - remove_action(true) -end -o.disable = lost_state - -o = s:option(Button, "save") -o.inputtitle= translate("Save") -o.template = "dockerman/cbi/inlinebutton" -o.inputstyle = "edit" -o.disable = lost_state -o.forcewrite = true -o.write = function (self, section) - local image_selected = {} - - for k in pairs(image_list) do - if image_list[k]._selected == 1 then - image_selected[#image_selected + 1] = image_list[k].id - end - end - - if next(image_selected) ~= nil then - local names, first, show_name - - for _, img in ipairs(image_selected) do - names = names and (names .. "&names=".. img) or img - end - if #image_selected > 1 then - show_name = "images" - else - show_name = image_selected[1] - end - local cb = function(res, chunk) - if res and res.code and res.code == 200 then - if not first then - first = true - luci.http.header('Content-Disposition', 'inline; filename="'.. show_name .. '.tar"') - luci.http.header('Content-Type', 'application\/x-tar') - end - luci.ltn12.pump.all(chunk, luci.http.write) - else - if not first then - first = true - luci.http.prepare_content("text/plain") - end - luci.ltn12.pump.all(chunk, luci.http.write) - end - end - - docker:write_status("Images: " .. "save" .. " " .. table.concat(image_selected, "\n") .. "...") - local msg = dk.images:get({query = {names = names}}, cb) - if msg and msg.code and msg.code ~= 200 then - docker:append_status("code:" .. msg.code.." ".. (msg.body.message and msg.body.message or msg.message).. "\n") - else - docker:clear_status() - end - end -end - -o = s:option(Button, "load") -o.inputtitle= translate("Load") -o.template = "dockerman/images_load" -o.inputstyle = "add" -o.disable = lost_state - -return m diff --git a/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua b/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua deleted file mode 100755 index 37702c783..000000000 --- a/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua +++ /dev/null @@ -1,159 +0,0 @@ ---[[ -LuCI - Lua Configuration Interface -Copyright 2019 lisaac -]]-- - -local docker = require "luci.model.docker" - -local m, s, o -local networks, dk, res, lost_state - -dk = docker.new() - -if dk:_ping().code ~= 200 then - lost_state = true -else - res = dk.networks:list() - if res and res.code and res.code < 300 then - networks = res.body - end -end - -local get_networks = function () - local data = {} - - if type(networks) ~= "table" then - return nil - end - - for i, v in ipairs(networks) do - local index = v.Created .. v.Id - - data[index]={} - data[index]["_selected"] = 0 - data[index]["_id"] = v.Id:sub(1,12) - data[index]["_name"] = v.Name - data[index]["_driver"] = v.Driver - - if v.Driver == "bridge" then - data[index]["_interface"] = v.Options["com.docker.network.bridge.name"] - elseif v.Driver == "macvlan" then - data[index]["_interface"] = v.Options.parent - end - - data[index]["_subnet"] = v.IPAM and v.IPAM.Config[1] and v.IPAM.Config[1].Subnet or nil - data[index]["_gateway"] = v.IPAM and v.IPAM.Config[1] and v.IPAM.Config[1].Gateway or nil - end - - return data -end - -local network_list = not lost_state and get_networks() or {} - -m = SimpleForm("docker", - translate("Docker - Networks"), - translate("This page displays all docker networks that have been created on the connected docker host.")) -m.submit=false -m.reset=false - -s = m:section(Table, network_list, translate("Networks overview")) -s.nodescr=true - -o = s:option(Flag, "_selected","") -o.template = "dockerman/cbi/xfvalue" -o.disabled = 0 -o.enabled = 1 -o.default = 0 -o.render = function(self, section, scope) - self.disable = 0 - if network_list[section]["_name"] == "bridge" or network_list[section]["_name"] == "none" or network_list[section]["_name"] == "host" then - self.disable = 1 - end - Flag.render(self, section, scope) -end -o.write = function(self, section, value) - network_list[section]._selected = value -end - -o = s:option(DummyValue, "_id", translate("ID")) - -o = s:option(DummyValue, "_name", translate("Network Name")) - -o = s:option(DummyValue, "_driver", translate("Driver")) - -o = s:option(DummyValue, "_interface", translate("Parent Interface")) - -o = s:option(DummyValue, "_subnet", translate("Subnet")) - -o = s:option(DummyValue, "_gateway", translate("Gateway")) - -s = m:section(SimpleSection) -s.template = "dockerman/apply_widget" -s.err = docker:read_status() -s.err = s.err and s.err:gsub("\n","
"):gsub(" "," ") -if s.err then - docker:clear_status() -end - -s = m:section(Table,{{}}) -s.notitle=true -s.rowcolors=false -s.template="cbi/nullsection" - -o = s:option(Button, "_new") -o.inputtitle= translate("New") -o.template = "dockerman/cbi/inlinebutton" -o.notitle=true -o.inputstyle = "add" -o.forcewrite = true -o.disable = lost_state -o.write = function(self, section) - luci.http.redirect(luci.dispatcher.build_url("admin/docker/newnetwork")) -end - -o = s:option(Button, "_remove") -o.inputtitle= translate("Remove") -o.template = "dockerman/cbi/inlinebutton" -o.inputstyle = "remove" -o.forcewrite = true -o.disable = lost_state -o.write = function(self, section) - local network_selected = {} - local network_name_selected = {} - local network_driver_selected = {} - - for k in pairs(network_list) do - if network_list[k]._selected == 1 then - network_selected[#network_selected + 1] = network_list[k]._id - network_name_selected[#network_name_selected + 1] = network_list[k]._name - network_driver_selected[#network_driver_selected + 1] = network_list[k]._driver - end - end - - if next(network_selected) ~= nil then - local success = true - docker:clear_status() - - for ii, net in ipairs(network_selected) do - docker:append_status("Networks: " .. "remove" .. " " .. net .. "...") - local res = dk.networks["remove"](dk, {id = net}) - - if res and res.code and res.code >= 300 then - docker:append_status("code:" .. res.code.." ".. (res.body.message and res.body.message or res.message).. "\n") - success = false - else - docker:append_status("done\n") - if network_driver_selected[ii] == "macvlan" then - docker.remove_macvlan_interface(network_name_selected[ii]) - end - end - end - - if success then - docker:clear_status() - end - luci.http.redirect(luci.dispatcher.build_url("admin/docker/networks")) - end -end - -return m diff --git a/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua b/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua deleted file mode 100755 index bfd1bf2a1..000000000 --- a/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua +++ /dev/null @@ -1,923 +0,0 @@ ---[[ -LuCI - Lua Configuration Interface -Copyright 2019 lisaac -]]-- - -local docker = require "luci.model.docker" - -local m, s, o - -local dk = docker.new() - -local cmd_line = table.concat(arg, '/') -local images, networks -local create_body = {} - -if dk:_ping().code ~= 200 then - lost_state = true - images = {} - networks = {} -else - images = dk.images:list().body - networks = dk.networks:list().body -end - -local is_quot_complete = function(str) - local num = 0, w - require "math" - - if not str then - return true - end - - local num = 0, w - for w in str:gmatch("\"") do - num = num + 1 - end - - if math.fmod(num, 2) ~= 0 then - return false - end - - num = 0 - for w in str:gmatch("\'") do - num = num + 1 - end - - if math.fmod(num, 2) ~= 0 then - return false - end - - return true -end - -function contains(list, x) - for _, v in pairs(list) do - if v == x then - return true - end - end - return false -end - -local resolve_cli = function(cmd_line) - local config = { - advance = 1 - } - - local key_no_val = { - 't', - 'd', - 'i', - 'tty', - 'rm', - 'read_only', - 'interactive', - 'init', - 'help', - 'detach', - 'privileged', - 'P', - 'publish_all', - } - - local key_with_val = { - 'sysctl', - 'add_host', - 'a', - 'attach', - 'blkio_weight_device', - 'cap_add', - 'cap_drop', - 'device', - 'device_cgroup_rule', - 'device_read_bps', - 'device_read_iops', - 'device_write_bps', - 'device_write_iops', - 'dns', - 'dns_option', - 'dns_search', - 'e', - 'env', - 'env_file', - 'expose', - 'group_add', - 'l', - 'label', - 'label_file', - 'link', - 'link_local_ip', - 'log_driver', - 'log_opt', - 'network_alias', - 'p', - 'publish', - 'security_opt', - 'storage_opt', - 'tmpfs', - 'v', - 'volume', - 'volumes_from', - 'blkio_weight', - 'cgroup_parent', - 'cidfile', - 'cpu_period', - 'cpu_quota', - 'cpu_rt_period', - 'cpu_rt_runtime', - 'c', - 'cpu_shares', - 'cpus', - 'cpuset_cpus', - 'cpuset_mems', - 'detach_keys', - 'disable_content_trust', - 'domainname', - 'entrypoint', - 'gpus', - 'health_cmd', - 'health_interval', - 'health_retries', - 'health_start_period', - 'health_timeout', - 'h', - 'hostname', - 'ip', - 'ip6', - 'ipc', - 'isolation', - 'kernel_memory', - 'mac_address', - 'm', - 'memory', - 'memory_reservation', - 'memory_swap', - 'memory_swappiness', - 'mount', - 'name', - 'network', - 'no_healthcheck', - 'oom_kill_disable', - 'oom_score_adj', - 'pid', - 'pids_limit', - 'restart', - 'runtime', - 'shm_size', - 'sig_proxy', - 'stop_signal', - 'stop_timeout', - 'ulimit', - 'u', - 'user', - 'userns', - 'uts', - 'volume_driver', - 'w', - 'workdir' - } - - local key_abb = { - net='network', - a='attach', - c='cpu-shares', - d='detach', - e='env', - h='hostname', - i='interactive', - l='label', - m='memory', - p='publish', - P='publish_all', - t='tty', - u='user', - v='volume', - w='workdir' - } - - local key_with_list = { - 'sysctl', - 'add_host', - 'a', - 'attach', - 'blkio_weight_device', - 'cap_add', - 'cap_drop', - 'device', - 'device_cgroup_rule', - 'device_read_bps', - 'device_read_iops', - 'device_write_bps', - 'device_write_iops', - 'dns', - 'dns_optiondns_search', - 'e', - 'env', - 'env_file', - 'expose', - 'group_add', - 'l', - 'label', - 'label_file', - 'link', - 'link_local_ip', - 'log_opt', - 'network_alias', - 'p', - 'publish', - 'security_opt', - 'storage_opt', - 'tmpfs', - 'v', - 'volume', - 'volumes_from', - } - - local key = nil - local _key = nil - local val = nil - local is_cmd = false - - cmd_line = cmd_line:match("^DOCKERCLI%s+(.+)") - for w in cmd_line:gmatch("[^%s]+") do - if w =='\\' then - elseif not key and not _key and not is_cmd then - --key=val - key, val = w:match("^%-%-([%lP%-]-)=(.+)") - if not key then - --key val - key = w:match("^%-%-([%lP%-]+)") - if not key then - -- -v val - key = w:match("^%-([%lP%-]+)") - if key then - -- for -dit - if key:match("i") or key:match("t") or key:match("d") then - if key:match("i") then - config[key_abb["i"]] = true - key:gsub("i", "") - end - if key:match("t") then - config[key_abb["t"]] = true - key:gsub("t", "") - end - if key:match("d") then - config[key_abb["d"]] = true - key:gsub("d", "") - end - if key:match("P") then - config[key_abb["P"]] = true - key:gsub("P", "") - end - if key == "" then - key = nil - end - end - end - end - end - if key then - key = key:gsub("-","_") - key = key_abb[key] or key - if contains(key_no_val, key) then - config[key] = true - val = nil - key = nil - elseif contains(key_with_val, key) then - -- if key == "cap_add" then config.privileged = true end - else - key = nil - val = nil - end - else - config.image = w - key = nil - val = nil - is_cmd = true - end - elseif (key or _key) and not is_cmd then - if key == "mount" then - -- we need resolve mount options here - -- type=bind,source=/source,target=/app - local _type = w:match("^type=([^,]+),") or "bind" - local source = (_type ~= "tmpfs") and (w:match("source=([^,]+),") or w:match("src=([^,]+),")) or "" - local target = w:match(",target=([^,]+)") or w:match(",dst=([^,]+)") or w:match(",destination=([^,]+)") or "" - local ro = w:match(",readonly") and "ro" or nil - - if source and target then - if _type ~= "tmpfs" then - local bind_propagation = (_type == "bind") and w:match(",bind%-propagation=([^,]+)") or nil - val = source..":"..target .. ((ro or bind_propagation) and (":" .. (ro and ro or "") .. (((ro and bind_propagation) and "," or "") .. (bind_propagation and bind_propagation or ""))or "")) - else - local tmpfs_mode = w:match(",tmpfs%-mode=([^,]+)") or nil - local tmpfs_size = w:match(",tmpfs%-size=([^,]+)") or nil - key = "tmpfs" - val = target .. ((tmpfs_mode or tmpfs_size) and (":" .. (tmpfs_mode and ("mode=" .. tmpfs_mode) or "") .. ((tmpfs_mode and tmpfs_size) and "," or "") .. (tmpfs_size and ("size=".. tmpfs_size) or "")) or "") - if not config[key] then - config[key] = {} - end - table.insert( config[key], val ) - key = nil - val = nil - end - end - else - val = w - end - elseif is_cmd then - config["command"] = (config["command"] and (config["command"] .. " " )or "") .. w - end - if (key or _key) and val then - key = _key or key - if contains(key_with_list, key) then - if not config[key] then - config[key] = {} - end - if _key then - config[key][#config[key]] = config[key][#config[key]] .. " " .. w - else - table.insert( config[key], val ) - end - if is_quot_complete(config[key][#config[key]]) then - config[key][#config[key]] = config[key][#config[key]]:gsub("[\"\']", "") - _key = nil - else - _key = key - end - else - config[key] = (config[key] and (config[key] .. " ") or "") .. val - if is_quot_complete(config[key]) then - config[key] = config[key]:gsub("[\"\']", "") - _key = nil - else - _key = key - end - end - key = nil - val = nil - end - end - - return config -end - -local default_config = {} - -if cmd_line and cmd_line:match("^DOCKERCLI.+") then - default_config = resolve_cli(cmd_line) -elseif cmd_line and cmd_line:match("^duplicate/[^/]+$") then - local container_id = cmd_line:match("^duplicate/(.+)") - create_body = dk:containers_duplicate_config({id = container_id}) or {} - if not create_body.HostConfig then - create_body.HostConfig = {} - end - - if next(create_body) ~= nil then - default_config.name = nil - default_config.image = create_body.Image - default_config.hostname = create_body.Hostname - default_config.tty = create_body.Tty and true or false - default_config.interactive = create_body.OpenStdin and true or false - default_config.privileged = create_body.HostConfig.Privileged and true or false - default_config.restart = create_body.HostConfig.RestartPolicy and create_body.HostConfig.RestartPolicy.name or nil - -- default_config.network = create_body.HostConfig.NetworkMode == "default" and "bridge" or create_body.HostConfig.NetworkMode - -- if container has leave original network, and add new network, .HostConfig.NetworkMode is INcorrect, so using first child of .NetworkingConfig.EndpointsConfig - default_config.network = create_body.NetworkingConfig and create_body.NetworkingConfig.EndpointsConfig and next(create_body.NetworkingConfig.EndpointsConfig) or nil - default_config.ip = default_config.network and default_config.network ~= "bridge" and default_config.network ~= "host" and default_config.network ~= "null" and create_body.NetworkingConfig.EndpointsConfig[default_config.network].IPAMConfig and create_body.NetworkingConfig.EndpointsConfig[default_config.network].IPAMConfig.IPv4Address or nil - default_config.link = create_body.HostConfig.Links - default_config.env = create_body.Env - default_config.dns = create_body.HostConfig.Dns - default_config.volume = create_body.HostConfig.Binds - default_config.cap_add = create_body.HostConfig.CapAdd - default_config.publish_all = create_body.HostConfig.PublishAllPorts - - if create_body.HostConfig.Sysctls and type(create_body.HostConfig.Sysctls) == "table" then - default_config.sysctl = {} - for k, v in pairs(create_body.HostConfig.Sysctls) do - table.insert( default_config.sysctl, k.."="..v ) - end - end - if create_body.HostConfig.LogConfig then - if create_body.HostConfig.LogConfig.Config and type(create_body.HostConfig.LogConfig.Config) == "table" then - default_config.log_opt = {} - for k, v in pairs(create_body.HostConfig.LogConfig.Config) do - table.insert( default_config.log_opt, k.."="..v ) - end - end - default_config.log_driver = create_body.HostConfig.LogConfig.Type or nil - end - - if create_body.HostConfig.PortBindings and type(create_body.HostConfig.PortBindings) == "table" then - default_config.publish = {} - for k, v in pairs(create_body.HostConfig.PortBindings) do - for x, y in ipairs(v) do - table.insert( default_config.publish, y.HostPort..":"..k:match("^(%d+)/.+").."/"..k:match("^%d+/(.+)") ) - end - end - end - - default_config.user = create_body.User or nil - default_config.command = create_body.Cmd and type(create_body.Cmd) == "table" and table.concat(create_body.Cmd, " ") or nil - default_config.advance = 1 - default_config.cpus = create_body.HostConfig.NanoCPUs - default_config.cpu_shares = create_body.HostConfig.CpuShares - default_config.memory = create_body.HostConfig.Memory - default_config.blkio_weight = create_body.HostConfig.BlkioWeight - - if create_body.HostConfig.Devices and type(create_body.HostConfig.Devices) == "table" then - default_config.device = {} - for _, v in ipairs(create_body.HostConfig.Devices) do - table.insert( default_config.device, v.PathOnHost..":"..v.PathInContainer..(v.CgroupPermissions ~= "" and (":" .. v.CgroupPermissions) or "") ) - end - end - - if create_body.HostConfig.Tmpfs and type(create_body.HostConfig.Tmpfs) == "table" then - default_config.tmpfs = {} - for k, v in pairs(create_body.HostConfig.Tmpfs) do - table.insert( default_config.tmpfs, k .. (v~="" and ":" or "")..v ) - end - end - end -end - -m = SimpleForm("docker", translate("Docker - Containers")) -m.redirect = luci.dispatcher.build_url("admin", "docker", "containers") -if lost_state then - m.submit=false - m.reset=false -end - -s = m:section(SimpleSection) -s.template = "dockerman/apply_widget" -s.err=docker:read_status() -s.err=s.err and s.err:gsub("\n","
"):gsub(" "," ") -if s.err then - docker:clear_status() -end - -s = m:section(SimpleSection, translate("Create new docker container")) -s.addremove = true -s.anonymous = true - -o = s:option(DummyValue,"cmd_line", translate("Resolve CLI")) -o.rawhtml = true -o.template = "dockerman/newcontainer_resolve" - -o = s:option(Value, "name", translate("Container Name")) -o.rmempty = true -o.default = default_config.name or nil - -o = s:option(Flag, "interactive", translate("Interactive (-i)")) -o.rmempty = true -o.disabled = 0 -o.enabled = 1 -o.default = default_config.interactive and 1 or 0 - -o = s:option(Flag, "tty", translate("TTY (-t)")) -o.rmempty = true -o.disabled = 0 -o.enabled = 1 -o.default = default_config.tty and 1 or 0 - -o = s:option(Value, "image", translate("Docker Image")) -o.rmempty = true -o.default = default_config.image or nil -for _, v in ipairs (images) do - if v.RepoTags then - o:value(v.RepoTags[1], v.RepoTags[1]) - end -end - -o = s:option(Flag, "_force_pull", translate("Always pull image first")) -o.rmempty = true -o.disabled = 0 -o.enabled = 1 -o.default = 0 - -o = s:option(Flag, "privileged", translate("Privileged")) -o.rmempty = true -o.disabled = 0 -o.enabled = 1 -o.default = default_config.privileged and 1 or 0 - -o = s:option(ListValue, "restart", translate("Restart Policy")) -o.rmempty = true -o:value("no", "No") -o:value("unless-stopped", "Unless stopped") -o:value("always", "Always") -o:value("on-failure", "On failure") -o.default = default_config.restart or "unless-stopped" - -local d_network = s:option(ListValue, "network", translate("Networks")) -d_network.rmempty = true -d_network.default = default_config.network or "bridge" - -local d_ip = s:option(Value, "ip", translate("IPv4 Address")) -d_ip.datatype="ip4addr" -d_ip:depends("network", "nil") -d_ip.default = default_config.ip or nil - -o = s:option(DynamicList, "link", translate("Links with other containers")) -o.placeholder = "container_name:alias" -o.rmempty = true -o:depends("network", "bridge") -o.default = default_config.link or nil - -o = s:option(DynamicList, "dns", translate("Set custom DNS servers")) -o.placeholder = "8.8.8.8" -o.rmempty = true -o.default = default_config.dns or nil - -o = s:option(Value, "user", - translate("User(-u)"), - translate("The user that commands are run as inside the container.(format: name|uid[:group|gid])")) -o.placeholder = "1000:1000" -o.rmempty = true -o.default = default_config.user or nil - -o = s:option(DynamicList, "env", - translate("Environmental Variable(-e)"), - translate("Set environment variables to inside the container")) -o.placeholder = "TZ=Asia/Shanghai" -o.rmempty = true -o.default = default_config.env or nil - -o = s:option(DynamicList, "volume", - translate("Bind Mount(-v)"), - translate("Bind mount a volume")) -o.placeholder = "/media:/media:slave" -o.rmempty = true -o.default = default_config.volume or nil - -local d_publish = s:option(DynamicList, "publish", - translate("Exposed Ports(-p)"), - translate("Publish container's port(s) to the host")) -d_publish.placeholder = "2200:22/tcp" -d_publish.rmempty = true -d_publish.default = default_config.publish or nil - -o = s:option(Value, "command", translate("Run command")) -o.placeholder = "/bin/sh init.sh" -o.rmempty = true -o.default = default_config.command or nil - -o = s:option(Flag, "advance", translate("Advance")) -o.rmempty = true -o.disabled = 0 -o.enabled = 1 -o.default = default_config.advance or 0 - -o = s:option(Value, "hostname", - translate("Host Name"), - translate("The hostname to use for the container")) -o.rmempty = true -o.default = default_config.hostname or nil -o:depends("advance", 1) - -o = s:option(Flag, "publish_all", - translate("Exposed All Ports(-P)"), - translate("Allocates an ephemeral host port for all of a container's exposed ports")) -o.rmempty = true -o.disabled = 0 -o.enabled = 1 -o.default = default_config.publish_all and 1 or 0 -o:depends("advance", 1) - -o = s:option(DynamicList, "device", - translate("Device(--device)"), - translate("Add host device to the container")) -o.placeholder = "/dev/sda:/dev/xvdc:rwm" -o.rmempty = true -o:depends("advance", 1) -o.default = default_config.device or nil - -o = s:option(DynamicList, "tmpfs", - translate("Tmpfs(--tmpfs)"), - translate("Mount tmpfs directory")) -o.placeholder = "/run:rw,noexec,nosuid,size=65536k" -o.rmempty = true -o:depends("advance", 1) -o.default = default_config.tmpfs or nil - -o = s:option(DynamicList, "sysctl", - translate("Sysctl(--sysctl)"), - translate("Sysctls (kernel parameters) options")) -o.placeholder = "net.ipv4.ip_forward=1" -o.rmempty = true -o:depends("advance", 1) -o.default = default_config.sysctl or nil - -o = s:option(DynamicList, "cap_add", - translate("CAP-ADD(--cap-add)"), - translate("A list of kernel capabilities to add to the container")) -o.placeholder = "NET_ADMIN" -o.rmempty = true -o:depends("advance", 1) -o.default = default_config.cap_add or nil - -o = s:option(Value, "cpus", - translate("CPUs"), - translate("Number of CPUs. Number is a fractional number. 0.000 means no limit")) -o.placeholder = "1.5" -o.rmempty = true -o:depends("advance", 1) -o.datatype="ufloat" -o.default = default_config.cpus or nil - -o = s:option(Value, "cpu_shares", - translate("CPU Shares Weight"), - translate("CPU shares relative weight, if 0 is set, the system will ignore the value and use the default of 1024")) -o.placeholder = "1024" -o.rmempty = true -o:depends("advance", 1) -o.datatype="uinteger" -o.default = default_config.cpu_shares or nil - -o = s:option(Value, "memory", - translate("Memory"), - translate("Memory limit (format: []). Number is a positive integer. Unit can be one of b, k, m, or g. Minimum is 4M")) -o.placeholder = "128m" -o.rmempty = true -o:depends("advance", 1) -o.default = default_config.memory or nil - -o = s:option(Value, "blkio_weight", - translate("Block IO Weight"), - translate("Block IO weight (relative weight) accepts a weight value between 10 and 1000")) -o.placeholder = "500" -o.rmempty = true -o:depends("advance", 1) -o.datatype="uinteger" -o.default = default_config.blkio_weight or nil - -o = s:option(Value, "log_driver", - translate("Logging driver"), - translate("The logging driver for the container")) -o.placeholder = "json-file" -o.rmempty = true -o:depends("advance", 1) -o.default = default_config.log_driver or nil - -o = s:option(DynamicList, "log_opt", - translate("Log driver options"), - translate("The logging configuration for this container")) -o.placeholder = "max-size=1m" -o.rmempty = true -o:depends("advance", 1) -o.default = default_config.log_opt or nil - -for _, v in ipairs (networks) do - if v.Name then - local parent = v.Options and v.Options.parent or nil - local ip = v.IPAM and v.IPAM.Config and v.IPAM.Config[1] and v.IPAM.Config[1].Subnet or nil - ipv6 = v.IPAM and v.IPAM.Config and v.IPAM.Config[2] and v.IPAM.Config[2].Subnet or nil - local network_name = v.Name .. " | " .. v.Driver .. (parent and (" | " .. parent) or "") .. (ip and (" | " .. ip) or "").. (ipv6 and (" | " .. ipv6) or "") - d_network:value(v.Name, network_name) - - if v.Name ~= "none" and v.Name ~= "bridge" and v.Name ~= "host" then - d_ip:depends("network", v.Name) - end - - if v.Driver == "bridge" then - d_publish:depends("network", v.Name) - end - end -end - -m.handle = function(self, state, data) - if state ~= FORM_VALID then - return - end - - local tmp - local name = data.name or ("luci_" .. os.date("%Y%m%d%H%M%S")) - local hostname = data.hostname - local tty = type(data.tty) == "number" and (data.tty == 1 and true or false) or default_config.tty or false - local publish_all = type(data.publish_all) == "number" and (data.publish_all == 1 and true or false) or default_config.publish_all or false - local interactive = type(data.interactive) == "number" and (data.interactive == 1 and true or false) or default_config.interactive or false - local image = data.image - local user = data.user - - if image and not image:match(".-:.+") then - image = image .. ":latest" - end - - local privileged = type(data.privileged) == "number" and (data.privileged == 1 and true or false) or default_config.privileged or false - local restart = data.restart - local env = data.env - local dns = data.dns - local cap_add = data.cap_add - local sysctl = {} - local log_driver = data.log_driver - - tmp = data.sysctl - if type(tmp) == "table" then - for i, v in ipairs(tmp) do - local k,v1 = v:match("(.-)=(.+)") - if k and v1 then - sysctl[k]=v1 - end - end - end - - local log_opt = {} - tmp = data.log_opt - if type(tmp) == "table" then - for i, v in ipairs(tmp) do - local k,v1 = v:match("(.-)=(.+)") - if k and v1 then - log_opt[k]=v1 - end - end - end - - local network = data.network - local ip = (network ~= "bridge" and network ~= "host" and network ~= "none") and data.ip or nil - local volume = data.volume - local memory = data.memory or nil - local cpu_shares = data.cpu_shares or nil - local cpus = data.cpus or nil - local blkio_weight = data.blkio_weight or nil - - local portbindings = {} - local exposedports = {} - - local tmpfs = {} - tmp = data.tmpfs - if type(tmp) == "table" then - for i, v in ipairs(tmp)do - local k= v:match("([^:]+)") - local v1 = v:match(".-:([^:]+)") or "" - if k then - tmpfs[k]=v1 - end - end - end - - local device = {} - tmp = data.device - if type(tmp) == "table" then - for i, v in ipairs(tmp) do - local t = {} - local _,_, h, c, p = v:find("(.-):(.-):(.+)") - if h and c then - t['PathOnHost'] = h - t['PathInContainer'] = c - t['CgroupPermissions'] = p or "rwm" - else - local _,_, h, c = v:find("(.-):(.+)") - if h and c then - t['PathOnHost'] = h - t['PathInContainer'] = c - t['CgroupPermissions'] = "rwm" - else - t['PathOnHost'] = v - t['PathInContainer'] = v - t['CgroupPermissions'] = "rwm" - end - end - - if next(t) ~= nil then - table.insert( device, t ) - end - end - end - - tmp = data.publish or {} - for i, v in ipairs(tmp) do - for v1 ,v2 in string.gmatch(v, "(%d+):([^%s]+)") do - local _,_,p= v2:find("^%d+/(%w+)") - if p == nil then - v2=v2..'/tcp' - end - portbindings[v2] = {{HostPort=v1}} - exposedports[v2] = {HostPort=v1} - end - end - - local link = data.link - tmp = data.command - local command = {} - if tmp ~= nil then - for v in string.gmatch(tmp, "[^%s]+") do - command[#command+1] = v - end - end - - if memory and memory ~= 0 then - _,_,n,unit = memory:find("([%d%.]+)([%l%u]+)") - if n then - unit = unit and unit:sub(1,1):upper() or "B" - if unit == "M" then - memory = tonumber(n) * 1024 * 1024 - elseif unit == "G" then - memory = tonumber(n) * 1024 * 1024 * 1024 - elseif unit == "K" then - memory = tonumber(n) * 1024 - else - memory = tonumber(n) - end - end - end - - create_body.Hostname = network ~= "host" and (hostname or name) or nil - create_body.Tty = tty and true or false - create_body.OpenStdin = interactive and true or false - create_body.User = user - create_body.Cmd = command - create_body.Env = env - create_body.Image = image - create_body.ExposedPorts = exposedports - create_body.HostConfig = create_body.HostConfig or {} - create_body.HostConfig.Dns = dns - create_body.HostConfig.Binds = volume - create_body.HostConfig.RestartPolicy = { Name = restart, MaximumRetryCount = 0 } - create_body.HostConfig.Privileged = privileged and true or false - create_body.HostConfig.PortBindings = portbindings - create_body.HostConfig.Memory = memory and tonumber(memory) - create_body.HostConfig.CpuShares = cpu_shares and tonumber(cpu_shares) - create_body.HostConfig.NanoCPUs = cpus and tonumber(cpus) * 10 ^ 9 - create_body.HostConfig.BlkioWeight = blkio_weight and tonumber(blkio_weight) - create_body.HostConfig.PublishAllPorts = publish_all - - if create_body.HostConfig.NetworkMode ~= network then - create_body.NetworkingConfig = nil - end - - create_body.HostConfig.NetworkMode = network - - if ip then - if create_body.NetworkingConfig and create_body.NetworkingConfig.EndpointsConfig and type(create_body.NetworkingConfig.EndpointsConfig) == "table" then - for k, v in pairs (create_body.NetworkingConfig.EndpointsConfig) do - if k == network and v.IPAMConfig and v.IPAMConfig.IPv4Address then - v.IPAMConfig.IPv4Address = ip - else - create_body.NetworkingConfig.EndpointsConfig = { [network] = { IPAMConfig = { IPv4Address = ip } } } - end - break - end - else - create_body.NetworkingConfig = { EndpointsConfig = { [network] = { IPAMConfig = { IPv4Address = ip } } } } - end - elseif not create_body.NetworkingConfig then - create_body.NetworkingConfig = nil - end - - create_body["HostConfig"]["Tmpfs"] = tmpfs - create_body["HostConfig"]["Devices"] = device - create_body["HostConfig"]["Sysctls"] = sysctl - create_body["HostConfig"]["CapAdd"] = cap_add - create_body["HostConfig"]["LogConfig"] = { - Config = log_opt, - Type = log_driver - } - - if network == "bridge" then - create_body["HostConfig"]["Links"] = link - end - - local pull_image = function(image) - local json_stringify = luci.jsonc and luci.jsonc.stringify - docker:append_status("Images: " .. "pulling" .. " " .. image .. "...\n") - local res = dk.images:create({query = {fromImage=image}}, docker.pull_image_show_status_cb) - if res and res.code and res.code == 200 and (res.body[#res.body] and not res.body[#res.body].error and res.body[#res.body].status and (res.body[#res.body].status == "Status: Downloaded newer image for ".. image or res.body[#res.body].status == "Status: Image is up to date for ".. image)) then - docker:append_status("done\n") - else - res.code = (res.code == 200) and 500 or res.code - docker:append_status("code:" .. res.code.." ".. (res.body[#res.body] and res.body[#res.body].error or (res.body.message or res.message)).. "\n") - luci.http.redirect(luci.dispatcher.build_url("admin/docker/newcontainer")) - end - end - - docker:clear_status() - local exist_image = false - - if image then - for _, v in ipairs (images) do - if v.RepoTags and v.RepoTags[1] == image then - exist_image = true - break - end - end - if not exist_image then - pull_image(image) - elseif data._force_pull == 1 then - pull_image(image) - end - end - - create_body = docker.clear_empty_tables(create_body) - - docker:append_status("Container: " .. "create" .. " " .. name .. "...") - local res = dk.containers:create({name = name, body = create_body}) - if res and res.code and res.code == 201 then - docker:clear_status() - luci.http.redirect(luci.dispatcher.build_url("admin/docker/containers")) - else - docker:append_status("code:" .. res.code.." ".. (res.body.message and res.body.message or res.message)) - luci.http.redirect(luci.dispatcher.build_url("admin/docker/newcontainer")) - end -end - -return m diff --git a/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua b/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua deleted file mode 100755 index c87678b85..000000000 --- a/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua +++ /dev/null @@ -1,258 +0,0 @@ ---[[ -LuCI - Lua Configuration Interface -Copyright 2019 lisaac -]]-- - -local docker = require "luci.model.docker" - -local m, s, o - -local dk = docker.new() -if dk:_ping().code ~= 200 then - lost_state = true -end - -m = SimpleForm("docker", translate("Docker - Network")) -m.redirect = luci.dispatcher.build_url("admin", "docker", "networks") -if lost_state then - m.submit=false - m.reset=false -end - - -s = m:section(SimpleSection) -s.template = "dockerman/apply_widget" -s.err=docker:read_status() -s.err=s.err and s.err:gsub("\n","
"):gsub(" "," ") -if s.err then - docker:clear_status() -end - -s = m:section(SimpleSection, translate("Create new docker network")) -s.addremove = true -s.anonymous = true - -o = s:option(Value, "name", - translate("Network Name"), - translate("Name of the network that can be selected during container creation")) -o.rmempty = true - -o = s:option(ListValue, "driver", translate("Driver")) -o.rmempty = true -o:value("bridge", translate("Bridge device")) -o:value("macvlan", translate("MAC VLAN")) -o:value("ipvlan", translate("IP VLAN")) -o:value("overlay", translate("Overlay network")) - -o = s:option(Value, "parent", translate("Base device")) -o.rmempty = true -o:depends("driver", "macvlan") -local interfaces = luci.sys and luci.sys.net and luci.sys.net.devices() or {} -for _, v in ipairs(interfaces) do - o:value(v, v) -end -o.default="br-lan" -o.placeholder="br-lan" - -o = s:option(ListValue, "macvlan_mode", translate("Mode")) -o.rmempty = true -o:depends("driver", "macvlan") -o.default="bridge" -o:value("bridge", translate("Bridge (Support direct communication between MAC VLANs)")) -o:value("private", translate("Private (Prevent communication between MAC VLANs)")) -o:value("vepa", translate("VEPA (Virtual Ethernet Port Aggregator)")) -o:value("passthru", translate("Pass-through (Mirror physical device to single MAC VLAN)")) - -o = s:option(ListValue, "ipvlan_mode", translate("Ipvlan Mode")) -o.rmempty = true -o:depends("driver", "ipvlan") -o.default="l3" -o:value("l2", translate("L2 bridge")) -o:value("l3", translate("L3 bridge")) - -o = s:option(Flag, "ingress", - translate("Ingress"), - translate("Ingress network is the network which provides the routing-mesh in swarm mode")) -o.rmempty = true -o.disabled = 0 -o.enabled = 1 -o.default = 0 -o:depends("driver", "overlay") - -o = s:option(DynamicList, "options", translate("Options")) -o.rmempty = true -o.placeholder="com.docker.network.driver.mtu=1500" - -o = s:option(Flag, "internal", translate("Internal"), translate("Restrict external access to the network")) -o.rmempty = true -o:depends("driver", "overlay") -o.disabled = 0 -o.enabled = 1 -o.default = 0 - -if nixio.fs.access("/etc/config/network") and nixio.fs.access("/etc/config/firewall")then - o = s:option(Flag, "op_macvlan", translate("Create macvlan interface"), translate("Auto create macvlan interface in Openwrt")) - o:depends("driver", "macvlan") - o.disabled = 0 - o.enabled = 1 - o.default = 1 -end - -o = s:option(Value, "subnet", translate("Subnet")) -o.rmempty = true -o.placeholder="10.1.0.0/16" -o.datatype="ip4addr" - -o = s:option(Value, "gateway", translate("Gateway")) -o.rmempty = true -o.placeholder="10.1.1.1" -o.datatype="ip4addr" - -o = s:option(Value, "ip_range", translate("IP range")) -o.rmempty = true -o.placeholder="10.1.1.0/24" -o.datatype="ip4addr" - -o = s:option(DynamicList, "aux_address", translate("Exclude IPs")) -o.rmempty = true -o.placeholder="my-route=10.1.1.1" - -o = s:option(Flag, "ipv6", translate("Enable IPv6")) -o.rmempty = true -o.disabled = 0 -o.enabled = 1 -o.default = 0 - -o = s:option(Value, "subnet6", translate("IPv6 Subnet")) -o.rmempty = true -o.placeholder="fe80::/10" -o.datatype="ip6addr" -o:depends("ipv6", 1) - -o = s:option(Value, "gateway6", translate("IPv6 Gateway")) -o.rmempty = true -o.placeholder="fe80::1" -o.datatype="ip6addr" -o:depends("ipv6", 1) - -m.handle = function(self, state, data) - if state == FORM_VALID then - local name = data.name - local driver = data.driver - - local internal = data.internal == 1 and true or false - - local subnet = data.subnet - local gateway = data.gateway - local ip_range = data.ip_range - - local aux_address = {} - local tmp = data.aux_address or {} - for i,v in ipairs(tmp) do - _,_,k1,v1 = v:find("(.-)=(.+)") - aux_address[k1] = v1 - end - - local options = {} - tmp = data.options or {} - for i,v in ipairs(tmp) do - _,_,k1,v1 = v:find("(.-)=(.+)") - options[k1] = v1 - end - - local ipv6 = data.ipv6 == 1 and true or false - - local create_body = { - Name = name, - Driver = driver, - EnableIPv6 = ipv6, - IPAM = { - Driver= "default" - }, - Internal = internal - } - - if subnet or gateway or ip_range then - create_body["IPAM"]["Config"] = { - { - Subnet = subnet, - Gateway = gateway, - IPRange = ip_range, - AuxAddress = aux_address, - AuxiliaryAddresses = aux_address - } - } - end - - if driver == "macvlan" then - create_body["Options"] = { - macvlan_mode = data.macvlan_mode, - parent = data.parent - } - elseif driver == "ipvlan" then - create_body["Options"] = { - ipvlan_mode = data.ipvlan_mode - } - elseif driver == "overlay" then - create_body["Ingress"] = data.ingerss == 1 and true or false - end - - if ipv6 and data.subnet6 and data.subnet6 then - if type(create_body["IPAM"]["Config"]) ~= "table" then - create_body["IPAM"]["Config"] = {} - end - local index = #create_body["IPAM"]["Config"] - create_body["IPAM"]["Config"][index+1] = { - Subnet = data.subnet6, - Gateway = data.gateway6 - } - end - - if next(options) ~= nil then - create_body["Options"] = create_body["Options"] or {} - for k, v in pairs(options) do - create_body["Options"][k] = v - end - end - - create_body = docker.clear_empty_tables(create_body) - docker:write_status("Network: " .. "create" .. " " .. create_body.Name .. "...") - - local res = dk.networks:create({ - body = create_body - }) - - if res and res.code == 201 then - docker:write_status("Network: " .. "create macvlan interface...") - res = dk.networks:inspect({ - name = create_body.Name - }) - - if driver == "macvlan" and - data.op_macvlan ~= 0 and - res and - res.code and - res.code == 200 and - res.body and - res.body.IPAM and - res.body.IPAM.Config and - res.body.IPAM.Config[1] and - res.body.IPAM.Config[1].Gateway and - res.body.IPAM.Config[1].Subnet then - - docker.create_macvlan_interface(data.name, - data.parent, - res.body.IPAM.Config[1].Gateway, - res.body.IPAM.Config[1].Subnet) - end - - docker:clear_status() - luci.http.redirect(luci.dispatcher.build_url("admin/docker/networks")) - else - docker:append_status("code:" .. res.code.." ".. (res.body.message and res.body.message or res.message).. "\n") - luci.http.redirect(luci.dispatcher.build_url("admin/docker/newnetwork")) - end - end -end - -return m diff --git a/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua b/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua deleted file mode 100755 index c91f349ce..000000000 --- a/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua +++ /dev/null @@ -1,151 +0,0 @@ ---[[ -LuCI - Lua Configuration Interface -Copyright 2019 lisaac -]]-- - -local docker = require "luci.model.docker" -local uci = (require "luci.model.uci").cursor() - -local m, s, o, lost_state -local dk = docker.new() - -if dk:_ping().code ~= 200 then - lost_state = true -end - -m = SimpleForm("dockerd", - translate("Docker - Overview"), - translate("An overview with the relevant data is displayed here with which the LuCI docker client is connected.") -.. - " " .. - [[]] .. - translate("Github") .. - [[]]) -m.submit=false -m.reset=false - -local docker_info_table = {} --- docker_info_table['0OperatingSystem'] = {_key=translate("Operating System"),_value='-'} --- docker_info_table['1Architecture'] = {_key=translate("Architecture"),_value='-'} --- docker_info_table['2KernelVersion'] = {_key=translate("Kernel Version"),_value='-'} -docker_info_table['3ServerVersion'] = {_key=translate("Docker Version"),_value='-'} -docker_info_table['4ApiVersion'] = {_key=translate("Api Version"),_value='-'} -docker_info_table['5NCPU'] = {_key=translate("CPUs"),_value='-'} -docker_info_table['6MemTotal'] = {_key=translate("Total Memory"),_value='-'} -docker_info_table['7DockerRootDir'] = {_key=translate("Docker Root Dir"),_value='-'} -docker_info_table['8IndexServerAddress'] = {_key=translate("Index Server Address"),_value='-'} -docker_info_table['9RegistryMirrors'] = {_key=translate("Registry Mirrors"),_value='-'} - -if nixio.fs.access("/usr/bin/dockerd") and not uci:get_bool("dockerd", "dockerman", "remote_endpoint") then - s = m:section(SimpleSection) - s.template = "dockerman/apply_widget" - s.err=docker:read_status() - s.err=s.err and s.err:gsub("\n","
"):gsub(" "," ") - if s.err then - docker:clear_status() - end - s = m:section(Table,{{}}) - s.notitle=true - s.rowcolors=false - s.template = "cbi/nullsection" - - o = s:option(Button, "_start") - o.template = "dockerman/cbi/inlinebutton" - o.inputtitle = lost_state and translate("Start") or translate("Stop") - o.inputstyle = lost_state and "add" or "remove" - o.forcewrite = true - o.write = function(self, section) - docker:clear_status() - - if lost_state then - docker:append_status("Docker daemon: starting") - luci.util.exec("/etc/init.d/dockerd start") - luci.util.exec("sleep 5") - luci.util.exec("/etc/init.d/dockerman start") - - else - docker:append_status("Docker daemon: stopping") - luci.util.exec("/etc/init.d/dockerd stop") - end - docker:clear_status() - luci.http.redirect(luci.dispatcher.build_url("admin/docker/overview")) - end - - o = s:option(Button, "_restart") - o.template = "dockerman/cbi/inlinebutton" - o.inputtitle = translate("Restart") - o.inputstyle = "reload" - o.forcewrite = true - o.write = function(self, section) - docker:clear_status() - docker:append_status("Docker daemon: restarting") - luci.util.exec("/etc/init.d/dockerd restart") - luci.util.exec("sleep 5") - luci.util.exec("/etc/init.d/dockerman start") - docker:clear_status() - luci.http.redirect(luci.dispatcher.build_url("admin/docker/overview")) - end -end - -s = m:section(Table, docker_info_table) -s:option(DummyValue, "_key", translate("Info")) -s:option(DummyValue, "_value") - -s = m:section(SimpleSection) -s.template = "dockerman/overview" - -s.containers_running = '-' -s.images_used = '-' -s.containers_total = '-' -s.images_total = '-' -s.networks_total = '-' -s.volumes_total = '-' - --- local socket = luci.model.uci.cursor():get("dockerd", "dockerman", "socket_path") -if not lost_state then - local containers_list = dk.containers:list({query = {all=true}}).body - local images_list = dk.images:list().body - local vol = dk.volumes:list() - local volumes_list = vol and vol.body and vol.body.Volumes or {} - local networks_list = dk.networks:list().body or {} - local docker_info = dk:info() - - -- docker_info_table['0OperatingSystem']._value = docker_info.body.OperatingSystem - -- docker_info_table['1Architecture']._value = docker_info.body.Architecture - -- docker_info_table['2KernelVersion']._value = docker_info.body.KernelVersion - docker_info_table['3ServerVersion']._value = docker_info.body.ServerVersion - docker_info_table['4ApiVersion']._value = docker_info.headers["Api-Version"] - docker_info_table['5NCPU']._value = tostring(docker_info.body.NCPU) - docker_info_table['6MemTotal']._value = docker.byte_format(docker_info.body.MemTotal) - if docker_info.body.DockerRootDir then - local statvfs = nixio.fs.statvfs(docker_info.body.DockerRootDir) - local size = statvfs and (statvfs.bavail * statvfs.bsize) or 0 - docker_info_table['7DockerRootDir']._value = docker_info.body.DockerRootDir .. " (" .. tostring(docker.byte_format(size)) .. " " .. translate("Available") .. ")" - end - - docker_info_table['8IndexServerAddress']._value = docker_info.body.IndexServerAddress - for i, v in ipairs(docker_info.body.RegistryConfig.Mirrors) do - docker_info_table['9RegistryMirrors']._value = docker_info_table['9RegistryMirrors']._value == "-" and v or (docker_info_table['9RegistryMirrors']._value .. ", " .. v) - end - - s.images_used = 0 - for i, v in ipairs(images_list) do - for ci,cv in ipairs(containers_list) do - if v.Id == cv.ImageID then - s.images_used = s.images_used + 1 - break - end - end - end - - s.containers_running = tostring(docker_info.body.ContainersRunning) - s.images_used = tostring(s.images_used) - s.containers_total = tostring(docker_info.body.Containers) - s.images_total = tostring(#images_list) - s.networks_total = tostring(#networks_list) - s.volumes_total = tostring(#volumes_list) -else - docker_info_table['3ServerVersion']._value = translate("Can NOT connect to docker daemon, please check!!") -end - -return m diff --git a/luci-app-dockerman/luasrc/model/cbi/dockerman/volumes.lua b/luci-app-dockerman/luasrc/model/cbi/dockerman/volumes.lua deleted file mode 100755 index 43e6bda3a..000000000 --- a/luci-app-dockerman/luasrc/model/cbi/dockerman/volumes.lua +++ /dev/null @@ -1,142 +0,0 @@ ---[[ -LuCI - Lua Configuration Interface -Copyright 2019 lisaac -]]-- - -local docker = require "luci.model.docker" -local dk = docker.new() - -local m, s, o - -local res, containers, volumes, lost_state - -function get_volumes() - local data = {} - for i, v in ipairs(volumes) do - local index = v.Name - data[index]={} - data[index]["_selected"] = 0 - data[index]["_nameraw"] = v.Name - data[index]["_name"] = v.Name:sub(1,12) - - for ci,cv in ipairs(containers) do - if cv.Mounts and type(cv.Mounts) ~= "table" then - break - end - for vi, vv in ipairs(cv.Mounts) do - if v.Name == vv.Name then - data[index]["_containers"] = (data[index]["_containers"] and (data[index]["_containers"] .. " | ") or "").. - ''.. cv.Names[1]:sub(2)..'' - end - end - end - data[index]["_driver"] = v.Driver - data[index]["_mountpoint"] = nil - - for v1 in v.Mountpoint:gmatch('[^/]+') do - if v1 == index then - data[index]["_mountpoint"] = data[index]["_mountpoint"] .."/" .. v1:sub(1,12) .. "..." - else - data[index]["_mountpoint"] = (data[index]["_mountpoint"] and data[index]["_mountpoint"] or "").."/".. v1 - end - end - data[index]["_created"] = v.CreatedAt - data[index]["_size"] = "-" - end - - return data -end -if dk:_ping().code ~= 200 then - lost_state = true -else - res = dk.volumes:list() - if res and res.code and res.code <300 then - volumes = res.body.Volumes - end - - res = dk.containers:list({ - query = { - all=true - } - }) - if res and res.code and res.code <300 then - containers = res.body - end -end - -local volume_list = not lost_state and get_volumes() or {} - -m = SimpleForm("docker", translate("Docker - Volumes")) -m.submit=false -m.reset=false -m:append(Template("dockerman/volume_size")) - -s = m:section(Table, volume_list, translate("Volumes overview")) - -o = s:option(Flag, "_selected","") -o.disabled = 0 -o.enabled = 1 -o.default = 0 -o.write = function(self, section, value) - volume_list[section]._selected = value -end - -o = s:option(DummyValue, "_name", translate("Name")) -o = s:option(DummyValue, "_driver", translate("Driver")) -o = s:option(DummyValue, "_containers", translate("Containers")) -o.rawhtml = true -o = s:option(DummyValue, "_mountpoint", translate("Mount Point")) -o = s:option(DummyValue, "_size", translate("Size")) -o.rawhtml = true -o = s:option(DummyValue, "_created", translate("Created")) - -s = m:section(SimpleSection) -s.template = "dockerman/apply_widget" -s.err=docker:read_status() -s.err=s.err and s.err:gsub("\n","
"):gsub(" "," ") -if s.err then - docker:clear_status() -end - -s = m:section(Table,{{}}) -s.notitle=true -s.rowcolors=false -s.template="cbi/nullsection" - -o = s:option(Button, "remove") -o.inputtitle= translate("Remove") -o.template = "dockerman/cbi/inlinebutton" -o.inputstyle = "remove" -o.forcewrite = true -o.disable = lost_state -o.write = function(self, section) - local volume_selected = {} - - for k in pairs(volume_list) do - if volume_list[k]._selected == 1 then - volume_selected[#volume_selected+1] = k - end - end - - if next(volume_selected) ~= nil then - local success = true - docker:clear_status() - for _,vol in ipairs(volume_selected) do - docker:append_status("Volumes: " .. "remove" .. " " .. vol .. "...") - local msg = dk.volumes["remove"](dk, {id = vol}) - if msg and msg.code and msg.code ~= 204 then - docker:append_status("code:" .. msg.code.." ".. (msg.body.message and msg.body.message or msg.message).. "\n") - success = false - else - docker:append_status("done\n") - end - end - - if success then - docker:clear_status() - end - luci.http.redirect(luci.dispatcher.build_url("admin/docker/volumes")) - end -end - -return m diff --git a/luci-app-dockerman/luasrc/model/docker.lua b/luci-app-dockerman/luasrc/model/docker.lua deleted file mode 100755 index 2a902912a..000000000 --- a/luci-app-dockerman/luasrc/model/docker.lua +++ /dev/null @@ -1,507 +0,0 @@ ---[[ -LuCI - Lua Configuration Interface -Copyright 2019 lisaac -]]-- - -local docker = require "luci.docker" -local fs = require "nixio.fs" -local uci = (require "luci.model.uci").cursor() - -local _docker = {} -_docker.options = {} - ---pull image and return iamge id -local update_image = function(self, image_name) - local json_stringify = luci.jsonc and luci.jsonc.stringify - _docker:append_status("Images: " .. "pulling" .. " " .. image_name .. "...\n") - local res = self.images:create({query = {fromImage=image_name}}, _docker.pull_image_show_status_cb) - - if res and res.code and res.code == 200 and (#res.body > 0 and not res.body[#res.body].error and res.body[#res.body].status and (res.body[#res.body].status == "Status: Downloaded newer image for ".. image_name)) then - _docker:append_status("done\n") - else - res.body.message = res.body[#res.body] and res.body[#res.body].error or (res.body.message or res.message) - end - - new_image_id = self.images:inspect({name = image_name}).body.Id - return new_image_id, res -end - -local table_equal = function(t1, t2) - if not t1 then - return true - end - - if not t2 then - return false - end - - if #t1 ~= #t2 then - return false - end - - for i, v in ipairs(t1) do - if t1[i] ~= t2[i] then - return false - end - end - - return true -end - -local table_subtract = function(t1, t2) - if not t1 or next(t1) == nil then - return nil - end - - if not t2 or next(t2) == nil then - return t1 - end - - local res = {} - for _, v1 in ipairs(t1) do - local found = false - for _, v2 in ipairs(t2) do - if v1 == v2 then - found= true - break - end - end - if not found then - table.insert(res, v1) - end - end - - return next(res) == nil and nil or res -end - -local map_subtract = function(t1, t2) - if not t1 or next(t1) == nil then - return nil - end - - if not t2 or next(t2) == nil then - return t1 - end - - local res = {} - for k1, v1 in pairs(t1) do - local found = false - for k2, v2 in ipairs(t2) do - if k1 == k2 and luci.util.serialize_data(v1) == luci.util.serialize_data(v2) then - found= true - break - end - end - - if not found then - res[k1] = v1 - end - end - - return next(res) ~= nil and res or nil -end - -_docker.clear_empty_tables = function ( t ) - local k, v - - if next(t) == nil then - t = nil - else - for k, v in pairs(t) do - if type(v) == 'table' then - t[k] = _docker.clear_empty_tables(v) - if t[k] and next(t[k]) == nil then - t[k] = nil - end - end - end - end - - return t -end - -local get_config = function(container_config, image_config) - local config = container_config.Config - local old_host_config = container_config.HostConfig - local old_network_setting = container_config.NetworkSettings.Networks or {} - - if config.WorkingDir == image_config.WorkingDir then - config.WorkingDir = "" - end - - if config.User == image_config.User then - config.User = "" - end - - if table_equal(config.Cmd, image_config.Cmd) then - config.Cmd = nil - end - - if table_equal(config.Entrypoint, image_config.Entrypoint) then - config.Entrypoint = nil - end - - if table_equal(config.ExposedPorts, image_config.ExposedPorts) then - config.ExposedPorts = nil - end - - config.Env = table_subtract(config.Env, image_config.Env) - config.Labels = table_subtract(config.Labels, image_config.Labels) - config.Volumes = map_subtract(config.Volumes, image_config.Volumes) - - if old_host_config.PortBindings and next(old_host_config.PortBindings) ~= nil then - config.ExposedPorts = {} - for p, v in pairs(old_host_config.PortBindings) do - config.ExposedPorts[p] = { HostPort=v[1] and v[1].HostPort } - end - end - - local network_setting = {} - local multi_network = false - local extra_network = {} - - for k, v in pairs(old_network_setting) do - if multi_network then - extra_network[k] = v - else - network_setting[k] = v - end - multi_network = true - end - - local host_config = old_host_config - host_config.Mounts = {} - for i, v in ipairs(container_config.Mounts) do - if v.Type == "volume" then - table.insert(host_config.Mounts, { - Type = v.Type, - Target = v.Destination, - Source = v.Source:match("([^/]+)\/_data"), - BindOptions = (v.Type == "bind") and {Propagation = v.Propagation} or nil, - ReadOnly = not v.RW - }) - end - end - - local create_body = config - create_body["HostConfig"] = host_config - create_body["NetworkingConfig"] = {EndpointsConfig = network_setting} - create_body = _docker.clear_empty_tables(create_body) or {} - extra_network = _docker.clear_empty_tables(extra_network) or {} - - return create_body, extra_network -end - -local upgrade = function(self, request) - _docker:clear_status() - - local container_info = self.containers:inspect({id = request.id}) - - if container_info.code > 300 and type(container_info.body) == "table" then - return container_info - end - - local image_name = container_info.body.Config.Image - if not image_name:match(".-:.+") then - image_name = image_name .. ":latest" - end - - local old_image_id = container_info.body.Image - local container_name = container_info.body.Name:sub(2) - - local image_id, res = update_image(self, image_name) - if res and res.code and res.code ~= 200 then - return res - end - - if image_id == old_image_id then - return {code = 305, body = {message = "Already up to date"}} - end - - local t = os.date("%Y%m%d%H%M%S") - _docker:append_status("Container: rename" .. " " .. container_name .. " to ".. container_name .. "_old_".. t .. "...") - res = self.containers:rename({name = container_name, query = { name = container_name .. "_old_" ..t }}) - if res and res.code and res.code < 300 then - _docker:append_status("done\n") - else - return res - end - - local image_config = self.images:inspect({id = old_image_id}).body.Config - local create_body, extra_network = get_config(container_info.body, image_config) - - -- create new container - _docker:append_status("Container: Create" .. " " .. container_name .. "...") - create_body = _docker.clear_empty_tables(create_body) - res = self.containers:create({name = container_name, body = create_body}) - if res and res.code and res.code > 300 then - return res - end - _docker:append_status("done\n") - - -- extra networks need to network connect action - for k, v in pairs(extra_network) do - _docker:append_status("Networks: Connect" .. " " .. container_name .. "...") - res = self.networks:connect({id = k, body = {Container = container_name, EndpointConfig = v}}) - if res and res.code and res.code > 300 then - return res - end - _docker:append_status("done\n") - end - - _docker:append_status("Container: " .. "Stop" .. " " .. container_name .. "_old_".. t .. "...") - res = self.containers:stop({name = container_name .. "_old_" ..t }) - if res and res.code and res.code < 305 then - _docker:append_status("done\n") - else - return res - end - - _docker:append_status("Container: " .. "Start" .. " " .. container_name .. "...") - res = self.containers:start({name = container_name}) - if res and res.code and res.code < 305 then - _docker:append_status("done\n") - else - return res - end - - _docker:clear_status() - return res -end - -local duplicate_config = function (self, request) - local container_info = self.containers:inspect({id = request.id}) - if container_info.code > 300 and type(container_info.body) == "table" then - return nil - end - - local old_image_id = container_info.body.Image - local image_config = self.images:inspect({id = old_image_id}).body.Config - - return get_config(container_info.body, image_config) -end - -_docker.new = function() - local host = nil - local port = nil - local socket_path = nil - local debug_path = nil - - if uci:get_bool("dockerd", "dockerman", "remote_endpoint") then - host = uci:get("dockerd", "dockerman", "remote_host") or nil - port = uci:get("dockerd", "dockerman", "remote_port") or nil - else - socket_path = uci:get("dockerd", "dockerman", "socket_path") or "/var/run/docker.sock" - end - - local debug = uci:get_bool("dockerd", "dockerman", "debug") - if debug then - debug_path = uci:get("dockerd", "dockerman", "debug_path") or "/tmp/.docker_debug" - end - - local status_path = uci:get("dockerd", "dockerman", "status_path") or "/tmp/.docker_action_status" - - _docker.options = { - host = host, - port = port, - socket_path = socket_path, - debug = debug, - debug_path = debug_path, - status_path = status_path - } - - local _new = docker.new(_docker.options) - _new.containers_upgrade = upgrade - _new.containers_duplicate_config = duplicate_config - - return _new -end - -_docker.options.status_path = uci:get("dockerd", "dockerman", "status_path") or "/tmp/.docker_action_status" - -_docker.append_status=function(self,val) - if not val then - return - end - local file_docker_action_status=io.open(self.options.status_path, "a+") - file_docker_action_status:write(val) - file_docker_action_status:close() -end - -_docker.write_status=function(self,val) - if not val then - return - end - local file_docker_action_status=io.open(self.options.status_path, "w+") - file_docker_action_status:write(val) - file_docker_action_status:close() -end - -_docker.read_status=function(self) - return fs.readfile(self.options.status_path) -end - -_docker.clear_status=function(self) - fs.remove(self.options.status_path) -end - -local status_cb = function(res, source, handler) - res.body = res.body or {} - while true do - local chunk = source() - if chunk then - --standard output to res.body - table.insert(res.body, chunk) - handler(chunk) - else - return - end - end -end - ---{"status":"Pulling from library\/debian","id":"latest"} ---{"status":"Pulling fs layer","progressDetail":[],"id":"50e431f79093"} ---{"status":"Downloading","progressDetail":{"total":50381971,"current":2029978},"id":"50e431f79093","progress":"[==> ] 2.03MB\/50.38MB"} ---{"status":"Download complete","progressDetail":[],"id":"50e431f79093"} ---{"status":"Extracting","progressDetail":{"total":50381971,"current":17301504},"id":"50e431f79093","progress":"[=================> ] 17.3MB\/50.38MB"} ---{"status":"Pull complete","progressDetail":[],"id":"50e431f79093"} ---{"status":"Digest: sha256:a63d0b2ecbd723da612abf0a8bdb594ee78f18f691d7dc652ac305a490c9b71a"} ---{"status":"Status: Downloaded newer image for debian:latest"} -_docker.pull_image_show_status_cb = function(res, source) - return status_cb(res, source, function(chunk) - local json_parse = luci.jsonc.parse - local step = json_parse(chunk) - if type(step) == "table" then - local buf = _docker:read_status() - local num = 0 - local str = '\t' .. (step.id and (step.id .. ": ") or "") .. (step.status and step.status or "") .. (step.progress and (" " .. step.progress) or "").."\n" - if step.id then - buf, num = buf:gsub("\t"..step.id .. ": .-\n", str) - end - if num == 0 then - buf = buf .. str - end - _docker:write_status(buf) - end - end) -end - ---{"status":"Downloading from https://downloads.openwrt.org/releases/19.07.0/targets/x86/64/openwrt-19.07.0-x86-64-generic-rootfs.tar.gz"} ---{"status":"Importing","progressDetail":{"current":1572391,"total":3821714},"progress":"[====================\u003e ] 1.572MB/3.822MB"} ---{"status":"sha256:d5304b58e2d8cc0a2fd640c05cec1bd4d1229a604ac0dd2909f13b2b47a29285"} -_docker.import_image_show_status_cb = function(res, source) - return status_cb(res, source, function(chunk) - local json_parse = luci.jsonc.parse - local step = json_parse(chunk) - if type(step) == "table" then - local buf = _docker:read_status() - local num = 0 - local str = '\t' .. (step.status and step.status or "") .. (step.progress and (" " .. step.progress) or "").."\n" - if step.status then - buf, num = buf:gsub("\t"..step.status .. " .-\n", str) - end - if num == 0 then - buf = buf .. str - end - _docker:write_status(buf) - end - end) -end - -_docker.create_macvlan_interface = function(name, device, gateway, subnet) - if not fs.access("/etc/config/network") or not fs.access("/etc/config/firewall") then - return - end - - if uci:get_bool("dockerd", "dockerman", "remote_endpoint") then - return - end - - local ip = require "luci.ip" - local if_name = "docker_"..name - local dev_name = "macvlan_"..name - local net_mask = tostring(ip.new(subnet):mask()) - local lan_interfaces - - -- add macvlan device - uci:delete("network", dev_name) - uci:set("network", dev_name, "device") - uci:set("network", dev_name, "name", dev_name) - uci:set("network", dev_name, "ifname", device) - uci:set("network", dev_name, "type", "macvlan") - uci:set("network", dev_name, "mode", "bridge") - - -- add macvlan interface - uci:delete("network", if_name) - uci:set("network", if_name, "interface") - uci:set("network", if_name, "proto", "static") - uci:set("network", if_name, "ifname", dev_name) - uci:set("network", if_name, "ipaddr", gateway) - uci:set("network", if_name, "netmask", net_mask) - uci:foreach("firewall", "zone", function(s) - if s.name == "lan" then - local interfaces - if type(s.network) == "table" then - interfaces = table.concat(s.network, " ") - uci:delete("firewall", s[".name"], "network") - else - interfaces = s.network and s.network or "" - end - interfaces = interfaces .. " " .. if_name - interfaces = interfaces:gsub("%s+", " ") - uci:set("firewall", s[".name"], "network", interfaces) - end - end) - - uci:commit("firewall") - uci:commit("network") - - os.execute("ifup " .. if_name) -end - -_docker.remove_macvlan_interface = function(name) - if not fs.access("/etc/config/network") or not fs.access("/etc/config/firewall") then - return - end - - if uci:get_bool("dockerd", "dockerman", "remote_endpoint") then - return - end - - local if_name = "docker_"..name - local dev_name = "macvlan_"..name - uci:foreach("firewall", "zone", function(s) - if s.name == "lan" then - local interfaces - if type(s.network) == "table" then - interfaces = table.concat(s.network, " ") - else - interfaces = s.network and s.network or "" - end - interfaces = interfaces and interfaces:gsub(if_name, "") - interfaces = interfaces and interfaces:gsub("%s+", " ") - uci:set("firewall", s[".name"], "network", interfaces) - end - end) - - uci:delete("network", dev_name) - uci:delete("network", if_name) - uci:commit("network") - uci:commit("firewall") - - os.execute("ip link del " .. if_name) -end - -_docker.byte_format = function (byte) - if not byte then return 'NaN' end - local suff = {"B", "KB", "MB", "GB", "TB"} - for i=1, 5 do - if byte > 1024 and i < 5 then - byte = byte / 1024 - else - return string.format("%.2f %s", byte, suff[i]) - end - end -end - -return _docker diff --git a/luci-app-dockerman/luasrc/view/dockerman/apply_widget.htm b/luci-app-dockerman/luasrc/view/dockerman/apply_widget.htm deleted file mode 100755 index f96b2d72a..000000000 --- a/luci-app-dockerman/luasrc/view/dockerman/apply_widget.htm +++ /dev/null @@ -1,147 +0,0 @@ - - - diff --git a/luci-app-dockerman/luasrc/view/dockerman/cbi/inlinebutton.htm b/luci-app-dockerman/luasrc/view/dockerman/cbi/inlinebutton.htm deleted file mode 100755 index a061a6dba..000000000 --- a/luci-app-dockerman/luasrc/view/dockerman/cbi/inlinebutton.htm +++ /dev/null @@ -1,7 +0,0 @@ -
- <% if self:cfgvalue(section) ~= false then %> - " type="submit"" <% if self.disable then %>disabled <% end %><%= attr("name", cbid) .. attr("id", cbid) .. attr("value", self.inputtitle or self.title)%> /> - <% else %> - - - <% end %> -
diff --git a/luci-app-dockerman/luasrc/view/dockerman/cbi/inlinevalue.htm b/luci-app-dockerman/luasrc/view/dockerman/cbi/inlinevalue.htm deleted file mode 100755 index e4b0cf7a0..000000000 --- a/luci-app-dockerman/luasrc/view/dockerman/cbi/inlinevalue.htm +++ /dev/null @@ -1,33 +0,0 @@ -
- - <%- if self.password then -%> - /> - <%- end -%> - 0, "data-choices", { self.keylist, self.vallist }) - %> /> - <%- if self.password then -%> -
- <% end %> -
diff --git a/luci-app-dockerman/luasrc/view/dockerman/cbi/namedsection.htm b/luci-app-dockerman/luasrc/view/dockerman/cbi/namedsection.htm deleted file mode 100755 index 244d2c10a..000000000 --- a/luci-app-dockerman/luasrc/view/dockerman/cbi/namedsection.htm +++ /dev/null @@ -1,9 +0,0 @@ -<% if self:cfgvalue(self.section) then section = self.section %> -
- <%+cbi/tabmenu%> -
- <%+cbi/ucisection%> -
-
-<% end %> - diff --git a/luci-app-dockerman/luasrc/view/dockerman/cbi/xfvalue.htm b/luci-app-dockerman/luasrc/view/dockerman/cbi/xfvalue.htm deleted file mode 100755 index 04f7bc2ee..000000000 --- a/luci-app-dockerman/luasrc/view/dockerman/cbi/xfvalue.htm +++ /dev/null @@ -1,10 +0,0 @@ -<%+cbi/valueheader%> - /> - disabled <% end %><%= - attr("id", cbid) .. attr("name", cbid) .. attr("value", self.enabled or 1) .. - ifattr((self:cfgvalue(section) or self.default) == self.enabled, "checked", "checked") - %> /> - > -<%+cbi/valuefooter%> diff --git a/luci-app-dockerman/luasrc/view/dockerman/container.htm b/luci-app-dockerman/luasrc/view/dockerman/container.htm deleted file mode 100755 index 9f05d9d58..000000000 --- a/luci-app-dockerman/luasrc/view/dockerman/container.htm +++ /dev/null @@ -1,28 +0,0 @@ -
- - - diff --git a/luci-app-dockerman/luasrc/view/dockerman/container_console.htm b/luci-app-dockerman/luasrc/view/dockerman/container_console.htm deleted file mode 100755 index 1a4dc2a6b..000000000 --- a/luci-app-dockerman/luasrc/view/dockerman/container_console.htm +++ /dev/null @@ -1,6 +0,0 @@ -
- -
- diff --git a/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm b/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm deleted file mode 100755 index 2e0650d9d..000000000 --- a/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm +++ /dev/null @@ -1,332 +0,0 @@ - -
- -
- - -
-
-
- - diff --git a/luci-app-dockerman/luasrc/view/dockerman/container_stats.htm b/luci-app-dockerman/luasrc/view/dockerman/container_stats.htm deleted file mode 100755 index bbcd633e7..000000000 --- a/luci-app-dockerman/luasrc/view/dockerman/container_stats.htm +++ /dev/null @@ -1,81 +0,0 @@ - diff --git a/luci-app-dockerman/luasrc/view/dockerman/containers_running_stats.htm b/luci-app-dockerman/luasrc/view/dockerman/containers_running_stats.htm deleted file mode 100755 index d88e28be9..000000000 --- a/luci-app-dockerman/luasrc/view/dockerman/containers_running_stats.htm +++ /dev/null @@ -1,91 +0,0 @@ - \ No newline at end of file diff --git a/luci-app-dockerman/luasrc/view/dockerman/images_import.htm b/luci-app-dockerman/luasrc/view/dockerman/images_import.htm deleted file mode 100755 index 0ad6e0fce..000000000 --- a/luci-app-dockerman/luasrc/view/dockerman/images_import.htm +++ /dev/null @@ -1,104 +0,0 @@ - - -
- disabled <% end %>/> - -
- - diff --git a/luci-app-dockerman/luasrc/view/dockerman/images_load.htm b/luci-app-dockerman/luasrc/view/dockerman/images_load.htm deleted file mode 100755 index b201510ac..000000000 --- a/luci-app-dockerman/luasrc/view/dockerman/images_load.htm +++ /dev/null @@ -1,40 +0,0 @@ -
- disabled <% end %>/> - -
- diff --git a/luci-app-dockerman/luasrc/view/dockerman/logs.htm b/luci-app-dockerman/luasrc/view/dockerman/logs.htm deleted file mode 100755 index 6cd2cb095..000000000 --- a/luci-app-dockerman/luasrc/view/dockerman/logs.htm +++ /dev/null @@ -1,13 +0,0 @@ -<% if self.title == "Events" then %> -<%+header%> -

<%:Docker - Events%>

-
-

<%:Events%>

-<% end %> -
- -
-<% if self.title == "Events" then %> -
-<%+footer%> -<% end %> diff --git a/luci-app-dockerman/luasrc/view/dockerman/newcontainer_resolve.htm b/luci-app-dockerman/luasrc/view/dockerman/newcontainer_resolve.htm deleted file mode 100755 index 338fd59d5..000000000 --- a/luci-app-dockerman/luasrc/view/dockerman/newcontainer_resolve.htm +++ /dev/null @@ -1,102 +0,0 @@ - - - -<%+cbi/valueheader%> - - - -<%+cbi/valuefooter%> diff --git a/luci-app-dockerman/luasrc/view/dockerman/overview.htm b/luci-app-dockerman/luasrc/view/dockerman/overview.htm deleted file mode 100755 index e491fc512..000000000 --- a/luci-app-dockerman/luasrc/view/dockerman/overview.htm +++ /dev/null @@ -1,197 +0,0 @@ - - -
-
-
-
-
- -
-
-
-

<%:Containers%>

-

- <%- if self.containers_total ~= "-" then -%><%- end -%> - <%=self.containers_running%> - /<%=self.containers_total%> - <%- if self.containers_total ~= "-" then -%><%- end -%> -

-
-
-
-
-
-
-
- -
-
-
-

<%:Images%>

-

- <%- if self.images_total ~= "-" then -%><%- end -%> - <%=self.images_used%> - /<%=self.images_total%> - <%- if self.images_total ~= "-" then -%><%- end -%> -

-
-
-
-
-
-
-
- -
-
-
-

<%:Networks%>

-

- <%- if self.networks_total ~= "-" then -%><%- end -%> - <%=self.networks_total%> - - <%- if self.networks_total ~= "-" then -%><%- end -%> -

-
-
-
-
-
-
-
- -
-
-
-

<%:Volumes%>

-

- <%- if self.volumes_total ~= "-" then -%><%- end -%> - <%=self.volumes_total%> - - <%- if self.volumes_total ~= "-" then -%><%- end -%> -

-
-
-
-
diff --git a/luci-app-dockerman/luasrc/view/dockerman/volume_size.htm b/luci-app-dockerman/luasrc/view/dockerman/volume_size.htm deleted file mode 100755 index dc024734b..000000000 --- a/luci-app-dockerman/luasrc/view/dockerman/volume_size.htm +++ /dev/null @@ -1,21 +0,0 @@ - \ No newline at end of file diff --git a/luci-app-dockerman/po/templates/dockerman.pot b/luci-app-dockerman/po/templates/dockerman.pot deleted file mode 100755 index 0d6a5de98..000000000 --- a/luci-app-dockerman/po/templates/dockerman.pot +++ /dev/null @@ -1,1002 +0,0 @@ -msgid "" -msgstr "Content-Type: text/plain; charset=UTF-8" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:619 -msgid "A list of kernel capabilities to add to the container" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:69 -msgid "Access Control" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:223 -msgid "Add" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:595 -msgid "Add host device to the container" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:571 -msgid "Advance" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:586 -msgid "Allocates an ephemeral host port for all of a container's exposed ports" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:118 -msgid "Allowed access interfaces" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:498 -msgid "Always pull image first" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:29 -msgid "" -"An overview with the relevant data is displayed here with which the LuCI " -"docker client is connected." -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:43 -msgid "Api Version" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:94 -msgid "Auto create macvlan interface in Openwrt" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:18 -msgid "Auto start" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:134 -msgid "Available" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:47 -msgid "Base device" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:553 -msgid "Bind Mount(-v)" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:554 -msgid "Bind mount a volume" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:596 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:652 -msgid "Block IO Weight" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:653 -msgid "" -"Block IO weight (relative weight) accepts a weight value between 10 and 1000" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:597 -msgid "" -"Block IO weight (relative weight) accepts a weight value between 10 and 1000." -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:61 -msgid "Bridge (Support direct communication between MAC VLANs)" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:42 -msgid "Bridge device" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:84 -msgid "" -"By entering a valid image name with the corresponding version, the docker " -"image can be downloaded from the configured registry." -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:618 -msgid "CAP-ADD(--cap-add)" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:581 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:635 -msgid "CPU Shares Weight" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:779 -msgid "CPU Useage" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:636 -msgid "" -"CPU shares relative weight, if 0 is set, the system will ignore the value " -"and use the default of 1024" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:582 -msgid "" -"CPU shares relative weight, if 0 is set, the system will ignore the value " -"and use the default of 1024." -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:573 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:626 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:44 -msgid "CPUs" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:159 -msgid "Can NOT connect to docker daemon, please check!!" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/newcontainer_resolve.htm:91 -msgid "Cancel" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:60 -msgid "Client connection" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:347 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:687 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:182 -msgid "Command" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/newcontainer_resolve.htm:100 -msgid "Command line" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/newcontainer_resolve.htm:72 -msgid "Command line Error" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/controller/dockerman.lua:17 -msgid "Configuration" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:36 -msgid "Configure the default bridge network" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:405 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:707 -msgid "Connect" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:403 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:437 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:473 -msgid "Connect Network" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:74 -msgid "Connect to remote docker endpoint" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container.htm:7 -msgid "Console" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:161 -msgid "Container Info" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:650 -msgid "Container Inspect" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:671 -msgid "Container Logs" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:473 -msgid "Container Name" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:92 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:58 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/volumes.lua:29 -msgid "Container detail" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/controller/dockerman.lua:38 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:142 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:148 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/volumes.lua:87 -#: applications/luci-app-dockerman/luasrc/view/dockerman/overview.htm:133 -msgid "Containers" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:94 -msgid "Create macvlan interface" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:465 -msgid "Create new docker container" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:31 -msgid "Create new docker network" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:312 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:153 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/volumes.lua:92 -msgid "Created" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm:33 -msgid "DELETING" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:371 -msgid "DNS" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:51 -msgid "Debug" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:35 -msgid "Default bridge" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:363 -msgid "Device" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:594 -msgid "Device(--device)" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:396 -msgid "Disconnect" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/controller/dockerman.lua:14 -msgid "Docker" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:12 -msgid "Docker - Configuration" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:192 -msgid "Docker - Container (%s)" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:128 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:450 -msgid "Docker - Containers" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/logs.htm:3 -msgid "Docker - Events" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:72 -msgid "Docker - Images" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:15 -msgid "Docker - Network" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua:54 -msgid "Docker - Networks" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:28 -msgid "Docker - Overview" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/volumes.lua:69 -msgid "Docker - Volumes" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:16 -msgid "Docker Daemon settings" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:489 -msgid "Docker Image" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:30 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:46 -msgid "Docker Root Dir" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:93 -msgid "Docker Socket Path" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:42 -msgid "Docker Version" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/apply_widget.htm:91 -msgid "Docker actions done." -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:70 -msgid "DockerMan" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:13 -msgid "DockerMan is a simple docker manager client for LuCI" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:68 -msgid "DockerMan settings" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm:172 -msgid "Download" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua:82 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:40 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/volumes.lua:85 -msgid "Driver" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:265 -msgid "Duplicate/Edit" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:120 -msgid "Enable IPv6" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:351 -msgid "Env" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:546 -msgid "Environmental Variable(-e)" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:54 -msgid "Error" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/controller/dockerman.lua:42 -#: applications/luci-app-dockerman/luasrc/view/dockerman/logs.htm:5 -msgid "Events" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:116 -msgid "Exclude IPs" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:247 -msgid "Export" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:585 -msgid "Exposed All Ports(-P)" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:560 -msgid "Exposed Ports(-p)" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:55 -msgid "Fatal" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container.htm:6 -msgid "File" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:324 -msgid "Finish Time" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:220 -msgid "Force Remove" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua:88 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:106 -msgid "Gateway" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:33 -msgid "Github" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/cbi/inlinevalue.htm:4 -msgid "Go to relevant configuration page" -msgstr "" - -#: applications/luci-app-dockerman/root/usr/share/rpcd/acl.d/luci-app-dockerman.json:3 -msgid "Grant UCI access for luci-app-dockerman" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:330 -msgid "Healthy" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:578 -msgid "Host Name" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:100 -msgid "Host or IP Address for the connection to a remote docker instance" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:300 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:142 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua:78 -msgid "ID" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:44 -msgid "IP VLAN" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:111 -msgid "IP range" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:522 -msgid "IPv4 Address" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:132 -msgid "IPv6 Gateway" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:126 -msgid "IPv6 Subnet" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:304 -#: applications/luci-app-dockerman/luasrc/view/dockerman/images_import.htm:54 -msgid "Image" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/controller/dockerman.lua:39 -#: applications/luci-app-dockerman/luasrc/view/dockerman/overview.htm:151 -msgid "Images" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:132 -msgid "Images overview" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/images_import.htm:4 -msgid "Import" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:125 -msgid "Import Image" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:47 -msgid "Index Server Address" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:52 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:414 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:102 -#: applications/luci-app-dockerman/luasrc/view/dockerman/container.htm:3 -msgid "Info" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:74 -msgid "Ingress" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:75 -msgid "" -"Ingress network is the network which provides the routing-mesh in swarm mode" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container.htm:8 -msgid "Inspect" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:477 -msgid "Interactive (-i)" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:86 -msgid "Internal" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:66 -msgid "Ipvlan Mode" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:43 -msgid "" -"It replaces the daemon registry mirrors with a new set of registry mirrors" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:238 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:264 -msgid "Kill" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:70 -msgid "L2 bridge" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:71 -msgid "L3 bridge" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:359 -msgid "Links" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:527 -msgid "Links with other containers" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:283 -#: applications/luci-app-dockerman/luasrc/view/dockerman/images_load.htm:2 -msgid "Load" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:49 -msgid "Log Level" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:661 -msgid "Log driver options" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container.htm:9 -msgid "Logs" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:43 -msgid "MAC VLAN" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:589 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:644 -msgid "Memory" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:783 -msgid "Memory Useage" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:645 -msgid "" -"Memory limit (format: []). Number is a positive integer. Unit " -"can be one of b, k, m, or g. Minimum is 4M" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:590 -msgid "" -"Memory limit (format: []). Number is a positive integer. Unit " -"can be one of b, k, m, or g. Minimum is 4M." -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:57 -msgid "Mode" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/volumes.lua:90 -msgid "Mount Point" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:603 -msgid "Mount tmpfs directory" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:343 -msgid "Mount/Volume" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:175 -msgid "Mounts" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:295 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:419 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/volumes.lua:83 -msgid "Name" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:37 -msgid "Name of the network that can be selected during container creation" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:394 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:528 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:169 -msgid "Network" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua:80 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:36 -msgid "Network Name" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/controller/dockerman.lua:40 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:518 -#: applications/luci-app-dockerman/luasrc/view/dockerman/overview.htm:169 -msgid "Networks" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua:59 -msgid "Networks overview" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua:104 -msgid "New" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:39 -#: applications/luci-app-dockerman/luasrc/view/dockerman/images_import.htm:54 -msgid "New tag" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:627 -msgid "Number of CPUs. Number is a fractional number. 0.000 means no limit" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:574 -msgid "Number of CPUs. Number is a fractional number. 0.000 means no limit." -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:73 -msgid "" -"On this page all images are displayed that are available on the system and " -"with which a container can be created." -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:193 -msgid "On this page, the selected container can be managed." -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:82 -msgid "Options" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:45 -msgid "Overlay network" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/controller/dockerman.lua:37 -msgid "Overview" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm:33 -msgid "PLEASE CONFIRM" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua:84 -msgid "Parent Interface" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:64 -msgid "Pass-through (Mirror physical device to single MAC VLAN)" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/images_import.htm:54 -msgid "Please input new tag" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm:270 -msgid "Please input the PATH and select the file !" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:82 -msgid "Please input the PORT or HOST IP of remote docker instance!" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:86 -msgid "Please input the SOCKET PATH of docker daemon!" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/newcontainer_resolve.htm:91 -msgid "Plese input command line:" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:355 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:172 -msgid "Ports" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:124 -msgid "Ports allowed to be accessed" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:62 -msgid "Private (Prevent communication between MAC VLANs)" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:504 -msgid "Privileged" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:561 -msgid "Publish container's port(s) to the host" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:100 -msgid "Pull" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:83 -msgid "Pull Image" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:42 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:48 -msgid "Registry Mirrors" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:73 -msgid "Remote Endpoint" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:99 -msgid "Remote Host" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:106 -msgid "Remote Port" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:274 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:274 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:210 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua:115 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/volumes.lua:108 -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm:173 -msgid "Remove" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:43 -#: applications/luci-app-dockerman/luasrc/view/dockerman/images_import.htm:82 -msgid "Remove tag" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm:171 -msgid "Rename" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:145 -msgid "RepoTags" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:469 -msgid "Resolve CLI" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container.htm:4 -msgid "Resources" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:220 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:244 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:87 -msgid "Restart" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:334 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:427 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:510 -msgid "Restart Policy" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:86 -msgid "Restrict external access to the network" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/cbi/inlinevalue.htm:31 -msgid "Reveal/hide password" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:566 -msgid "Run command" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:230 -msgid "Save" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:533 -msgid "Set custom DNS servers" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:547 -msgid "Set environment variables to inside the container" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:50 -msgid "Set the logging level" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:151 -msgid "Size" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:61 -msgid "" -"Specifies where the Docker daemon will listen for client connections " -"(default: unix:///var/run/docker.sock)" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:211 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:234 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:65 -msgid "Start" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:319 -msgid "Start Time" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:789 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:790 -#: applications/luci-app-dockerman/luasrc/view/dockerman/container.htm:5 -msgid "Stats" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:308 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:165 -msgid "Status" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:229 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:254 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:65 -msgid "Stop" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/newcontainer_resolve.htm:91 -msgid "Submit" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua:86 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:101 -msgid "Subnet" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:375 -msgid "Sysctl" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:610 -msgid "Sysctl(--sysctl)" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:611 -msgid "Sysctls (kernel parameters) options" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:792 -msgid "TOP" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:483 -msgid "TTY (-t)" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_stats.htm:56 -msgid "TX/RX" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:579 -msgid "The hostname to use for the container" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:662 -msgid "The logging configuration for this container" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:540 -msgid "" -"The user that commands are run as inside the container.(format: name|uid[:" -"group|gid])" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:129 -msgid "" -"This page displays all containers that have been created on the connected " -"docker host." -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua:55 -msgid "" -"This page displays all docker networks that have been created on the " -"connected docker host." -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:367 -msgid "Tmpfs" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:602 -msgid "Tmpfs(--tmpfs)" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:45 -msgid "Total Memory" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:697 -msgid "UID" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:297 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:336 -msgid "Update" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:256 -msgid "Upgrade" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm:7 -msgid "Upload" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm:303 -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm:304 -msgid "Upload Error" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm:294 -msgid "Upload Success" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_stats.htm:48 -msgid "Upload/Download" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:339 -msgid "User" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:539 -msgid "User(-u)" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:63 -msgid "VEPA (Virtual Ethernet Port Aggregator)" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/controller/dockerman.lua:41 -#: applications/luci-app-dockerman/luasrc/view/dockerman/overview.htm:187 -msgid "Volumes" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/volumes.lua:73 -msgid "Volumes overview" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:53 -msgid "Warning" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:126 -msgid "" -"When pressing the Import button, both a local image can be loaded onto the " -"system and a valid image tar can be downloaded from remote." -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:124 -msgid "" -"Which Port(s) can be accessed, it's not restricted by the Allowed Access " -"interfaces configuration. Use this configuration with caution!" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:118 -msgid "" -"Which interface(s) can access containers under the bridge network, fill-in " -"Interface Name" -msgstr "" diff --git a/luci-app-dockerman/po/zh-cn/dockerman.po b/luci-app-dockerman/po/zh-cn/dockerman.po deleted file mode 100755 index 2bdc11b8d..000000000 --- a/luci-app-dockerman/po/zh-cn/dockerman.po +++ /dev/null @@ -1,1094 +0,0 @@ -msgid "" -msgstr "" -"PO-Revision-Date: 2021-03-19 04:16+0000\n" -"Last-Translator: Eric \n" -"Language-Team: Chinese (Simplified) \n" -"Language: zh_Hans\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 4.5.2-dev\n" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:619 -msgid "A list of kernel capabilities to add to the container" -msgstr "要添加到容器的内核功能列表" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:69 -msgid "Access Control" -msgstr "访问控制" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:223 -msgid "Add" -msgstr "新增" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:595 -msgid "Add host device to the container" -msgstr "将主机设备添加到容器" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:571 -msgid "Advance" -msgstr "高级选项" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:586 -msgid "Allocates an ephemeral host port for all of a container's exposed ports" -msgstr "为容器的所有暴露端口分配临时主机端口" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:118 -msgid "Allowed access interfaces" -msgstr "允许的访问接口" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:498 -msgid "Always pull image first" -msgstr "总是先拉取镜像" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:29 -msgid "" -"An overview with the relevant data is displayed here with which the LuCI " -"docker client is connected." -msgstr "在此展示与LuCI docker客户端相连接的相关数据的概览。" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:43 -msgid "Api Version" -msgstr "Api 版本" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:94 -msgid "Auto create macvlan interface in Openwrt" -msgstr "在 Openwrt 中自动创建 macvlan 界面" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:18 -msgid "Auto start" -msgstr "自动启动" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:134 -msgid "Available" -msgstr "可用" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:47 -msgid "Base device" -msgstr "基设备" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:553 -msgid "Bind Mount(-v)" -msgstr "绑定挂载(-v)" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:554 -msgid "Bind mount a volume" -msgstr "绑定挂载卷" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:596 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:652 -msgid "Block IO Weight" -msgstr "块 IO 权重" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:653 -msgid "" -"Block IO weight (relative weight) accepts a weight value between 10 and 1000" -msgstr "块 IO 权重(相对权重)接受10到1000之间的数值" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:597 -msgid "" -"Block IO weight (relative weight) accepts a weight value between 10 and 1000." -msgstr "块 IO 权重(相对权重)接受10到1000之间的数值。" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:61 -msgid "Bridge (Support direct communication between MAC VLANs)" -msgstr "桥接(支持 MAC VLAN 之间的直接通信)" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:42 -msgid "Bridge device" -msgstr "Bridge device" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:84 -msgid "" -"By entering a valid image name with the corresponding version, the docker " -"image can be downloaded from the configured registry." -msgstr "" -"通过输入具有相应版本的有效映像名称,可以从镜像存储中心(Registry)中下载" -"docker映像。" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:618 -msgid "CAP-ADD(--cap-add)" -msgstr "权限控制(--cap-add)" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:581 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:635 -msgid "CPU Shares Weight" -msgstr "CPU 共享权重" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:779 -msgid "CPU Useage" -msgstr "CPU 使用率" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:636 -msgid "" -"CPU shares relative weight, if 0 is set, the system will ignore the value " -"and use the default of 1024" -msgstr "CPU 共享相对权重,如果设置为 0,则系统将忽略该值并使用默认值 1024" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:582 -msgid "" -"CPU shares relative weight, if 0 is set, the system will ignore the value " -"and use the default of 1024." -msgstr "CPU 共享相对权重,如果设置为 0,则系统将忽略该值并使用默认值 1024。" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:573 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:626 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:44 -msgid "CPUs" -msgstr "线程数量" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:159 -msgid "Can NOT connect to docker daemon, please check!!" -msgstr "无法连接到docker守护进程(docker daemon),请检查!!" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/newcontainer_resolve.htm:91 -msgid "Cancel" -msgstr "取消" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:60 -msgid "Client connection" -msgstr "客户端连接" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:347 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:687 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:182 -msgid "Command" -msgstr "命令" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/newcontainer_resolve.htm:100 -msgid "Command line" -msgstr "命令行" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/newcontainer_resolve.htm:72 -msgid "Command line Error" -msgstr "命令行错误" - -#: applications/luci-app-dockerman/luasrc/controller/dockerman.lua:17 -msgid "Configuration" -msgstr "配置" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:36 -msgid "Configure the default bridge network" -msgstr "配置默认桥接网络" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:405 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:707 -msgid "Connect" -msgstr "连接" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:403 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:437 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:473 -msgid "Connect Network" -msgstr "连接网络" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:74 -msgid "Connect to remote docker endpoint" -msgstr "连接到远程docker" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container.htm:7 -msgid "Console" -msgstr "控制台" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:161 -msgid "Container Info" -msgstr "容器信息" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:650 -msgid "Container Inspect" -msgstr "检查容器" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:671 -msgid "Container Logs" -msgstr "容器日志" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:473 -msgid "Container Name" -msgstr "容器名称" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:92 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:58 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/volumes.lua:29 -msgid "Container detail" -msgstr "容器详情" - -#: applications/luci-app-dockerman/luasrc/controller/dockerman.lua:38 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:142 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:148 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/volumes.lua:87 -#: applications/luci-app-dockerman/luasrc/view/dockerman/overview.htm:133 -msgid "Containers" -msgstr "容器" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:94 -msgid "Create macvlan interface" -msgstr "创建 macvlan 接口" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:465 -msgid "Create new docker container" -msgstr "创建 docker 容器" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:31 -msgid "Create new docker network" -msgstr "创建 docker 网络" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:312 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:153 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/volumes.lua:92 -msgid "Created" -msgstr "创建时间" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm:33 -msgid "DELETING" -msgstr "删除中" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:371 -msgid "DNS" -msgstr "DNS" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:51 -msgid "Debug" -msgstr "调试" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:35 -msgid "Default bridge" -msgstr "默认桥接" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:363 -msgid "Device" -msgstr "设备" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:594 -msgid "Device(--device)" -msgstr "设备(--device)" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:396 -msgid "Disconnect" -msgstr "断开" - -#: applications/luci-app-dockerman/luasrc/controller/dockerman.lua:14 -msgid "Docker" -msgstr "Docker" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:12 -msgid "Docker - Configuration" -msgstr "Docker - 配置" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:192 -msgid "Docker - Container (%s)" -msgstr "Docker - 容器 (%s)" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:128 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:450 -msgid "Docker - Containers" -msgstr "Docker - 容器" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/logs.htm:3 -msgid "Docker - Events" -msgstr "Docker - 事件" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:72 -msgid "Docker - Images" -msgstr "Docker - 镜像" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:15 -msgid "Docker - Network" -msgstr "Docker - 网络" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua:54 -msgid "Docker - Networks" -msgstr "Docker - 网络" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:28 -msgid "Docker - Overview" -msgstr "Docker - 概览" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/volumes.lua:69 -msgid "Docker - Volumes" -msgstr "Docker - 存储卷" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:16 -msgid "Docker Daemon settings" -msgstr "Docker 服务端(Docker Daemon)设置" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:489 -msgid "Docker Image" -msgstr "Docker 镜像" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:30 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:46 -msgid "Docker Root Dir" -msgstr "Docker 根目录" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:93 -msgid "Docker Socket Path" -msgstr "Docker 套接字路径" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:42 -msgid "Docker Version" -msgstr "Docker 版本" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/apply_widget.htm:91 -msgid "Docker actions done." -msgstr "Docker 执行完成。" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:70 -msgid "DockerMan" -msgstr "DockerMan" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:13 -msgid "DockerMan is a simple docker manager client for LuCI" -msgstr "DockerMan是用于LuCI的简单docker管理器客户端" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:68 -msgid "DockerMan settings" -msgstr "DockerMan设置" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm:172 -msgid "Download" -msgstr "下载" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua:82 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:40 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/volumes.lua:85 -msgid "Driver" -msgstr "驱动" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:265 -msgid "Duplicate/Edit" -msgstr "复制/编辑" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:120 -msgid "Enable IPv6" -msgstr "启用 IPv6" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:351 -msgid "Env" -msgstr "环境变量" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:546 -msgid "Environmental Variable(-e)" -msgstr "环境变量(-e)" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:54 -msgid "Error" -msgstr "错误" - -#: applications/luci-app-dockerman/luasrc/controller/dockerman.lua:42 -#: applications/luci-app-dockerman/luasrc/view/dockerman/logs.htm:5 -msgid "Events" -msgstr "事件" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:116 -msgid "Exclude IPs" -msgstr "排除 IP" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:247 -msgid "Export" -msgstr "导出" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:585 -msgid "Exposed All Ports(-P)" -msgstr "暴露所有端口(-P)" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:560 -msgid "Exposed Ports(-p)" -msgstr "暴露端口(-p)" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:55 -msgid "Fatal" -msgstr "致命的" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container.htm:6 -msgid "File" -msgstr "文件" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:324 -msgid "Finish Time" -msgstr "完成时间" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:220 -msgid "Force Remove" -msgstr "强制移除" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua:88 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:106 -msgid "Gateway" -msgstr "网关" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:33 -msgid "Github" -msgstr "Github" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/cbi/inlinevalue.htm:4 -msgid "Go to relevant configuration page" -msgstr "进入相关配置页面" - -#: applications/luci-app-dockerman/root/usr/share/rpcd/acl.d/luci-app-dockerman.json:3 -msgid "Grant UCI access for luci-app-dockerman" -msgstr "授予 UCI 访问 luci-app-dockerman 的权限" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:330 -msgid "Healthy" -msgstr "健康" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:578 -msgid "Host Name" -msgstr "主机名" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:100 -msgid "Host or IP Address for the connection to a remote docker instance" -msgstr "连接到远程Docker实例的主机名或IP地址" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:300 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:142 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua:78 -msgid "ID" -msgstr "ID" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:44 -msgid "IP VLAN" -msgstr "IP VLAN" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:111 -msgid "IP range" -msgstr "IP 范围" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:522 -msgid "IPv4 Address" -msgstr "IPv4 地址" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:132 -msgid "IPv6 Gateway" -msgstr "IPv6 网关" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:126 -msgid "IPv6 Subnet" -msgstr "IPv6 子网" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:304 -#: applications/luci-app-dockerman/luasrc/view/dockerman/images_import.htm:54 -msgid "Image" -msgstr "镜像" - -#: applications/luci-app-dockerman/luasrc/controller/dockerman.lua:39 -#: applications/luci-app-dockerman/luasrc/view/dockerman/overview.htm:151 -msgid "Images" -msgstr "镜像" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:132 -msgid "Images overview" -msgstr "镜像概览" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/images_import.htm:4 -msgid "Import" -msgstr "导入" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:125 -msgid "Import Image" -msgstr "导入镜像" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:47 -msgid "Index Server Address" -msgstr "索引服务器地址" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:52 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:414 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:102 -#: applications/luci-app-dockerman/luasrc/view/dockerman/container.htm:3 -msgid "Info" -msgstr "信息" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:74 -msgid "Ingress" -msgstr "入口" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:75 -msgid "" -"Ingress network is the network which provides the routing-mesh in swarm mode" -msgstr "入口网络是以群模式提供路由网格的网络" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container.htm:8 -msgid "Inspect" -msgstr "检查" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:477 -msgid "Interactive (-i)" -msgstr "交互(-i)" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:86 -msgid "Internal" -msgstr "内部" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:66 -msgid "Ipvlan Mode" -msgstr "Ipvlan 模式" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:43 -msgid "" -"It replaces the daemon registry mirrors with a new set of registry mirrors" -msgstr "" -"设置新的镜像存储中心(Registry)镜像源,这将取代服务端(daemon)配置的镜像存" -"储中心(Registry)的镜像源" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:238 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:264 -msgid "Kill" -msgstr "强制关闭" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:70 -msgid "L2 bridge" -msgstr "L2 桥接" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:71 -msgid "L3 bridge" -msgstr "L3 桥接" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:359 -msgid "Links" -msgstr "链接" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:527 -msgid "Links with other containers" -msgstr "与其他容器的链接" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:283 -#: applications/luci-app-dockerman/luasrc/view/dockerman/images_load.htm:2 -msgid "Load" -msgstr "负载" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:49 -msgid "Log Level" -msgstr "日志等级" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:661 -msgid "Log driver options" -msgstr "日志驱动选项" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container.htm:9 -msgid "Logs" -msgstr "日志" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:43 -msgid "MAC VLAN" -msgstr "MAC VLAN" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:589 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:644 -msgid "Memory" -msgstr "内存" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:783 -msgid "Memory Useage" -msgstr "内存使用率" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:645 -msgid "" -"Memory limit (format: []). Number is a positive integer. Unit " -"can be one of b, k, m, or g. Minimum is 4M" -msgstr "" -"内存限制(格式:<数字>[<单位>])。数字是正整数。单位可以是 b、k、m 或 g 之一。" -"最小值为 4M" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:590 -msgid "" -"Memory limit (format: []). Number is a positive integer. Unit " -"can be one of b, k, m, or g. Minimum is 4M." -msgstr "" -"内存限制(格式:<数字>[<单位>])。数字是正整数。单位可以是 b、k、m 或 g 之一。" -"最小值为 4M。" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:57 -msgid "Mode" -msgstr "模式" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/volumes.lua:90 -msgid "Mount Point" -msgstr "挂载点" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:603 -msgid "Mount tmpfs directory" -msgstr "挂载 tmpfs 目录" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:343 -msgid "Mount/Volume" -msgstr "挂载/卷" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:175 -msgid "Mounts" -msgstr "挂载点" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:295 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:419 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/volumes.lua:83 -msgid "Name" -msgstr "名称" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:37 -msgid "Name of the network that can be selected during container creation" -msgstr "在容器创建时可以选择网络的名称" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:394 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:528 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:169 -msgid "Network" -msgstr "网络" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua:80 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:36 -msgid "Network Name" -msgstr "网络名称" - -#: applications/luci-app-dockerman/luasrc/controller/dockerman.lua:40 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:518 -#: applications/luci-app-dockerman/luasrc/view/dockerman/overview.htm:169 -msgid "Networks" -msgstr "网络" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua:59 -msgid "Networks overview" -msgstr "网络概览" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua:104 -msgid "New" -msgstr "新建" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:39 -#: applications/luci-app-dockerman/luasrc/view/dockerman/images_import.htm:54 -msgid "New tag" -msgstr "新建标签" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:627 -msgid "Number of CPUs. Number is a fractional number. 0.000 means no limit" -msgstr "CPU 数量。数字是小数。0.000 表示没有限制" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:574 -msgid "Number of CPUs. Number is a fractional number. 0.000 means no limit." -msgstr "CPU 数量。数字是小数。0.000 表示没有限制。" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:73 -msgid "" -"On this page all images are displayed that are available on the system and " -"with which a container can be created." -msgstr "在此页面上,显示系统上可用的所有镜像文件,并可以用它们来创建容器" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:193 -msgid "On this page, the selected container can be managed." -msgstr "在此页面可以管理所选的容器。" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:82 -msgid "Options" -msgstr "选项" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:45 -msgid "Overlay network" -msgstr "Overlay network" - -#: applications/luci-app-dockerman/luasrc/controller/dockerman.lua:37 -msgid "Overview" -msgstr "概览" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm:33 -msgid "PLEASE CONFIRM" -msgstr "请确认" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua:84 -msgid "Parent Interface" -msgstr "父接口" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:64 -msgid "Pass-through (Mirror physical device to single MAC VLAN)" -msgstr "直通(将物理设备镜像到单独的 MAC VLAN)" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/images_import.htm:54 -msgid "Please input new tag" -msgstr "请输入新的标签" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm:270 -msgid "Please input the PATH and select the file !" -msgstr "请输入路径并选择文件!" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:82 -msgid "Please input the PORT or HOST IP of remote docker instance!" -msgstr "请输入合法的远程docker实例端口和主机IP" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:86 -msgid "Please input the SOCKET PATH of docker daemon!" -msgstr "请输入合法docker服务端(docker daemon)的SOCKET地址" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/newcontainer_resolve.htm:91 -msgid "Plese input command line:" -msgstr "请输入 的命令行:" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:355 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:172 -msgid "Ports" -msgstr "端口" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:124 -msgid "Ports allowed to be accessed" -msgstr "允许访问的端口" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:62 -msgid "Private (Prevent communication between MAC VLANs)" -msgstr "专用(阻止 MAC VLAN 之间的通信)" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:504 -msgid "Privileged" -msgstr "特权模式" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:561 -msgid "Publish container's port(s) to the host" -msgstr "将容器的端口发布到主机" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:100 -msgid "Pull" -msgstr "拉取" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:83 -msgid "Pull Image" -msgstr "拉取镜像" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:42 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:48 -msgid "Registry Mirrors" -msgstr "镜像加速器" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:73 -msgid "Remote Endpoint" -msgstr "远程实例" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:99 -msgid "Remote Host" -msgstr "远程主机" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:106 -msgid "Remote Port" -msgstr "远程端口" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:274 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:274 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:210 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua:115 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/volumes.lua:108 -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm:173 -msgid "Remove" -msgstr "移除" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:43 -#: applications/luci-app-dockerman/luasrc/view/dockerman/images_import.htm:82 -msgid "Remove tag" -msgstr "移除标签" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm:171 -msgid "Rename" -msgstr "重命名" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:145 -msgid "RepoTags" -msgstr "仓库标签" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:469 -msgid "Resolve CLI" -msgstr "解析 CLI" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container.htm:4 -msgid "Resources" -msgstr "资源" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:220 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:244 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:87 -msgid "Restart" -msgstr "重新启动" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:334 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:427 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:510 -msgid "Restart Policy" -msgstr "重启策略" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:86 -msgid "Restrict external access to the network" -msgstr "限制外部网络访问" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/cbi/inlinevalue.htm:31 -msgid "Reveal/hide password" -msgstr "显示/隐藏 密码" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:566 -msgid "Run command" -msgstr "运行命令" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:230 -msgid "Save" -msgstr "保存" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:533 -msgid "Set custom DNS servers" -msgstr "设置自定义 DNS 服务器" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:547 -msgid "Set environment variables to inside the container" -msgstr "在容器内部设置环境变量" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:50 -msgid "Set the logging level" -msgstr "设置日志记录级别" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:151 -msgid "Size" -msgstr "大小" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:61 -msgid "" -"Specifies where the Docker daemon will listen for client connections " -"(default: unix:///var/run/docker.sock)" -msgstr "" -"指定Docker服务端(Docker daemon)将在何处侦听客户端连接(默认: unix:///var/" -"run/docker.sock)" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:211 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:234 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:65 -msgid "Start" -msgstr "启动" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:319 -msgid "Start Time" -msgstr "开始时间" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:789 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:790 -#: applications/luci-app-dockerman/luasrc/view/dockerman/container.htm:5 -msgid "Stats" -msgstr "状态" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:308 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:165 -msgid "Status" -msgstr "状态" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:229 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:254 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:65 -msgid "Stop" -msgstr "停止" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/newcontainer_resolve.htm:91 -msgid "Submit" -msgstr "提交" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua:86 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:101 -msgid "Subnet" -msgstr "子网" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:375 -msgid "Sysctl" -msgstr "系统控制" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:610 -msgid "Sysctl(--sysctl)" -msgstr "系统控制(--sysctl)" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:611 -msgid "Sysctls (kernel parameters) options" -msgstr "系统控制(内核参数)选项" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:792 -msgid "TOP" -msgstr "TOP" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:483 -msgid "TTY (-t)" -msgstr "TTY(-t)" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_stats.htm:56 -msgid "TX/RX" -msgstr "发射/接收" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:579 -msgid "The hostname to use for the container" -msgstr "容器使用的主机名" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:662 -msgid "The logging configuration for this container" -msgstr "该容器的日志记录配置" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:540 -msgid "" -"The user that commands are run as inside the container.(format: name|uid[:" -"group|gid])" -msgstr "在容器中以用户运行命令。(格式:name|uid[:group|gid])" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:129 -msgid "" -"This page displays all containers that have been created on the connected " -"docker host." -msgstr "此页面显示在连接的Docker主机上已创建的所有容器。" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua:55 -msgid "" -"This page displays all docker networks that have been created on the " -"connected docker host." -msgstr "此页面显示在已连接的Docker主机上创建的所有Docker网络。" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:367 -msgid "Tmpfs" -msgstr "Tmpfs" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:602 -msgid "Tmpfs(--tmpfs)" -msgstr "Tmpfs(--tmpfs)" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:45 -msgid "Total Memory" -msgstr "总内存" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:697 -msgid "UID" -msgstr "UID" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:297 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:336 -msgid "Update" -msgstr "更新" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:256 -msgid "Upgrade" -msgstr "升级" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm:7 -msgid "Upload" -msgstr "上传" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm:303 -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm:304 -msgid "Upload Error" -msgstr "上传错误" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm:294 -msgid "Upload Success" -msgstr "上传成功" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_stats.htm:48 -msgid "Upload/Download" -msgstr "上传/下载" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:339 -msgid "User" -msgstr "用户" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:539 -msgid "User(-u)" -msgstr "用户(-u)" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:63 -msgid "VEPA (Virtual Ethernet Port Aggregator)" -msgstr "VEPA(虚拟以太网端口聚合器)" - -#: applications/luci-app-dockerman/luasrc/controller/dockerman.lua:41 -#: applications/luci-app-dockerman/luasrc/view/dockerman/overview.htm:187 -msgid "Volumes" -msgstr "存储卷" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/volumes.lua:73 -msgid "Volumes overview" -msgstr "卷概览" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:53 -msgid "Warning" -msgstr "警告" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:126 -msgid "" -"When pressing the Import button, both a local image can be loaded onto the " -"system and a valid image tar can be downloaded from remote." -msgstr "" -"按下导入按钮时,既可以将本地镜像文件加载到系统上,也可以从远程下载有效的Tar格" -"式的镜像文件。" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:124 -msgid "" -"Which Port(s) can be accessed, it's not restricted by the Allowed Access " -"interfaces configuration. Use this configuration with caution!" -msgstr "设置可以被访问的端口,该配置不受“允许的访问接口”配置的限制。请谨慎使用该配置选项!" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:118 -msgid "" -"Which interface(s) can access containers under the bridge network, fill-in " -"Interface Name" -msgstr "哪些接口可以访问桥接网络下的容器,请填写接口名称" - -#~ msgid "Containers allowed to be accessed" -#~ msgstr "允许访问的容器" - -#~ msgid "" -#~ "Which container(s) under bridge network can be accessed, even from " -#~ "interfaces that are not allowed, fill-in Container Id or Name" -#~ msgstr "" -#~ "桥接网络下哪些容器可以访问,即使是不允许从接口访问,也要填写容器 ID 或名称" - -#~ msgid "Connect to remote endpoint" -#~ msgstr "连接到远程终端" - -#~ msgid "Global settings" -#~ msgstr "全局设定" - -#~ msgid "Path" -#~ msgstr "路径" - -#~ msgid "Please input the PATH !" -#~ msgstr "请输入合法路径!" - -#~ msgid "Setting" -#~ msgstr "设置" - -#~ msgid "Specifies where the Docker daemon will listen for client connections" -#~ msgstr "指定Docker服务端(Docker daemon)侦听客户端连接的位置" - -#~ msgid "Docker Container" -#~ msgstr "Docker 容器" - -#~ msgid "" -#~ "DockerMan is a Simple Docker manager client for LuCI, If you have any " -#~ "issue please visit:" -#~ msgstr "" -#~ "DockerMan 是一个简单的 LuCI 客户端 Docker 管理器,如果您有任何问题,请访" -#~ "问:" - -#~ msgid "Import Images" -#~ msgstr "导入镜像" - -#~ msgid "New Container" -#~ msgstr "新建容器" - -#~ msgid "New Network" -#~ msgstr "新建网络" - -#~ msgid "Macvlan Mode" -#~ msgstr "Macvlan 模式" - -#~ msgid "" -#~ "Daemon unix socket (unix:///var/run/docker.sock) or TCP Remote Hosts " -#~ "(tcp://0.0.0.0:2375), default: unix:///var/run/docker.sock" -#~ msgstr "" -#~ "守护进程 unix 套接字 (unix:///var/run/docker.sock) 或 TCP 远程主机 " -#~ "(tcp://0.0.0.0:2375),默认值:unix:///var/run/docker.sock" - -#~ msgid "Docker Daemon" -#~ msgstr "Docker 服务端" - -#~ msgid "Dockerman connect to remote endpoint" -#~ msgstr "Dockerman 连接到远程端点" - -#~ msgid "Enable" -#~ msgstr "启用" - -#~ msgid "Server Host" -#~ msgstr "服务器主机" - -#~ msgid "Contaienr Info" -#~ msgstr "容器信息" diff --git a/luci-app-dockerman/po/zh_Hans b/luci-app-dockerman/po/zh_Hans deleted file mode 100755 index 41451e4a1..000000000 --- a/luci-app-dockerman/po/zh_Hans +++ /dev/null @@ -1 +0,0 @@ -zh-cn \ No newline at end of file diff --git a/luci-app-dockerman/postinst b/luci-app-dockerman/postinst deleted file mode 100755 index b0db1cb89..000000000 --- a/luci-app-dockerman/postinst +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -/init.sh env -touch /etc/config/dockerd -uci set dockerd.dockerman=dockerman -uci set dockerd.dockerman.socket_path=`uci get dockerd.dockerman.socket_path 2&> /dev/null || echo '/var/run/docker.sock'` -uci set dockerd.dockerman.status_path=`uci get dockerd.dockerman.status_path 2&> /dev/null || echo '/tmp/.docker_action_status'` -uci set dockerd.dockerman.debug=`uci get dockerd.dockerman.debug 2&> /dev/null || echo 'false'` -uci set dockerd.dockerman.debug_path=`uci get dockerd.dockerman.debug_path 2&> /dev/null || echo '/tmp/.docker_debug'` -uci set dockerd.dockerman.remote_port=`uci get dockerd.dockerman.remote_port 2&> /dev/null || echo '2375'` -uci set dockerd.dockerman.remote_endpoint=`uci get dockerd.dockerman.remote_endpoint 2&> /dev/null || echo '0'` -uci del_list dockerd.dockerman.ac_allowed_interface='br-lan' -uci add_list dockerd.dockerman.ac_allowed_interface='br-lan' -uci commit dockerd \ No newline at end of file diff --git a/luci-app-dockerman/root/etc/init.d/dockerman b/luci-app-dockerman/root/etc/init.d/dockerman deleted file mode 100755 index 80309aeab..000000000 --- a/luci-app-dockerman/root/etc/init.d/dockerman +++ /dev/null @@ -1,131 +0,0 @@ -#!/bin/sh /etc/rc.common - -START=99 -USE_PROCD=1 -# PROCD_DEBUG=1 -config_load 'dockerd' -# config_get daemon_ea "dockerman" daemon_ea -_DOCKERD=/etc/init.d/dockerd - -docker_running(){ - docker version > /dev/null 2>&1 - return $? -} - -add_ports() { - [ $# -eq 0 ] && return - $($_DOCKERD running) && docker_running || return 1 - ids=$@ - for id in $ids; do - id=$(docker ps --filter "ID=$id" --quiet) - [ -z "$id" ] && { - echo "Docker containner not running"; - return 1; - } - ports=$(docker ps --filter "ID=$id" --format "{{.Ports}}") - # echo "$ports" - for port in $ports; do - echo "$port" | grep -qE "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}:.*$" || continue; - [ "${port: -1}" == "," ] && port="${port:0:-1}" - local protocol="" - [ "${port%tcp}" != "$port" ] && protocol="/tcp" - [ "${port%udp}" != "$port" ] && protocol="/udp" - [ "$protocol" == "" ] && continue - port="${port%%->*}" - port="${port##*:}" - uci_add_list dockerd dockerman ac_allowed_ports "${port}${protocol}" - done - done - uci_commit dockerd -} - - -convert() { - _convert() { - _id=$1 - _id=$(docker ps --all --filter "ID=$_id" --quiet) - if [ -z "$_id" ]; then - uci_remove_list dockerd dockerman ac_allowed_container "$1" - return - fi - if /etc/init.d/dockerman add_ports "$_id"; then - uci_remove_list dockerd dockerman ac_allowed_container "$_id" - fi - } - config_list_foreach dockerman ac_allowed_container _convert - uci_commit dockerd -} - -iptables_append(){ - # Wait for a maximum of 10 second per command, retrying every millisecond - local iptables_wait_args="--wait 10 --wait-interval 1000" - if ! iptables ${iptables_wait_args} --check $@ 2>/dev/null; then - iptables ${iptables_wait_args} -A $@ 2>/dev/null - fi -} - -init_dockerman_chain(){ - iptables -N DOCKER-MAN >/dev/null 2>&1 - iptables -F DOCKER-MAN >/dev/null 2>&1 - iptables -D DOCKER-USER -j DOCKER-MAN >/dev/null 2>&1 - iptables -I DOCKER-USER -j DOCKER-MAN >/dev/null 2>&1 -} - -delete_dockerman_chain(){ - iptables -D DOCKER-USER -j DOCKER-MAN >/dev/null 2>&1 - iptables -F DOCKER-MAN >/dev/null 2>&1 - iptables -X DOCKER-MAN >/dev/null 2>&1 -} - -add_allowed_interface(){ - iptables_append DOCKER-MAN -i $1 -o docker0 -j RETURN -} - -add_allowed_ports(){ - port=$1 - if [ "${port%/tcp}" != "$port" ]; then - iptables_append DOCKER-MAN -p tcp -m conntrack --ctorigdstport ${port%/tcp} --ctdir ORIGINAL -j RETURN - elif [ "${port%/udp}" != "$port" ]; then - iptables_append DOCKER-MAN -p udp -m conntrack --ctorigdstport ${port%/udp} --ctdir ORIGINAL -j RETURN - fi -} - -handle_allowed_ports(){ - config_list_foreach "dockerman" "ac_allowed_ports" add_allowed_ports -} - -handle_allowed_interface(){ - config_list_foreach "dockerman" "ac_allowed_interface" add_allowed_interface - iptables_append DOCKER-MAN -m conntrack --ctstate ESTABLISHED,RELATED -o docker0 -j RETURN >/dev/null 2>&1 - iptables_append DOCKER-MAN -m conntrack --ctstate NEW,INVALID -o docker0 -j DROP >/dev/null 2>&1 - iptables_append DOCKER-MAN -j RETURN >/dev/null 2>&1 -} - -start_service(){ - [ -x "$_DOCKERD" ] && $($_DOCKERD enabled) || return 0 - delete_dockerman_chain - $($_DOCKERD running) && docker_running || return 0 - init_dockerman_chain - handle_allowed_ports - handle_allowed_interface -} - -stop_service(){ - delete_dockerman_chain -} - -service_triggers() { - procd_add_reload_trigger 'dockerd' -} - -reload_service() { - start -} - -boot() { - sleep 5s - start -} - -extra_command "add_ports" "Add allowed ports based on the container ID(s)" -extra_command "convert" "Convert Ac allowed container to AC allowed ports" diff --git a/luci-app-dockerman/root/etc/uci-defaults/luci-app-dockerman b/luci-app-dockerman/root/etc/uci-defaults/luci-app-dockerman deleted file mode 100755 index 4358728a1..000000000 --- a/luci-app-dockerman/root/etc/uci-defaults/luci-app-dockerman +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/sh - -. $IPKG_INSTROOT/lib/functions.sh - -[ -x "$(command -v dockerd)" ] && chmod +x /etc/init.d/dockerman && /etc/init.d/dockerman enable >/dev/null 2>&1 -sed -i 's/self:cfgvalue(section) or {}/self:cfgvalue(section) or self.default or {}/' /usr/lib/lua/luci/view/cbi/dynlist.htm -/etc/init.d/uhttpd restart >/dev/null 2>&1 -rm -fr /tmp/luci-indexcache /tmp/luci-modulecache >/dev/null 2>&1 -touch /etc/config/dockerd -ls /etc/rc.d/*dockerd &> /dev/null && uci -q set dockerd.globals.auto_start="1" || uci -q set dockerd.globals.auto_start="0" -uci -q batch <<-EOF >/dev/null - set uhttpd.main.script_timeout="3600" - commit uhttpd - set dockerd.dockerman=dockerman - set dockerd.dockerman.socket_path='/var/run/docker.sock' - set dockerd.dockerman.status_path='/tmp/.docker_action_status' - set dockerd.dockerman.debug='false' - set dockerd.dockerman.debug_path='/tmp/.docker_debug' - set dockerd.dockerman.remote_endpoint='0' - - del_list dockerd.dockerman.ac_allowed_interface='br-lan' - add_list dockerd.dockerman.ac_allowed_interface='br-lan' - - commit dockerd -EOF -# remove dockerd firewall -config_load dockerd -remove_firewall(){ - cfg=${1} - uci_remove dockerd ${1} -} -config_foreach remove_firewall firewall -# Convert ac_allowed_container to ac_allowed_ports -(sleep 30s && /etc/init.d/dockerman convert;/etc/init.d/dockerman restart) & - -exit 0 diff --git a/luci-app-dockerman/root/usr/share/rpcd/acl.d/luci-app-dockerman.json b/luci-app-dockerman/root/usr/share/rpcd/acl.d/luci-app-dockerman.json deleted file mode 100755 index 78c2c6418..000000000 --- a/luci-app-dockerman/root/usr/share/rpcd/acl.d/luci-app-dockerman.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "luci-app-dockerman": { - "description": "Grant UCI access for luci-app-dockerman", - "read": { - "uci": [ "dockerd" ] - }, - "write": { - "uci": [ "dockerd" ] - } - } -} diff --git a/luci-app-snmpd/Makefile b/luci-app-snmpd/Makefile old mode 100755 new mode 100644 index 12f22abd3..3cd753a5f --- a/luci-app-snmpd/Makefile +++ b/luci-app-snmpd/Makefile @@ -1,15 +1,11 @@ -# -# Copyright (C) 2018-2019 Ycarus (Yannick Chabanois) -# -# - include $(TOPDIR)/rules.mk +LUCI_TITLE:= Net-SNMP LuCI interface +LUCI_DEPENDS:=+luci-base +snmpd +LUCI_PKGARCH:=all +LUCI_DESCRIPTION:=Some common net-snmp config items. In no way is this comprehensive. -LUCI_TITLE:=LuCI SNMPD Interface -LUCI_DEPENDS:=+snmpd +snmptrapd +snmp-utils +snmp-mibs - -PKG_LICENSE:=GPLv3 - -#include ../luci/luci.mk +PKG_MAINTAINER:= Karl Palsson +PKG_LICENSE:=Apache-2.0 include $(TOPDIR)/feeds/luci/luci.mk + # call BuildPackage - OpenWrt buildroot signature diff --git a/luci-app-snmpd/htdocs/luci-static/resources/view/snmpd/snmpd.js b/luci-app-snmpd/htdocs/luci-static/resources/view/snmpd/snmpd.js new file mode 100644 index 000000000..b9e5e2853 --- /dev/null +++ b/luci-app-snmpd/htdocs/luci-static/resources/view/snmpd/snmpd.js @@ -0,0 +1,64 @@ +// SPDX: Apache-2.0 +// Karl Palsson 2021 +'use strict'; +'require form'; +'require ui'; +'require view'; + +var desc = _("" + + "SNMPD is a master daemon/agent for SNMP, from the " + + "net-snmp project. " + + "Note, OpenWrt has mostly complete UCI support for snmpd, but this LuCI applet " + + "only covers a few of those options. In particular, there is very little/no validation " + + "or help. See /etc/config/snmpd for manual configuration." +); + +return view.extend({ + render: function() { + var m, s, o; + + m = new form.Map("snmpd", _("net-snmp's SNMPD"), desc); + + s = m.section(form.TypedSection, "agent", _("Agent settings")); + s.anonymous = true; + o = s.option(form.Value, "agentaddress", _("The address the agent should listen on"), + _("Eg: UDP:161, or UDP:10.5.4.3:161 to only listen on a given interface")); + + s = m.section(form.TypedSection, "agentx", _("AgentX settings"), + _("Delete this section to disable AgentX")); + s.anonymous = true; + o = s.option(form.Value, "agentxsocket", _("The address the agent should allow AgentX connections to"), + _("This is only necessary if you have subagents using the agentX " + + "socket protocol. Eg: /var/run/agentx.sock")); + s.addremove = true; + + s = m.section(form.TypedSection, "com2sec", _("com2sec security")); + o = s.option(form.Value, "secname", "secname"); + o = s.option(form.Value, "source", "source"); + o = s.option(form.Value, "community", "community"); + + s = m.section(form.TypedSection, "group", "group", _("Groups help define access methods")); + s.addremove = true; + s.option(form.Value, "group", "group"); + s.option(form.Value, "version", "version"); + s.option(form.Value, "secname", "secname"); + + s = m.section(form.TypedSection, "access", "access"); + s.option(form.Value, "group", "group"); + s.option(form.Value, "context", "context"); + s.option(form.Value, "version", "version"); + s.option(form.Value, "level", "level"); + s.option(form.Value, "prefix", "prefix"); + s.option(form.Value, "read", "read"); + s.option(form.Value, "write", "write"); + s.option(form.Value, "notify", "notify"); + + s = m.section(form.TypedSection, "system", _("System"), _("Values used in the MIB2 System tree")); + s.anonymous = true; + s.option(form.Value, "sysLocation", "sysLocation"); + s.option(form.Value, "sysContact", "sysContact"); + s.option(form.Value, "sysName", "sysName"); + + return m.render(); + } +}); diff --git a/luci-app-snmpd/luasrc/controller/snmpd.lua b/luci-app-snmpd/luasrc/controller/snmpd.lua deleted file mode 100755 index 2694da219..000000000 --- a/luci-app-snmpd/luasrc/controller/snmpd.lua +++ /dev/null @@ -1,8 +0,0 @@ -local ucic = luci.model.uci.cursor() -local dt = require "luci.cbi.datatypes" -module("luci.controller.snmpd", package.seeall) - -function index() - entry({"admin", "network", "snmpd"}, alias("admin", "network", "snmpd", "index"), _("SNMPd")) - entry({"admin", "network", "snmpd", "index"}, cbi("snmpd")) -end diff --git a/luci-app-snmpd/luasrc/model/cbi/snmpd.lua b/luci-app-snmpd/luasrc/model/cbi/snmpd.lua deleted file mode 100755 index 132b3a1d2..000000000 --- a/luci-app-snmpd/luasrc/model/cbi/snmpd.lua +++ /dev/null @@ -1,141 +0,0 @@ --- Copyright 2018 Ycarus (Yannick Chabanois) --- Licensed to the public under the Apache License 2.0. - -m = Map("snmpd", translate("SNMPd"), translate("SNMPd settings interface (Beta)")) - -s = m:section(TypedSection, "snmpd", translate("General")) -s.addremove = false - -enabled = s:option(Flag, "enabled", translate("Enabled")) -enabled.rmempty = false - -network = s:option(Value, "network", translate("Networks")) -network.template = "cbi/network_netlist" -network.widget = "checkbox" -network.rmempty = true -network.cast = "string" -network.nocreate = true - -s = m:section(TypedSection, "system", translate("System")) -s.addremove = false - -sysLocation = s:option(Value, "sysLocation", translate("Location")) -sysContact = s:option(Value, "sysContact", translate("Contact")) -sysName = s:option(Value, "sysName", translate("Name")) ---sysServices = s:option(Value, "sysServices", translate("Services")) ---sysDescr = s:option(Value, "sysDescr", translate("Description")) ---sysObjectID = s:option(Value, "sysObjectID", translate("ObjectID")) - -s = m:section(TypedSection, "com2sec", translate("com2sec security")) -s.addremove = true - -secname = s:option(ListValue, "secname", translate("Server")) -secname.optional = false -secname:value("ro",translate("Read-only")) -secname:value("rw",translate("Read-write")) - -source = s:option(Value, "source", translate("Source")) -source.datatype = "host" -source.optional = false -source.rmempty = false - -community = s:option(Value, "community", translate("Community")) -community.optional = false -community.rmempty = false - ---s = m:section(TypedSection, "com2sec6", translate("com2sec6")) ---s.addremove = true - ---secname = s:option(ListValue, "secname", translate("secname")) ---secname.optional = false ---secname:value("ro",translate("Read-only")) ---secname:value("rw",translate("Read-write")) - ---source = s:option(Value, "source", translate("Source")) ---source.datatype = "host" ---source.optional = false ---source.rmempty = false - ---community = s:option(Value, "community", translate("Community")) ---community.optional = false ---community.rmempty = false - -s = m:section(TypedSection, "group", translate("Group"), translate("Groups help define access methods")) -s.addremove = true -s.anonymous = false - -secname = s:option(ListValue, "secname", translate("secname")) -secname.optional = false -secname:value("ro",translate("Read-only")) -secname:value("rw",translate("Read-write")) - -group = s:option(Value, "group", translate("Group")) -group.optional = false -group.rmempty = false - -version = s:option(ListValue, "version", translate("version")) -version.optional = false -version:value("v1","v1") -version:value("v2c","v2c") -version:value("usm","usm") - -s = m:section(TypedSection, "access", translate("Access")) -s.addremove = true -s.anonymous = false - -group = s:option(Value, "group", translate("Group")) -group.optional = false -group.rmempty = false - -version = s:option(ListValue, "version", translate("version")) -version.optional = false -version:value("any",translate("any")) -version:value("v1","v1") -version:value("v2c","v2c") -version:value("usm","usm") - -context = s:option(ListValue, "context", translate("Context")) -context.optional = false -context:value("none","none") - -level = s:option(ListValue, "level", translate("Level")) -level.optional = false -level:value("noauth",translate("noauth")) -level:value("auth",translate("auth")) - -read = s:option(ListValue, "read", translate("Read")) -read.optional = false -read:value("all","all") -read:value("none","none") - -write = s:option(ListValue, "write", translate("Write")) -write.optional = false -write:value("all","all") -write:value("none","none") - -notify = s:option(ListValue, "notify", translate("Notify")) -notify.optional = false -notify:value("all","all") -notify:value("none","none") - ---s = m:section(TypedSection, "engineid", translate("engineid")) ---s.addremove = false ---s.anonymous = true - ---engineid = s:option(Value, "engineid", translate("engineid")) ---engineidtype = s:option(ListValue, "engineidtype", translate("engineidtype")) ---engineidtype:value("1",translate("IPv4")) ---engineidtype:value("2",translate("IPv6")) ---engineidtype:value("3",translate("MAC")) ---engineidnic = s:option(Value, "engineidnic", translate("engineidnic")) - -s = m:section(TypedSection, "exec", translate("Exec")) -s.addremove = true -s.anonymous = true - -miboid = s:option(Value, "miboid", translate("ObjectID")) -name = s:option(Value, "name", translate("Name")) -prog = s:option(Value, "prog", translate("Program")) -args = s:option(Value, "args", translate("Arguments")) - -return m diff --git a/luci-app-snmpd/luasrc/view/snmpd.htm b/luci-app-snmpd/luasrc/view/snmpd.htm deleted file mode 100755 index 74e60ca9a..000000000 --- a/luci-app-snmpd/luasrc/view/snmpd.htm +++ /dev/null @@ -1,132 +0,0 @@ -<%+header%> - - - -<% - local uci = require("luci.model.uci").cursor() - local hosts = uci:get_list("dhcp", uci:get_first("dhcp","dnsmasq"), "ipset") - local ips = uci:get_list("omr-bypass", "ips", "ip") - local dpi = uci:get_list("omr-bypass", "dpi", "proto") - local tmpfile = os.tmpname() - local dpi_available_proto = luci.util.execi("cat /proc/net/xt_ndpi/proto | awk '{print $3}' | sort -u | head -n -1") - local sys = require "luci.sys" - local ifaces = sys.net:devices() - local bypassif = uci:get("omr-bypass","defaults","ifname") or "" -%> -<% if stderr and #stderr > 0 then %>
<%=pcdata(stderr)%>
<% end %> -
-
-

<%:SNMPd%>

-
- <%:General%> -
-
- -
- checked<% end %>> -
-
-
- network -
-
-
- -
-
-
-
- -
-
-
-
- -
-
- -

<%:General%>

- -
-
-
-
-
<%:Domain, IP or network%>
-
<%:Output interface%>
-
-
-
-
-
- -
-
-
- -
-
-
-
- -
-
-
-

<%:Protocols%>

-
-
-
-
<%:Protocols%>
-
<%:Output interface%>
-
-
-
-
-<% - local allprt="""" - local protos = {} - for l in io.lines("/proc/net/xt_ndpi/proto") do - local a,b,c,d = l:match('(%w+) (%w+)') - if b ~= "2" and not string.match(b,"custom") then - table.insert(protos,b) - end - end - table.sort(protos) - for _,b in ipairs(protos) do - allprt=allprt .. ","" .. b .. """ - end -%> -
-
- -
-
-
- -
-
-
-
- -
-
-
-
- - -
- - -<%+footer%> diff --git a/luci-app-snmpd/po/de/snmpd.po b/luci-app-snmpd/po/de/snmpd.po deleted file mode 100755 index cfe49bcae..000000000 --- a/luci-app-snmpd/po/de/snmpd.po +++ /dev/null @@ -1,184 +0,0 @@ -msgid "" -msgstr "" -"PO-Revision-Date: 2020-10-05 12:39+0000\n" -"Last-Translator: Weblate Admin \n" -"Language-Team: German \n" -"Language: de\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.0.4\n" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:82 -msgid "Access" -msgstr "Zugriff" - -#: luci-app-snmpd/luasrc/view/snmpd.htm:81 -#: luci-app-snmpd/luasrc/view/snmpd.htm:122 -msgid "Add" -msgstr "Hinzufügen" - -#: luci-app-snmpd/luasrc/view/snmpd.htm:66 -#: luci-app-snmpd/luasrc/view/snmpd.htm:116 -msgid "All" -msgstr "alle" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:139 -msgid "Arguments" -msgstr "Parameter" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:42 -msgid "Community" -msgstr "Community" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:23 -msgid "Contact" -msgstr "Kontakt" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:97 -msgid "Context" -msgstr "Umgebung" - -#: luci-app-snmpd/luasrc/view/snmpd.htm:54 -msgid "Domain, IP or network" -msgstr "FQDN, IP-Adresse oder CIDR-Netzmaske" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:9 -#: luci-app-snmpd/luasrc/view/snmpd.htm:24 -msgid "Enabled" -msgstr "Aktiv" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:132 -msgid "Exec" -msgstr "Ausführung" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:6 -#: luci-app-snmpd/luasrc/view/snmpd.htm:21 -#: luci-app-snmpd/luasrc/view/snmpd.htm:48 -msgid "General" -msgstr "Allgemein" - -#: luci-app-snmpd/root/usr/share/rpcd/acl.d/luci-app-snmpd.json:3 -msgid "Grant UCI access for luci-app-snmpd" -msgstr "UCI-Zugriff für luci-app-snmpd gewähren" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:63 -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:72 -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:86 -msgid "Group" -msgstr "Gruppe" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:63 -msgid "Groups help define access methods" -msgstr "Gruppen ermöglichen es, Zugriffsmethoden festzulegen" - -#: luci-app-snmpd/luasrc/view/snmpd.htm:64 -#: luci-app-snmpd/luasrc/view/snmpd.htm:114 -msgid "Interface" -msgstr "Schnittstelle" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:101 -msgid "Level" -msgstr "Ebene" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:22 -msgid "Location" -msgstr "Ort" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:24 -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:137 -msgid "Name" -msgstr "Name" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:12 -msgid "Networks" -msgstr "Netzwerke" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:116 -msgid "Notify" -msgstr "Benachrichten" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:136 -msgid "ObjectID" -msgstr "Objekt-Identifikation" - -#: luci-app-snmpd/luasrc/view/snmpd.htm:55 -#: luci-app-snmpd/luasrc/view/snmpd.htm:90 -msgid "Output interface" -msgstr "Ausgabe-Anschluss" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:138 -msgid "Program" -msgstr "Programm" - -#: luci-app-snmpd/luasrc/view/snmpd.htm:85 -#: luci-app-snmpd/luasrc/view/snmpd.htm:89 -msgid "Protocols" -msgstr "Protokolle" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:106 -msgid "Read" -msgstr "Lesen" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:34 -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:69 -msgid "Read-only" -msgstr "Nur-Lesen" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:35 -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:70 -msgid "Read-write" -msgstr "Lesen/Schreiben" - -#: luci-app-snmpd/luasrc/controller/snmpd.lua:6 -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:4 -#: luci-app-snmpd/luasrc/view/snmpd.htm:19 -#: luci-app-snmpd/root/usr/share/luci/menu.d/luci-app-snmpd.json:3 -msgid "SNMPd" -msgstr "SNMPd" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:4 -msgid "SNMPd settings interface (Beta)" -msgstr "SNMPd Einstellungen (Beta)" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:32 -msgid "Server" -msgstr "Server" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:37 -msgid "Source" -msgstr "Quelle" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:19 -msgid "System" -msgstr "System" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:111 -msgid "Write" -msgstr "Schreiben" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:92 -msgid "any" -msgstr "jede" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:104 -msgid "auth" -msgstr "Authentifizierung" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:29 -msgid "com2sec security" -msgstr "com2sec-Sicherheit" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:103 -msgid "noauth" -msgstr "noauth/offen" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:67 -msgid "secname" -msgstr "sec-Name" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:76 -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:90 -msgid "version" -msgstr "Version" diff --git a/luci-app-snmpd/po/fr/snmpd.po b/luci-app-snmpd/po/fr/snmpd.po deleted file mode 100755 index 7efb48a42..000000000 --- a/luci-app-snmpd/po/fr/snmpd.po +++ /dev/null @@ -1,184 +0,0 @@ -msgid "" -msgstr "" -"PO-Revision-Date: 2022-02-19 07:53+0000\n" -"Last-Translator: Weblate Admin \n" -"Language-Team: French \n" -"Language: fr\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 4.6.1\n" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:82 -msgid "Access" -msgstr "Accès" - -#: luci-app-snmpd/luasrc/view/snmpd.htm:81 -#: luci-app-snmpd/luasrc/view/snmpd.htm:122 -msgid "Add" -msgstr "Ajouter" - -#: luci-app-snmpd/luasrc/view/snmpd.htm:66 -#: luci-app-snmpd/luasrc/view/snmpd.htm:116 -msgid "All" -msgstr "Tout" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:139 -msgid "Arguments" -msgstr "Arguments" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:42 -msgid "Community" -msgstr "Communauté" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:23 -msgid "Contact" -msgstr "Contact" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:97 -msgid "Context" -msgstr "Contexte" - -#: luci-app-snmpd/luasrc/view/snmpd.htm:54 -msgid "Domain, IP or network" -msgstr "Domaine, IP ou réseau" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:9 -#: luci-app-snmpd/luasrc/view/snmpd.htm:24 -msgid "Enabled" -msgstr "Activer" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:132 -msgid "Exec" -msgstr "" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:6 -#: luci-app-snmpd/luasrc/view/snmpd.htm:21 -#: luci-app-snmpd/luasrc/view/snmpd.htm:48 -msgid "General" -msgstr "Général" - -#: luci-app-snmpd/root/usr/share/rpcd/acl.d/luci-app-snmpd.json:3 -msgid "Grant UCI access for luci-app-snmpd" -msgstr "Accorder l'accès UCI pour luci-app-snmpd" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:63 -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:72 -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:86 -msgid "Group" -msgstr "Groupe" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:63 -msgid "Groups help define access methods" -msgstr "Les groupes aident à définir les méthodes d'accès" - -#: luci-app-snmpd/luasrc/view/snmpd.htm:64 -#: luci-app-snmpd/luasrc/view/snmpd.htm:114 -msgid "Interface" -msgstr "Interface" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:101 -msgid "Level" -msgstr "Niveau" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:22 -msgid "Location" -msgstr "Localisation" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:24 -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:137 -msgid "Name" -msgstr "Nom" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:12 -msgid "Networks" -msgstr "Réseaux" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:116 -msgid "Notify" -msgstr "Notifier" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:136 -msgid "ObjectID" -msgstr "ObjectID" - -#: luci-app-snmpd/luasrc/view/snmpd.htm:55 -#: luci-app-snmpd/luasrc/view/snmpd.htm:90 -msgid "Output interface" -msgstr "Interface de sortie" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:138 -msgid "Program" -msgstr "Programme" - -#: luci-app-snmpd/luasrc/view/snmpd.htm:85 -#: luci-app-snmpd/luasrc/view/snmpd.htm:89 -msgid "Protocols" -msgstr "Protocoles" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:106 -msgid "Read" -msgstr "Lecture" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:34 -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:69 -msgid "Read-only" -msgstr "Lecture Seule" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:35 -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:70 -msgid "Read-write" -msgstr "Lecture-écriture" - -#: luci-app-snmpd/luasrc/controller/snmpd.lua:6 -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:4 -#: luci-app-snmpd/luasrc/view/snmpd.htm:19 -#: luci-app-snmpd/root/usr/share/luci/menu.d/luci-app-snmpd.json:3 -msgid "SNMPd" -msgstr "SNMPd" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:4 -msgid "SNMPd settings interface (Beta)" -msgstr "Paramètres du protocole SNMPd (Beta)" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:32 -msgid "Server" -msgstr "Serveur" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:37 -msgid "Source" -msgstr "Source" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:19 -msgid "System" -msgstr "Système" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:111 -msgid "Write" -msgstr "Ecriture" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:92 -msgid "any" -msgstr "Tout" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:104 -msgid "auth" -msgstr "Authentification" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:29 -msgid "com2sec security" -msgstr "com2sec security" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:103 -msgid "noauth" -msgstr "pas d'authentification" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:67 -msgid "secname" -msgstr "" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:76 -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:90 -msgid "version" -msgstr "version" diff --git a/luci-app-snmpd/po/it/snmpd.po b/luci-app-snmpd/po/it/snmpd.po deleted file mode 100755 index 5517296de..000000000 --- a/luci-app-snmpd/po/it/snmpd.po +++ /dev/null @@ -1,184 +0,0 @@ -msgid "" -msgstr "" -"PO-Revision-Date: 2022-02-21 21:14+0000\n" -"Last-Translator: Deleted User \n" -"Language-Team: Italian \n" -"Language: it\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.10.1\n" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:82 -msgid "Access" -msgstr "Accesso" - -#: luci-app-snmpd/luasrc/view/snmpd.htm:81 -#: luci-app-snmpd/luasrc/view/snmpd.htm:122 -msgid "Add" -msgstr "Aggiungi" - -#: luci-app-snmpd/luasrc/view/snmpd.htm:66 -#: luci-app-snmpd/luasrc/view/snmpd.htm:116 -msgid "All" -msgstr "Tutti" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:139 -msgid "Arguments" -msgstr "Parametri" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:42 -msgid "Community" -msgstr "Community" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:23 -msgid "Contact" -msgstr "Contatto" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:97 -msgid "Context" -msgstr "Contesto" - -#: luci-app-snmpd/luasrc/view/snmpd.htm:54 -msgid "Domain, IP or network" -msgstr "Dominio, IP o rete" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:9 -#: luci-app-snmpd/luasrc/view/snmpd.htm:24 -msgid "Enabled" -msgstr "Abilitato" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:132 -msgid "Exec" -msgstr "Esegui" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:6 -#: luci-app-snmpd/luasrc/view/snmpd.htm:21 -#: luci-app-snmpd/luasrc/view/snmpd.htm:48 -msgid "General" -msgstr "Generale" - -#: luci-app-snmpd/root/usr/share/rpcd/acl.d/luci-app-snmpd.json:3 -msgid "Grant UCI access for luci-app-snmpd" -msgstr "Concedi l'accesso UCI per luci-app-snmpd" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:63 -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:72 -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:86 -msgid "Group" -msgstr "Gruppo" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:63 -msgid "Groups help define access methods" -msgstr "I gruppi aiutano a definire i metodi di accesso" - -#: luci-app-snmpd/luasrc/view/snmpd.htm:64 -#: luci-app-snmpd/luasrc/view/snmpd.htm:114 -msgid "Interface" -msgstr "Interfaccia" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:101 -msgid "Level" -msgstr "Livello" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:22 -msgid "Location" -msgstr "Sede" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:24 -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:137 -msgid "Name" -msgstr "Nome" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:12 -msgid "Networks" -msgstr "Reti" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:116 -msgid "Notify" -msgstr "Notificare" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:136 -msgid "ObjectID" -msgstr "" - -#: luci-app-snmpd/luasrc/view/snmpd.htm:55 -#: luci-app-snmpd/luasrc/view/snmpd.htm:90 -msgid "Output interface" -msgstr "Interfaccia di output" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:138 -msgid "Program" -msgstr "Programma" - -#: luci-app-snmpd/luasrc/view/snmpd.htm:85 -#: luci-app-snmpd/luasrc/view/snmpd.htm:89 -msgid "Protocols" -msgstr "Protocollo" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:106 -msgid "Read" -msgstr "Leggi" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:34 -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:69 -msgid "Read-only" -msgstr "Sola lettura" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:35 -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:70 -msgid "Read-write" -msgstr "Leggi-Scrivi" - -#: luci-app-snmpd/luasrc/controller/snmpd.lua:6 -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:4 -#: luci-app-snmpd/luasrc/view/snmpd.htm:19 -#: luci-app-snmpd/root/usr/share/luci/menu.d/luci-app-snmpd.json:3 -msgid "SNMPd" -msgstr "" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:4 -msgid "SNMPd settings interface (Beta)" -msgstr "Interfaccia delle impostazioni SNMPd (Beta)" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:32 -msgid "Server" -msgstr "" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:37 -msgid "Source" -msgstr "" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:19 -msgid "System" -msgstr "Sistema" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:111 -msgid "Write" -msgstr "Scrittura" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:92 -msgid "any" -msgstr "qualsiasi" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:104 -msgid "auth" -msgstr "" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:29 -msgid "com2sec security" -msgstr "" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:103 -msgid "noauth" -msgstr "" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:67 -msgid "secname" -msgstr "" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:76 -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:90 -msgid "version" -msgstr "versione" diff --git a/luci-app-snmpd/po/oc/snmpd.po b/luci-app-snmpd/po/oc/snmpd.po deleted file mode 100755 index 10292f065..000000000 --- a/luci-app-snmpd/po/oc/snmpd.po +++ /dev/null @@ -1,184 +0,0 @@ -msgid "" -msgstr "" -"PO-Revision-Date: 2020-08-31 17:15+0000\n" -"Last-Translator: Quentin PAGÈS \n" -"Language-Team: Occitan \n" -"Language: oc\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 4.0.4\n" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:82 -msgid "Access" -msgstr "Accès" - -#: luci-app-snmpd/luasrc/view/snmpd.htm:81 -#: luci-app-snmpd/luasrc/view/snmpd.htm:122 -msgid "Add" -msgstr "Ajustar" - -#: luci-app-snmpd/luasrc/view/snmpd.htm:66 -#: luci-app-snmpd/luasrc/view/snmpd.htm:116 -msgid "All" -msgstr "Tot" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:139 -msgid "Arguments" -msgstr "Arguments" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:42 -msgid "Community" -msgstr "Comunautat" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:23 -msgid "Contact" -msgstr "Contacte" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:97 -msgid "Context" -msgstr "Contèxt" - -#: luci-app-snmpd/luasrc/view/snmpd.htm:54 -msgid "Domain, IP or network" -msgstr "Domeni, IP o ret" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:9 -#: luci-app-snmpd/luasrc/view/snmpd.htm:24 -msgid "Enabled" -msgstr "Activat" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:132 -msgid "Exec" -msgstr "Exec" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:6 -#: luci-app-snmpd/luasrc/view/snmpd.htm:21 -#: luci-app-snmpd/luasrc/view/snmpd.htm:48 -msgid "General" -msgstr "General" - -#: luci-app-snmpd/root/usr/share/rpcd/acl.d/luci-app-snmpd.json:3 -msgid "Grant UCI access for luci-app-snmpd" -msgstr "Acordar l'accès UCI a luci-app-snmpd" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:63 -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:72 -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:86 -msgid "Group" -msgstr "Grop" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:63 -msgid "Groups help define access methods" -msgstr "Los grops ajudan a gerir los metòdes d'accès" - -#: luci-app-snmpd/luasrc/view/snmpd.htm:64 -#: luci-app-snmpd/luasrc/view/snmpd.htm:114 -msgid "Interface" -msgstr "Interfàcia" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:101 -msgid "Level" -msgstr "Nivèl" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:22 -msgid "Location" -msgstr "Emplaçament" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:24 -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:137 -msgid "Name" -msgstr "Nom" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:12 -msgid "Networks" -msgstr "Rets" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:116 -msgid "Notify" -msgstr "Notificar" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:136 -msgid "ObjectID" -msgstr "ObjectID" - -#: luci-app-snmpd/luasrc/view/snmpd.htm:55 -#: luci-app-snmpd/luasrc/view/snmpd.htm:90 -msgid "Output interface" -msgstr "Interfàcia de sortida" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:138 -msgid "Program" -msgstr "Programa" - -#: luci-app-snmpd/luasrc/view/snmpd.htm:85 -#: luci-app-snmpd/luasrc/view/snmpd.htm:89 -msgid "Protocols" -msgstr "Protocòls" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:106 -msgid "Read" -msgstr "Lectura" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:34 -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:69 -msgid "Read-only" -msgstr "Lectura sola" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:35 -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:70 -msgid "Read-write" -msgstr "Lectura-escritura" - -#: luci-app-snmpd/luasrc/controller/snmpd.lua:6 -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:4 -#: luci-app-snmpd/luasrc/view/snmpd.htm:19 -#: luci-app-snmpd/root/usr/share/luci/menu.d/luci-app-snmpd.json:3 -msgid "SNMPd" -msgstr "SNMPd" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:4 -msgid "SNMPd settings interface (Beta)" -msgstr "Interfàcia de paramètres SNMPd (Beta)" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:32 -msgid "Server" -msgstr "Servidor" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:37 -msgid "Source" -msgstr "Font" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:19 -msgid "System" -msgstr "Sistèma" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:111 -msgid "Write" -msgstr "Escritura" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:92 -msgid "any" -msgstr "Quin que siá" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:104 -msgid "auth" -msgstr "auth" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:29 -msgid "com2sec security" -msgstr "seguretat com2sec" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:103 -msgid "noauth" -msgstr "noauth" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:67 -msgid "secname" -msgstr "secname" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:76 -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:90 -msgid "version" -msgstr "version" diff --git a/luci-app-snmpd/po/templates/snmpd.pot b/luci-app-snmpd/po/templates/snmpd.pot old mode 100755 new mode 100644 index 9acfaf5cb..5eb995f6b --- a/luci-app-snmpd/po/templates/snmpd.pot +++ b/luci-app-snmpd/po/templates/snmpd.pot @@ -1,175 +1,69 @@ msgid "" msgstr "Content-Type: text/plain; charset=UTF-8" -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:82 -msgid "Access" +#: applications/luci-app-snmpd/htdocs/luci-static/resources/view/snmpd/snmpd.js:22 +msgid "Agent settings" msgstr "" -#: luci-app-snmpd/luasrc/view/snmpd.htm:81 -#: luci-app-snmpd/luasrc/view/snmpd.htm:122 -msgid "Add" +#: applications/luci-app-snmpd/htdocs/luci-static/resources/view/snmpd/snmpd.js:27 +msgid "AgentX settings" msgstr "" -#: luci-app-snmpd/luasrc/view/snmpd.htm:66 -#: luci-app-snmpd/luasrc/view/snmpd.htm:116 -msgid "All" +#: applications/luci-app-snmpd/htdocs/luci-static/resources/view/snmpd/snmpd.js:28 +msgid "Delete this section to disable AgentX" msgstr "" -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:139 -msgid "Arguments" +#: applications/luci-app-snmpd/htdocs/luci-static/resources/view/snmpd/snmpd.js:25 +msgid "Eg: UDP:161, or UDP:10.5.4.3:161 to only listen on a given interface" msgstr "" -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:42 -msgid "Community" -msgstr "" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:23 -msgid "Contact" -msgstr "" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:97 -msgid "Context" -msgstr "" - -#: luci-app-snmpd/luasrc/view/snmpd.htm:54 -msgid "Domain, IP or network" -msgstr "" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:9 -#: luci-app-snmpd/luasrc/view/snmpd.htm:24 -msgid "Enabled" -msgstr "" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:132 -msgid "Exec" -msgstr "" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:6 -#: luci-app-snmpd/luasrc/view/snmpd.htm:21 -#: luci-app-snmpd/luasrc/view/snmpd.htm:48 -msgid "General" -msgstr "" - -#: luci-app-snmpd/root/usr/share/rpcd/acl.d/luci-app-snmpd.json:3 +#: applications/luci-app-snmpd/root/usr/share/rpcd/acl.d/luci-app-snmpd.json:3 msgid "Grant UCI access for luci-app-snmpd" msgstr "" -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:63 -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:72 -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:86 -msgid "Group" -msgstr "" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:63 +#: applications/luci-app-snmpd/htdocs/luci-static/resources/view/snmpd/snmpd.js:40 msgid "Groups help define access methods" msgstr "" -#: luci-app-snmpd/luasrc/view/snmpd.htm:64 -#: luci-app-snmpd/luasrc/view/snmpd.htm:114 -msgid "Interface" +#: applications/luci-app-snmpd/root/usr/share/luci/menu.d/luci-app-snmpd.json:3 +msgid "SNMPD" msgstr "" -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:101 -msgid "Level" +#: applications/luci-app-snmpd/htdocs/luci-static/resources/view/snmpd/snmpd.js:8 +msgid "" +"SNMPD is a master daemon/agent for SNMP, from the net-snmp project. Note, OpenWrt has mostly complete UCI " +"support for snmpd, but this LuCI applet only covers a few of those options. " +"In particular, there is very little/no validation or help. See /etc/config/" +"snmpd for manual configuration." msgstr "" -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:22 -msgid "Location" -msgstr "" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:24 -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:137 -msgid "Name" -msgstr "" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:12 -msgid "Networks" -msgstr "" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:116 -msgid "Notify" -msgstr "" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:136 -msgid "ObjectID" -msgstr "" - -#: luci-app-snmpd/luasrc/view/snmpd.htm:55 -#: luci-app-snmpd/luasrc/view/snmpd.htm:90 -msgid "Output interface" -msgstr "" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:138 -msgid "Program" -msgstr "" - -#: luci-app-snmpd/luasrc/view/snmpd.htm:85 -#: luci-app-snmpd/luasrc/view/snmpd.htm:89 -msgid "Protocols" -msgstr "" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:106 -msgid "Read" -msgstr "" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:34 -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:69 -msgid "Read-only" -msgstr "" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:35 -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:70 -msgid "Read-write" -msgstr "" - -#: luci-app-snmpd/luasrc/controller/snmpd.lua:6 -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:4 -#: luci-app-snmpd/luasrc/view/snmpd.htm:19 -#: luci-app-snmpd/root/usr/share/luci/menu.d/luci-app-snmpd.json:3 -msgid "SNMPd" -msgstr "" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:4 -msgid "SNMPd settings interface (Beta)" -msgstr "" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:32 -msgid "Server" -msgstr "" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:37 -msgid "Source" -msgstr "" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:19 +#: applications/luci-app-snmpd/htdocs/luci-static/resources/view/snmpd/snmpd.js:56 msgid "System" msgstr "" -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:111 -msgid "Write" +#: applications/luci-app-snmpd/htdocs/luci-static/resources/view/snmpd/snmpd.js:30 +msgid "The address the agent should allow AgentX connections to" msgstr "" -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:92 -msgid "any" +#: applications/luci-app-snmpd/htdocs/luci-static/resources/view/snmpd/snmpd.js:24 +msgid "The address the agent should listen on" msgstr "" -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:104 -msgid "auth" +#: applications/luci-app-snmpd/htdocs/luci-static/resources/view/snmpd/snmpd.js:31 +msgid "" +"This is only necessary if you have subagents using the agentX socket " +"protocol. Eg: /var/run/agentx.sock" msgstr "" -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:29 +#: applications/luci-app-snmpd/htdocs/luci-static/resources/view/snmpd/snmpd.js:56 +msgid "Values used in the MIB2 System tree" +msgstr "" + +#: applications/luci-app-snmpd/htdocs/luci-static/resources/view/snmpd/snmpd.js:35 msgid "com2sec security" msgstr "" -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:103 -msgid "noauth" -msgstr "" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:67 -msgid "secname" -msgstr "" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:76 -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:90 -msgid "version" +#: applications/luci-app-snmpd/htdocs/luci-static/resources/view/snmpd/snmpd.js:20 +msgid "net-snmp's SNMPD" msgstr "" diff --git a/luci-app-snmpd/po/zh_Hans/snmpd.po b/luci-app-snmpd/po/zh_Hans/snmpd.po deleted file mode 100755 index 43c9d8f1d..000000000 --- a/luci-app-snmpd/po/zh_Hans/snmpd.po +++ /dev/null @@ -1,184 +0,0 @@ -msgid "" -msgstr "" -"PO-Revision-Date: 2021-05-05 11:40+0000\n" -"Last-Translator: niergouge <1150108426@qq.com>\n" -"Language-Team: Chinese (Simplified) \n" -"Language: zh_Hans\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 4.6.1\n" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:82 -msgid "Access" -msgstr "访问" - -#: luci-app-snmpd/luasrc/view/snmpd.htm:81 -#: luci-app-snmpd/luasrc/view/snmpd.htm:122 -msgid "Add" -msgstr "添加" - -#: luci-app-snmpd/luasrc/view/snmpd.htm:66 -#: luci-app-snmpd/luasrc/view/snmpd.htm:116 -msgid "All" -msgstr "所有" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:139 -msgid "Arguments" -msgstr "理由" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:42 -msgid "Community" -msgstr "公共" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:23 -msgid "Contact" -msgstr "联系" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:97 -msgid "Context" -msgstr "语境" - -#: luci-app-snmpd/luasrc/view/snmpd.htm:54 -msgid "Domain, IP or network" -msgstr "域,IP或网络" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:9 -#: luci-app-snmpd/luasrc/view/snmpd.htm:24 -msgid "Enabled" -msgstr "启用" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:132 -msgid "Exec" -msgstr "执行" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:6 -#: luci-app-snmpd/luasrc/view/snmpd.htm:21 -#: luci-app-snmpd/luasrc/view/snmpd.htm:48 -msgid "General" -msgstr "通用" - -#: luci-app-snmpd/root/usr/share/rpcd/acl.d/luci-app-snmpd.json:3 -msgid "Grant UCI access for luci-app-snmpd" -msgstr "授予UCI访问luci-app-snmpd的权限" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:63 -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:72 -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:86 -msgid "Group" -msgstr "组" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:63 -msgid "Groups help define access methods" -msgstr "定义访问组帮助方法" - -#: luci-app-snmpd/luasrc/view/snmpd.htm:64 -#: luci-app-snmpd/luasrc/view/snmpd.htm:114 -msgid "Interface" -msgstr "接口" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:101 -msgid "Level" -msgstr "级别" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:22 -msgid "Location" -msgstr "位置" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:24 -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:137 -msgid "Name" -msgstr "名称" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:12 -msgid "Networks" -msgstr "网络" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:116 -msgid "Notify" -msgstr "通知" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:136 -msgid "ObjectID" -msgstr "对象ID" - -#: luci-app-snmpd/luasrc/view/snmpd.htm:55 -#: luci-app-snmpd/luasrc/view/snmpd.htm:90 -msgid "Output interface" -msgstr "输出接口" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:138 -msgid "Program" -msgstr "程序" - -#: luci-app-snmpd/luasrc/view/snmpd.htm:85 -#: luci-app-snmpd/luasrc/view/snmpd.htm:89 -msgid "Protocols" -msgstr "协议" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:106 -msgid "Read" -msgstr "读取" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:34 -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:69 -msgid "Read-only" -msgstr "只读" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:35 -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:70 -msgid "Read-write" -msgstr "读写" - -#: luci-app-snmpd/luasrc/controller/snmpd.lua:6 -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:4 -#: luci-app-snmpd/luasrc/view/snmpd.htm:19 -#: luci-app-snmpd/root/usr/share/luci/menu.d/luci-app-snmpd.json:3 -msgid "SNMPd" -msgstr "SNMPd设置" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:4 -msgid "SNMPd settings interface (Beta)" -msgstr "SNMPd设置界面(测试版)" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:32 -msgid "Server" -msgstr "服务器" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:37 -msgid "Source" -msgstr "源" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:19 -msgid "System" -msgstr "系统" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:111 -msgid "Write" -msgstr "写" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:92 -msgid "any" -msgstr "任何" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:104 -msgid "auth" -msgstr "认证" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:29 -msgid "com2sec security" -msgstr "com2sec安全" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:103 -msgid "noauth" -msgstr "无认证" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:67 -msgid "secname" -msgstr "第二名称" - -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:76 -#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:90 -msgid "version" -msgstr "版本" diff --git a/luci-app-snmpd/root/etc/config/snmpd b/luci-app-snmpd/root/etc/config/snmpd deleted file mode 100755 index 09a89474f..000000000 --- a/luci-app-snmpd/root/etc/config/snmpd +++ /dev/null @@ -1,91 +0,0 @@ - -config agent - option agentaddress 'UDP:161,UDP6:161' - -config agentx - option agentxsocket '/var/run/agentx.sock' - -config com2sec 'public' - option secname 'ro' - option source 'default' - option community 'public' - -config com2sec 'private' - option secname 'rw' - option source 'localhost' - option community 'private' - -config group 'public_v1' - option group 'public' - option version 'v1' - option secname 'ro' - -config group 'public_v2c' - option group 'public' - option version 'v2c' - option secname 'ro' - -config group 'public_usm' - option group 'public' - option version 'usm' - option secname 'ro' - -config group 'private_v1' - option group 'private' - option version 'v1' - option secname 'rw' - -config group 'private_v2c' - option group 'private' - option version 'v2c' - option secname 'rw' - -config group 'private_usm' - option group 'private' - option version 'usm' - option secname 'rw' - -config view 'all' - option viewname 'all' - option type 'included' - option oid '.1' - -config access 'public_access' - option group 'public' - option context 'none' - option version 'any' - option level 'noauth' - option prefix 'exact' - option read 'all' - option write 'none' - option notify 'none' - -config access 'private_access' - option group 'private' - option context 'none' - option version 'any' - option level 'noauth' - option prefix 'exact' - option read 'all' - option write 'all' - option notify 'all' - -config system - option sysLocation 'office' - option sysContact 'bofh@example.com' - option sysName 'OpenMPTCProuter' - -config exec - option name 'filedescriptors' - option prog '/bin/cat' - option args '/proc/sys/fs/file-nr' - -config engineid - option engineidtype '3' - option engineidnic 'eth0' - -config snmpd 'general' - list network 'lan' - option enabled '0' - option ipv6cpipv4 '1' - diff --git a/luci-app-snmpd/root/etc/init.d/snmpd b/luci-app-snmpd/root/etc/init.d/snmpd deleted file mode 100755 index 39fc71445..000000000 --- a/luci-app-snmpd/root/etc/init.d/snmpd +++ /dev/null @@ -1,349 +0,0 @@ -#!/bin/sh /etc/rc.common -# Copyright (C) 2008 OpenWrt.org -START=50 - -USE_PROCD=1 -PROG="/usr/sbin/snmpd" - -CONFIGFILE="/var/run/snmpd.conf" - -snmpd_agent_add() { - local cfg="$1" - - config_get agentaddress "$cfg" agentaddress - [ -n "$agentaddress" ] || return 0 - echo "agentaddress $agentaddress" >> $CONFIGFILE -} - -snmpd_agentx_add() { - local cfg="$1" - echo "master agentx" >> $CONFIGFILE - config_get agentxsocket "$cfg" agentxsocket - [ -n "$agentxsocket" ] && echo "agentXSocket $agentxsocket" >> $CONFIGFILE -} - -snmpd_system_add() { - local cfg="$1" - config_get syslocation "$cfg" sysLocation - [ -n "$syslocation" ] && echo "sysLocation $syslocation" >> $CONFIGFILE - config_get syscontact "$cfg" sysContact - [ -n "$syscontact" ] && echo "sysContact $syscontact" >> $CONFIGFILE - config_get sysname "$cfg" sysName - [ -n "$sysname" ] && echo "sysName $sysname" >> $CONFIGFILE - config_get sysservice "$cfg" sysService - [ -n "$sysservice" ] && echo "sysService $sysservice" >> $CONFIGFILE - config_get sysdescr "$cfg" sysDescr - [ -n "$sysdescr" ] && echo "sysDescr $sysdescr" >> $CONFIGFILE - config_get sysobjectid "$cfg" sysObjectID - [ -n "$sysobjectid" ] && echo "sysObjectID $sysobjectid" >> $CONFIGFILE -} - -snmpd_com2sec_add() { - local cfg="$1" - config_get secname "$cfg" secname - [ -n "$secname" ] || return 0 - config_get source "$cfg" source - [ -n "$source" ] || return 0 - config_get community "$cfg" community - [ -n "$community" ] || return 0 - echo "com2sec $secname $source $community" >> $CONFIGFILE -} - -snmpd_com2sec6_add() { - local cfg="$1" - config_get secname "$cfg" secname - [ -n "$secname" ] || return 0 - config_get source "$cfg" source - [ -n "$source" ] || return 0 - config_get community "$cfg" community - [ -n "$community" ] || return 0 - echo "com2sec6 $secname $source $community" >> $CONFIGFILE -} - -snmpd_group_add() { - local cfg="$1" - config_get group "$cfg" group - [ -n "$group" ] || return 0 - config_get version "$cfg" version - [ -n "$version" ] || return 0 - config_get secname "$cfg" secname - [ -n "$secname" ] || return 0 - echo "group $group $version $secname" >> $CONFIGFILE -} - -snmpd_view_add() { - local cfg="$1" - config_get viewname "$cfg" viewname - [ -n "$viewname" ] || return 0 - config_get type "$cfg" type - [ -n "$type" ] || return 0 - config_get oid "$cfg" oid - [ -n "$oid" ] || return 0 - # optional mask - config_get mask "$cfg" mask - echo "view $viewname $type $oid $mask" >> $CONFIGFILE -} - -snmpd_access_add() { - local cfg="$1" - config_get group "$cfg" group - [ -n "$group" ] || return 0 - config_get context "$cfg" context - [ -n $context ] || return 0 - [ "$context" == "none" ] && context='""' - config_get version "$cfg" version - [ -n "$version" ] || return 0 - config_get level "$cfg" level - [ -n "$level" ] || return 0 - config_get prefix "$cfg" prefix - [ -n "$prefix" ] || return 0 - config_get read "$cfg" read - [ -n "$read" ] || return 0 - config_get write "$cfg" write - [ -n "$write" ] || return 0 - config_get notify "$cfg" notify - [ -n "$notify" ] || return 0 - echo "access $group $context $version $level $prefix $read $write $notify" >> $CONFIGFILE -} - -snmpd_trap_hostname_add() { - local cfg="$1" - config_get hostname "$cfg" HostName - config_get port "$cfg" Port - config_get community "$cfg" Community - config_get type "$cfg" Type - echo "$type $hostname $community $port" >> $CONFIGFILE -} - -snmpd_trap_ip_add() { - local cfg="$1" - config_get host_ip "$cfg" HostIP - config_get port "$cfg" Port - config_get community "$cfg" Community - config_get type "$cfg" Type - echo "$type $host_ip $community $port" >> $CONFIGFILE -} - -snmpd_access_default_add() { - local cfg="$1" - config_get mode "$cfg" Mode - config_get community "$cfg" CommunityName - config_get oidrestrict "$cfg" RestrictOID - config_get oid "$cfg" RestrictedOID - echo -n "$mode $community default" >> $CONFIGFILE - [ "$oidrestrict" == "yes" ] && echo " $oid" >> $CONFIGFILE - [ "$oidrestrict" == "no" ] && echo "" >> $CONFIGFILE -} - -snmpd_access_HostName_add() { - local cfg="$1" - config_get hostname "$cfg" HostName - config_get mode "$cfg" Mode - config_get community "$cfg" CommunityName - config_get oidrestrict "$cfg" RestrictOID - config_get oid "$cfg" RestrictedOID - echo -n "$mode $community $hostname" >> $CONFIGFILE - [ "$oidrestrict" == "yes" ] && echo " $oid" >> $CONFIGFILE - [ "$oidrestrict" == "no" ] && echo "" >> $CONFIGFILE -} - -snmpd_access_HostIP_add() { - local cfg="$1" - config_get host_ip "$cfg" HostIP - config_get ip_mask "$cfg" IPMask - config_get mode "$cfg" Mode - config_get community "$cfg" CommunityName - config_get oidrestrict "$cfg" RestrictOID - config_get oid "$cfg" RestrictedOID - echo -n "$mode $community $host_ip/$ip_mask" >> $CONFIGFILE - [ "$oidrestrict" == "yes" ] && echo " $oid" >> $CONFIGFILE - [ "$oidrestrict" == "no" ] && echo "" >> $CONFIGFILE -} - -snmpd_pass_add() { - local cfg="$1" - local pass='pass' - - config_get miboid "$cfg" miboid - [ -n "$miboid" ] || return 0 - config_get prog "$cfg" prog - [ -n "$prog" ] || return 0 - config_get_bool persist "$cfg" persist 0 - [ $persist -ne 0 ] && pass='pass_persist' - config_get priority "$cfg" priority - priority=${priority:+-p $priority} - echo "$pass $priority $miboid $prog" >> $CONFIGFILE -} - -snmpd_exec_add() { - local cfg="$1" - - config_get name "$cfg" name - [ -n "$name" ] || return 0 - config_get prog "$cfg" prog - [ -n "$prog" ] || return 0 - config_get args "$cfg" args - config_get miboid "$cfg" miboid - echo "exec $miboid $name $prog $args" >> $CONFIGFILE -} - -snmpd_disk_add() { - local cfg="$1" - local disk='disk' - - config_get partition "$cfg" partition - [ -n "$partition" ] || return 0 - config_get size "$cfg" size - [ -n "$size" ] || return 0 - echo "$disk $partition $size" >> $CONFIGFILE -} - -snmpd_engineid_add() { - local cfg="$1" - - config_get engineid "$cfg" engineid - [ -n "$engineid" ] && echo "engineID $engineid" >> $CONFIGFILE - config_get engineidtype "$cfg" engineidtype - [ "$engineidtype" -ge 1 -a "$engineidtype" -le 3 ] && \ - echo "engineIDType $engineidtype" >> $CONFIGFILE - config_get engineidnic "$cfg" engineidnic - [ -n "$engineidnic" ] && echo "engineIDNic $engineidnic" >> $CONFIGFILE -} - -snmpd_sink_add() { - local cfg="$1" - local section="$2" - local community - local port - local host - - config_get host "$cfg" host - [ -n "section" -a -n "$host" ] || return 0 - # optional community - config_get community "$cfg" community - # optional port - config_get port "$cfg" port - port=${port:+:$port} - echo "$section $host$port $community" >> $CONFIGFILE -} - -append_parm() { - local section="$1" - local option="$2" - local switch="$3" - local _loctmp - config_get _loctmp "$section" "$option" - [ -z "$_loctmp" ] && return 0 - echo "$switch $_loctmp" >> $CONFIGFILE -} - -append_authtrapenable() { - local section="$1" - local option="$2" - local switch="$3" - local _loctmp - config_get_bool _loctmp "$section" "$option" - [ -z "$_loctmp" ] && return 0 - [ "$_loctmp" -gt 0 ] && echo "$switch $_loctmp" >> $CONFIGFILE -} - -snmpd_setup_fw_rules() { - local net="$1" - local zone - - zone=$(fw3 -q network "$net" 2>/dev/null) - - local handled_zone - for handled_zone in $HANDLED_SNMP_ZONES; do - [ "$handled_zone" = "$zone" ] && return - done - - json_add_object "" - json_add_string type rule - json_add_string src "$zone" - json_add_string proto udp - json_add_string dest_port 161 - json_add_string target ACCEPT - json_close_object - - HANDLED_SNMP_ZONES="$HANDLED_SNMP_ZONES $zone" -} - -start_service() { - [ -f "$CONFIGFILE" ] && rm -f "$CONFIGFILE" - - config_load snmpd - - config_get_bool snmp_enabled general enabled 1 - [ "$snmp_enabled" -eq 0 ] && return - - procd_open_instance - - config_foreach snmpd_agent_add agent - config_foreach snmpd_agentx_add agentx - config_foreach snmpd_system_add system - config_foreach snmpd_com2sec_add com2sec - if [ "$(uci -q get snmpd.general.ipv6cpipv4)" = "1" ]; then - config_foreach snmpd_com2sec6_add com2sec - else - config_foreach snmpd_com2sec6_add com2sec6 - fi - config_foreach snmpd_group_add group - config_foreach snmpd_view_add view - config_foreach snmpd_access_add access - config_foreach snmpd_trap_hostname_add trap_HostName - config_foreach snmpd_trap_ip_add trap_HostIP - config_foreach snmpd_access_default_add access_default - config_foreach snmpd_access_HostName_add access_HostName - config_foreach snmpd_access_HostIP_add access_HostIP - config_foreach snmpd_pass_add pass - config_foreach snmpd_exec_add exec - config_foreach snmpd_disk_add disk - config_foreach snmpd_engineid_add engineid - append_parm trapcommunity community trapcommunity - config_foreach snmpd_sink_add trapsink trapsink - config_foreach snmpd_sink_add trap2sink trap2sink - config_foreach snmpd_sink_add informsink informsink - append_authtrapenable authtrapenable enable authtrapenable - append_parm v1trapaddress host v1trapaddress - append_parm trapsess trapsess trapsess - - procd_set_param command $PROG -Lf /dev/null -f - procd_set_param file $CONFIGFILE - procd_set_param respawn - - for iface in $(ls /sys/class/net 2>/dev/null); do - procd_append_param netdev "$iface" - done - - procd_open_data - - json_add_array firewall - config_list_foreach general network snmpd_setup_fw_rules - json_close_array - - procd_close_data - - procd_close_instance -} - -stop_service() { - [ -f "$CONFIGFILE" ] && rm -f "$CONFIGFILE" - procd_set_config_changed firewall -} - -service_triggers(){ - local script=$(readlink "$initscript") - local name=$(basename ${script:-$initscript}) - - procd_open_trigger - procd_add_raw_trigger "interface.*" 2000 /etc/init.d/$name reload - procd_close_trigger - - procd_add_reload_trigger 'snmpd' -} - -service_started() { - [ "$snmp_enabled" -eq 0 ] && return - procd_set_config_changed firewall -} diff --git a/luci-app-snmpd/root/etc/uci-defaults/4400-snmpd b/luci-app-snmpd/root/etc/uci-defaults/4400-snmpd deleted file mode 100755 index 8c6f6a547..000000000 --- a/luci-app-snmpd/root/etc/uci-defaults/4400-snmpd +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh -if [ "$(uci -q get snmpd.general.network)" = "" ]; then - uci -q batch <<-EOF >/dev/null - add_list snmpd.general.network=lan - set snmpd.@system[0].sysName="OpenMPTCProuter" - set snmpd.general.enabled=0 - commit snmpd - EOF -fi - -uci -q batch <<-EOF >/dev/null - delete ucitrack.@snmpd[-1] - add ucitrack snmpd - set ucitrack.@snmpd[-1].init=snmpd - commit ucitrack -EOF - -rm -f /tmp/luci-indexcache -exit 0 \ No newline at end of file diff --git a/luci-app-snmpd/root/usr/share/luci/menu.d/luci-app-snmpd.json b/luci-app-snmpd/root/usr/share/luci/menu.d/luci-app-snmpd.json old mode 100755 new mode 100644 index 771c4021a..85850a218 --- a/luci-app-snmpd/root/usr/share/luci/menu.d/luci-app-snmpd.json +++ b/luci-app-snmpd/root/usr/share/luci/menu.d/luci-app-snmpd.json @@ -1,13 +1,13 @@ { - "admin/network/snmpd": { - "title": "SNMPd", - "order": 91, + "admin/services/snmpd": { + "title": "SNMPD", "action": { - "type": "cbi", - "path": "snmpd" + "type": "view", + "path": "snmpd/snmpd" }, "depends": { - "acl": [ "luci-app-snmpd" ] + "acl": [ "luci-app-snmpd" ], + "uci": { "snmpd": true } } } } diff --git a/luci-app-snmpd/root/usr/share/rpcd/acl.d/luci-app-snmpd.json b/luci-app-snmpd/root/usr/share/rpcd/acl.d/luci-app-snmpd.json old mode 100755 new mode 100644 index 1fc168524..566e52139 --- a/luci-app-snmpd/root/usr/share/rpcd/acl.d/luci-app-snmpd.json +++ b/luci-app-snmpd/root/usr/share/rpcd/acl.d/luci-app-snmpd.json @@ -1,11 +1,11 @@ { - "luci-app-snmpd": { - "description": "Grant UCI access for luci-app-snmpd", - "read": { - "uci": [ "snmpd" ] - }, - "write": { - "uci": [ "snmpd" ] + "luci-app-snmpd": { + "description": "Grant UCI access for luci-app-snmpd", + "read": { + "uci": [ "snmpd" ] + }, + "write": { + "uci": [ "snmpd" ] + } } - } -} \ No newline at end of file +} diff --git a/luci-mod-dashboard/Makefile b/luci-mod-dashboard/Makefile old mode 100755 new mode 100644 index 6a6d84166..4a9aec96f --- a/luci-mod-dashboard/Makefile +++ b/luci-mod-dashboard/Makefile @@ -1,11 +1,8 @@ # # Copyright 2019-2020 ZHANG Zhao -# Copyright 2020 Ycarus (Yannick Chabanois) for OpenMPTCProuter # # This is free software, licensed under the Apache License, Version 2.0 . # -# Based on openwrt luci commit 03c77dafe3cfb922b995adfe9c0f8a75c98a18af -# include $(TOPDIR)/rules.mk diff --git a/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/css/custom.css b/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/css/custom.css old mode 100755 new mode 100644 index f20713832..66dd81f79 --- a/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/css/custom.css +++ b/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/css/custom.css @@ -8,7 +8,6 @@ .Dashboard h3 { color:#000; - background: transparent; } .Dashboard hr { @@ -21,7 +20,7 @@ } .Dashboard .box-s1 { - min-height: 550px; + min-height: 466px; } .Dashboard .internet-status-self .internet-status-info .title { @@ -33,13 +32,6 @@ background-color: #e0e0e0; } -.Dashboard div > table > tbody > tr:nth-of-type(2n), div > .table > .tr:nth-of-type(2n) { - background-color: transparent; -} -.Dashboard .tr { - background-color: transparent; -} - .Dashboard .title { text-align: center; } @@ -109,11 +101,11 @@ } .Dashboard .internet-status-self .settings-info p:first-child span:first-child{ - font-size: 12px; + font-size: 15px; font-weight: 500; } -//.Dashboard .internet-status-self .settings-info p:first-child span:first-child, +.Dashboard .internet-status-self .settings-info p:nth-child(2) span:first-child, .Dashboard .router-status-wifi .wifi-info .settings-info p:first-child span:first-child, .Dashboard .router-status-wifi .wifi-info .settings-info p:nth-child(2) span:first-child{ font-weight: 700; @@ -128,10 +120,11 @@ .Dashboard .settings-info p span:nth-child(2){ display: inline-block; word-break: break-all; - overflow: hidden; - max-height: 16px; - position: relative; - top:2px; +} + +.Dashboard .settings-info p span:nth-child(2).label { + padding: 1px 4px 1px 4px; + font-size: 9.75px; } .Dashboard .router-status-info .settings-info p span:nth-child(2){ @@ -199,14 +192,6 @@ border-bottom:1px solid rgba(0,0,0,.1); } -.Dashboard .label-success { - background-color: green; -} - -.Dashboard .label-danger { - background-color: red; -} - /** * Responsive **/ diff --git a/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/icons/devices.svg b/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/icons/devices.svg old mode 100755 new mode 100644 diff --git a/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/icons/internet.svg b/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/icons/internet.svg old mode 100755 new mode 100644 diff --git a/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/icons/not-internet.svg b/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/icons/not-internet.svg old mode 100755 new mode 100644 diff --git a/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/icons/router.svg b/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/icons/router.svg old mode 100755 new mode 100644 diff --git a/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/icons/wireless.svg b/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/icons/wireless.svg old mode 100755 new mode 100644 diff --git a/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js b/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js old mode 100755 new mode 100644 index cf69d4d0e..c43e2ca54 --- a/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js +++ b/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js @@ -14,24 +14,16 @@ var callSystemInfo = rpc.declare({ method: 'info' }); -var callOpenMPTCProuterInfo = rpc.declare({ - object: 'openmptcprouter', - method: 'status' -}); - - return baseclass.extend({ params: [], - formatBytes: function(a,b=2){if(0===a)return"0 Bytes";const c=0>b?0:b,d=Math.floor(Math.log(a)/Math.log(1024));return parseFloat((a/Math.pow(1024,d)).toFixed(c))+" "+["Bytes","KiB","MiB","GiB","TiB","PiB","EiB","ZiB","YiB"][d]}, load: function() { return Promise.all([ network.getWANNetworks(), network.getWAN6Networks(), L.resolveDefault(callSystemBoard(), {}), - L.resolveDefault(callSystemInfo(), {}), - L.resolveDefault(callOpenMPTCProuterInfo(), {}) + L.resolveDefault(callSystemInfo(), {}) ]); }, @@ -44,7 +36,7 @@ return baseclass.extend({ var container_item = E('div', { 'class': 'settings-info'}); if ('internet' == type) { - icon = (data.internet.v4.connected.value || data.internet.v6.connected.value) ? type : 'not-internet'; + icon = (data.v4.connected.value || data.v6.connected.value) ? type : 'not-internet'; } container_box.appendChild(E('div', { 'class': 'title'}, [ @@ -60,45 +52,19 @@ return baseclass.extend({ container_box.appendChild(E('hr')); if ('internet' == type) { - var container_internet_v4 = E('div'); var container_internet_v6 = E('div'); - var container_internet_vps = E('div'); - for(var idx in data['vps']) { - var classname = ver, - suppelements = '', - visible = data['vps'][idx].visible; - if ('title' === idx) { - container_internet_vps.appendChild( - E('p', { 'class': 'mt-2'}, [ - E('h4', {'class': ''}, [ data['vps'].title ]), - ]) - ); - continue; - } - if (visible) { - container_internet_vps.appendChild( - E('p', { 'class': 'mt-2'}, [ - E('span', {'class': ''}, [ data['vps'][idx].title + ':' ]), - E('span', {'class': ''}, [ data['vps'][idx].value ]), - suppelements - ]) - ); - } - } + for(var idx in data) { - - for(var idx in data['internet']) { - - for(var ver in data['internet'][idx]) { + for(var ver in data[idx]) { var classname = ver, suppelements = '', - visible = data['internet'][idx][ver].visible; + visible = data[idx][ver].visible; if('connected' === ver) { - classname = data['internet'][idx][ver].value ? 'label label-success' : 'label label-danger'; - data['internet'][idx][ver].value = data['internet'][idx][ver].value ? _('yes') : _('no'); + classname = data[idx][ver].value ? 'label label-success' : 'label label-danger'; + data[idx][ver].value = data[idx][ver].value ? _('yes') : _('no'); } if ('v4' === idx) { @@ -106,17 +72,17 @@ return baseclass.extend({ if ('title' === ver) { container_internet_v4.appendChild( E('p', { 'class': 'mt-2'}, [ - E('h4', {'class': ''}, [ data['internet'][idx].title ]), + E('span', {'class': ''}, [ data[idx].title ]), ]) ); continue; } if ('addrsv4' === ver) { - var addrs = data['internet'][idx][ver].value; + var addrs = data[idx][ver].value; if(Array.isArray(addrs) && addrs.length) { for(var ip in addrs) { - data['internet'][idx][ver].value = addrs[ip].split('/')[0]; + data[idx][ver].value = addrs[ip].split('/')[0]; } } } @@ -124,8 +90,8 @@ return baseclass.extend({ if (visible) { container_internet_v4.appendChild( E('p', { 'class': 'mt-2'}, [ - E('span', {'class': ''}, [ data['internet'][idx][ver].title + ':' ]), - E('span', {'class': classname }, [ data['internet'][idx][ver].value ]), + E('span', {'class': ''}, [ data[idx][ver].title + ':' ]), + E('span', {'class': classname }, [ data[idx][ver].value ]), suppelements ]) ); @@ -136,7 +102,7 @@ return baseclass.extend({ if ('title' === ver) { container_internet_v6.appendChild( E('p', { 'class': 'mt-2'}, [ - E('h4', {'class': ''}, [ data['internet'][idx].title ]), + E('span', {'class': ''}, [ data[idx].title ]), ]) ); continue; @@ -145,8 +111,8 @@ return baseclass.extend({ if (visible) { container_internet_v6.appendChild( E('p', {'class': 'mt-2'}, [ - E('span', {'class': ''}, [data['internet'][idx][ver].title + ':']), - E('span', {'class': classname}, [data['internet'][idx][ver].value]), + E('span', {'class': ''}, [data[idx][ver].title + ':']), + E('span', {'class': classname}, [data[idx][ver].value]), suppelements ]) ); @@ -155,19 +121,8 @@ return baseclass.extend({ } } - container_item.appendChild(E('p', { 'class': 'table'}, [ - E('div', { 'class': 'tr' }, [ - E('div', { 'class': 'td' }, [ container_internet_vps ]) - ]), - E('div', { 'class': 'tr' }, [ - E('div', { 'class': 'td' }, [ - container_internet_v4 - ]), - E('div', { 'class': 'td' }, [ - container_internet_v6 - ]) - ]) - ])); + container_item.appendChild(container_internet_v4); + container_item.appendChild(container_internet_v6); } else { for(var idx in data) { container_item.appendChild( @@ -186,10 +141,13 @@ return baseclass.extend({ }, renderUpdateWanData: function(data, v6) { + for (var i = 0; i < data.length; i++) { var ifc = data[i]; if (v6) { + var uptime = ifc.getUptime(); + this.params.internet.v6.uptime.value = (uptime > 0) ? '%t'.format(uptime) : '-'; this.params.internet.v6.ipprefixv6.value = ifc.getIP6Prefix() || '-'; this.params.internet.v6.gatewayv6.value = ifc.getGateway6Addr() || '-'; this.params.internet.v6.protocol.value= ifc.getI18n() || E('em', _('Not connected')); @@ -207,115 +165,102 @@ return baseclass.extend({ } } }, - renderUpdateOpenMPTCProuterData: function(data, v6) { - if (data.openmptcprouter != undefined) { - if (data.openmptcprouter.wan_addr != '') this.params.omrvps.internet.v4.connected.value = true; - if (data.openmptcprouter.wan_addr) this.params.omrvps.internet.v4.addrsv4.value = data.openmptcprouter.wan_addr || [ '-']; - if (data.openmptcprouter.wan_addr6) this.params.omrvps.internet.v6.addrsv6.value = data.openmptcprouter.wan_addr6 || [ '-']; - if (data.openmptcprouter.vps_kernel) this.params.omrvps.vps.version.value = data.openmptcprouter.vps_kernel + ' ' + data.openmptcprouter.vps_omr_version || [ '-']; - if (data.openmptcprouter.vps_loadavg) { - var vps_loadavg = data.openmptcprouter.vps_loadavg.split(" "); - this.params.omrvps.vps.load.value = '%s, %s, %s'.format(vps_loadavg[0],vps_loadavg[1],vps_loadavg[2]); - } - if (data.openmptcprouter.vps_uptime) this.params.omrvps.vps.uptime.value = String.format('%t', data.openmptcprouter.vps_uptime) || [ '-']; - if (data.openmptcprouter.proxy_traffic) this.params.omrvps.vps.trafficproxy.value = this.formatBytes(data.openmptcprouter.proxy_traffic) || [ '-']; - if (data.openmptcprouter.vpn_traffic) this.params.omrvps.vps.trafficvpn.value = this.formatBytes(data.openmptcprouter.vpn_traffic) || [ '-']; - if (data.openmptcprouter.total_traffic) this.params.omrvps.vps.traffictotal.value = this.formatBytes(data.openmptcprouter.total_traffic) || [ '-']; - if (data.openmptcprouter.ipv6 != 'disabled') this.params.omrvps.internet.v6.connected.value = true; - } - }, renderInternetBox: function(data) { - this.params.omrvps = { - vps: { - title: _('Server'), + this.params.internet = { - version: { - title: _('Version'), - visible: true, - value: [ '-' ] - }, + v4: { + title: _('IPv4 Internet'), - load: { - title: _('Load'), + connected: { + title: _('Connected'), visible: true, - value: [ '-' ] + value: false }, uptime: { title: _('Uptime'), visible: true, - value: [ '-' ] + value: '-' }, - trafficproxy: { - title: _('Proxy traffic'), + protocol: { + title: _('Protocol'), + visible: true, + value: '-' + }, + + addrsv4: { + title: _('IPv4'), visible: true, value: [ '-' ] }, - trafficvpn: { - title: _('VPN traffic'), + gatewayv4: { + title: _('GatewayV4'), visible: true, - value: [ '-' ] + value: '-' }, - traffictotal: { - title: _('Total traffic'), + dnsv4: { + title: _('DNSv4'), visible: true, - value: [ '-' ] + value: ['-'] } }, - internet: { + v6: { + title: _('IPv6 Internet'), - v4: { - title: _('IPv4 Internet'), - - connected: { - title: _('Connected'), - visible: true, - value: false - }, - - addrsv4: { - title: _('IPv4'), - visible: true, - value: [ '-' ] - } + connected: { + title: _('Connected'), + visible: true, + value: false }, - v6: { - title: _('IPv6 Internet'), + uptime: { + title: _('Uptime'), + visible: true, + value: '-' + }, - connected: { - title: _('Connected'), - visible: true, - value: false - }, + protocol: { + title: _('Protocol'), + visible: true, + value: ' - ' + }, - ipprefixv6 : { - title: _('IPv6 prefix'), - visible: false, - value: ' - ' - }, + ipprefixv6 : { + title: _('IPv6 prefix'), + visible: true, + value: ' - ' + }, - addrsv6: { - title: _('IPv6'), - visible: true, - value: [ '-' ] - } + addrsv6: { + title: _('IPv6'), + visible: false, + value: [ '-' ] + }, + gatewayv6: { + title: _('GatewayV6'), + visible: true, + value: '-' + }, + + dnsv6: { + title: _('DNSv6'), + visible: true, + value: [ '-' ] } } }; - //this.renderUpdateWanData(data[0], false); - //this.renderUpdateWanData(data[1], true); - this.renderUpdateOpenMPTCProuterData(data[4], true); + this.renderUpdateWanData(data[0], false); + this.renderUpdateWanData(data[1], true); - return this.renderHtml(this.params.omrvps, 'internet'); + return this.renderHtml(this.params.internet, 'internet'); }, renderRouterBox: function(data) { @@ -349,11 +294,6 @@ return baseclass.extend({ value: datestr }, - load: { - title: _('Load Average'), - value: Array.isArray(systeminfo.load) ? '%.2f, %.2f, %.2f'.format(systeminfo.load[0] / 65535.0,systeminfo.load[1] / 65535.0,systeminfo.load[2] / 65535.0) : null - }, - kernel: { title: _('Kernel Version'), value: boardinfo.kernel @@ -371,7 +311,7 @@ return baseclass.extend({ release: { title: _('Firmware Version'), - value: (typeof boardinfo.release !== "undefined") ? ((typeof boardinfo.release.description !== "undefined") ? boardinfo.release.description : null) : null + value: boardinfo.release.description } }; diff --git a/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js b/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js old mode 100755 new mode 100644 index c673fa681..9f4edce28 --- a/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js +++ b/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js @@ -70,13 +70,11 @@ return baseclass.extend({ ])); } - if (this.params.lan.devices.length > 0) { - container_box.appendChild(E('hr')); - container_box.appendChild(container_devices); - container_box.appendChild(E('hr')); - container_box.appendChild(container_deviceslist); - container_wapper.appendChild(container_box); - } + container_box.appendChild(E('hr')); + container_box.appendChild(container_devices); + container_box.appendChild(E('hr')); + container_box.appendChild(container_deviceslist); + container_wapper.appendChild(container_box); return container_wapper; }, diff --git a/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js b/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js old mode 100755 new mode 100644 index fe5e843f0..318c3abf8 --- a/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js +++ b/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js @@ -78,20 +78,20 @@ return baseclass.extend({ container_box.appendChild(container_radio); - var container_devices = E('div', { 'class': 'table assoclist devices-info' }, [ - E('div', { 'class': 'tr table-titles dashboard-bg' }, [ - E('div', { 'class': 'th nowrap' }, _('Hostname')), - E('div', { 'class': 'th' }, _('Wireless')), - E('div', { 'class': 'th' }, _('Signal')), - E('div', { 'class': 'th' }, '%s / %s'.format( _('Up.'), _('Down.'))) + var container_devices = E('table', { 'class': 'table assoclist devices-info' }, [ + E('tr', { 'class': 'tr table-titles dashboard-bg' }, [ + E('th', { 'class': 'th nowrap' }, _('Hostname')), + E('th', { 'class': 'th' }, _('Wireless')), + E('th', { 'class': 'th' }, _('Signal')), + E('th', { 'class': 'th' }, '%s / %s'.format( _('Up.'), _('Down.'))) ]) ]); var container_devices_item; - var container_devices_list = E('div', { 'class': 'table assoclist devices-info' }); + var container_devices_list = E('table', { 'class': 'table assoclist devices-info' }); for (var i =0; i < this.params.wifi.devices.length; i++) { - container_devices_item = E('div', { 'class': 'tr cbi-rowstyle-1' }); + container_devices_item = E('tr', { 'class': 'tr cbi-rowstyle-1' }); for(var idx in this.params.wifi.devices[i]) { var device = this.params.wifi.devices[i]; @@ -109,7 +109,7 @@ return baseclass.extend({ ]) ]); } else if ('rate' == idx) { - container_content = E('div', { 'class': 'td device-info' }, [ + container_content = E('td', { 'class': 'td device-info' }, [ E('p', {}, [ E('span', { 'class': ''}, [ device[idx].value.rx ]), E('br'), @@ -117,7 +117,7 @@ return baseclass.extend({ ]) ]); } else { - container_content = E('div', { 'class': 'td device-info'}, [ + container_content = E('td', { 'class': 'td device-info'}, [ E('p', {}, [ E('span', { 'class': ''}, [ device[idx].value ]), ]) @@ -130,13 +130,11 @@ return baseclass.extend({ container_devices_list.appendChild(container_devices_item); } - if (this.params.wifi.devices.length > 0) { - container_devices.appendChild(container_devices_list); - container_box.appendChild(E('hr')); - container_box.appendChild(container_devices); - container_box.appendChild(container_devices_list); - container_wapper.appendChild(container_box); - } + container_devices.appendChild(container_devices_list); + container_box.appendChild(E('hr')); + container_box.appendChild(container_devices); + container_box.appendChild(container_devices_list); + container_wapper.appendChild(container_box); return container_wapper; }, @@ -149,7 +147,7 @@ return baseclass.extend({ for (var j = 0; j < network_items.length; j++) { var net = network_items[j], is_assoc = (net.getBSSID() != '00:00:00:00:00:00' && net.getChannel() && !net.isDisabled()), - chan = net.getChannel(), + chan = net.getChannel(), freq = net.getFrequency(), rate = net.getBitRate(); @@ -264,6 +262,8 @@ return baseclass.extend({ this.renderUpdateData(data[0], data[1], data[2]); - return this.renderHtml(); + if (this.params.wifi.radios.length) + return this.renderHtml(); + return E([]); } }); diff --git a/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/index.js b/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/index.js old mode 100755 new mode 100644 diff --git a/luci-mod-dashboard/po/ar/dashboard.po b/luci-mod-dashboard/po/ar/dashboard.po new file mode 100644 index 000000000..41ecc7e3a --- /dev/null +++ b/luci-mod-dashboard/po/ar/dashboard.po @@ -0,0 +1,215 @@ +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" +"Project-Id-Version: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: ar\n" +"MIME-Version: 1.0\n" +"Content-Transfer-Encoding: 8bit\n" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:163 +msgid "Active" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:308 +msgid "Architecture" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:181 +msgid "BSSID" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:175 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:243 +msgid "Bitrate" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:169 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:234 +msgid "Channel" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:177 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:217 +msgid "Connected" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:13 +msgid "DHCP Devices" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:207 +msgid "DNSv4" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:253 +msgid "DNSv6" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/luci/menu.d/luci-mod-dashboard.json:3 +msgid "Dashboard" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:134 +msgid "Devices" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:193 +msgid "Devices Connected" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Down." +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:129 +msgid "Download" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:187 +msgid "Encryption" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:313 +msgid "Firmware Version" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:171 +msgid "GHz" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:201 +msgid "GatewayV4" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:247 +msgid "GatewayV6" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:25 +msgid "Grant access to DHCP status display" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:12 +msgid "Grant access to main status display" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:3 +msgid "Grant access to the system route status" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:34 +msgid "Grant access to wireless status display" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:30 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:83 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:222 +msgid "Hostname" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:31 +msgid "IP Address" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:195 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:114 +msgid "IPv4" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:174 +msgid "IPv4 Internet" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:241 +msgid "IPv6" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:214 +msgid "IPv6 Internet" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:235 +msgid "IPv6 prefix" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "Internet" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:298 +msgid "Kernel Version" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:293 +msgid "Local Time" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:32 +msgid "MAC" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:119 +msgid "Mac" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:177 +msgid "Mbit/s" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:303 +msgid "Model" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:153 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:160 +msgid "Not connected" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:189 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:229 +msgid "Protocol" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:157 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:228 +msgid "SSID" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:85 +msgid "Signal" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "System" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Up." +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:124 +msgid "Upload" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:183 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:223 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:288 +msgid "Uptime" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:9 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:84 +msgid "Wireless" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "no" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "yes" +msgstr "" diff --git a/luci-mod-dashboard/po/bg/dashboard.po b/luci-mod-dashboard/po/bg/dashboard.po new file mode 100644 index 000000000..2a7df7bb6 --- /dev/null +++ b/luci-mod-dashboard/po/bg/dashboard.po @@ -0,0 +1,222 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"PO-Revision-Date: 2021-08-27 12:56+0000\n" +"Last-Translator: Iskren Mihaylov \n" +"Language-Team: Bulgarian \n" +"Language: bg\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.8.1-dev\n" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:163 +msgid "Active" +msgstr "Активен" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:308 +msgid "Architecture" +msgstr "Архитектура" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:181 +msgid "BSSID" +msgstr "BSSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:175 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:243 +msgid "Bitrate" +msgstr "Битрейт" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:169 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:234 +msgid "Channel" +msgstr "Канал" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:177 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:217 +msgid "Connected" +msgstr "Свързан" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:13 +msgid "DHCP Devices" +msgstr "DHCP Устройства" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:207 +msgid "DNSv4" +msgstr "DNSv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:253 +msgid "DNSv6" +msgstr "DNSv6" + +#: modules/luci-mod-dashboard/root/usr/share/luci/menu.d/luci-mod-dashboard.json:3 +msgid "Dashboard" +msgstr "Табло" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:134 +msgid "Devices" +msgstr "Устройства" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:193 +msgid "Devices Connected" +msgstr "Свързани устройства" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Down." +msgstr "Долу." + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:129 +msgid "Download" +msgstr "Сваляне" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:187 +msgid "Encryption" +msgstr "Криптиране" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:313 +msgid "Firmware Version" +msgstr "Версия на firmware" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:171 +msgid "GHz" +msgstr "GHz" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:201 +msgid "GatewayV4" +msgstr "ГейтауейV4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:247 +msgid "GatewayV6" +msgstr "GatewayV6" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:25 +msgid "Grant access to DHCP status display" +msgstr "Разрешаване достъп до DHCP статус екран" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:12 +msgid "Grant access to main status display" +msgstr "Разрешаване достъп до главен статус екран" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:3 +msgid "Grant access to the system route status" +msgstr "Разрешаване достъп до екран със системни маршрути" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:34 +msgid "Grant access to wireless status display" +msgstr "Разрешаване достъп до екран с безжичен статус" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:30 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:83 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:222 +msgid "Hostname" +msgstr "Хостнейм" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:31 +msgid "IP Address" +msgstr "IP адрес" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:195 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:114 +msgid "IPv4" +msgstr "IPv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:174 +msgid "IPv4 Internet" +msgstr "IPv4 Интернет" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:241 +msgid "IPv6" +msgstr "IPv6" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:214 +msgid "IPv6 Internet" +msgstr "IPv6 Интернет" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:235 +msgid "IPv6 prefix" +msgstr "IPv6 префикс" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "Internet" +msgstr "Интернет" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:298 +msgid "Kernel Version" +msgstr "Версия на ядрото" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:293 +msgid "Local Time" +msgstr "Местно време" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:32 +msgid "MAC" +msgstr "MAC" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:119 +msgid "Mac" +msgstr "Mac" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:177 +msgid "Mbit/s" +msgstr "Mbit/s" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:303 +msgid "Model" +msgstr "Модел" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:153 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:160 +msgid "Not connected" +msgstr "Не е свързан" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:189 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:229 +msgid "Protocol" +msgstr "Протокол" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:157 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:228 +msgid "SSID" +msgstr "SSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:85 +msgid "Signal" +msgstr "Сигнал" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "System" +msgstr "Система" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Up." +msgstr "Горе." + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:124 +msgid "Upload" +msgstr "Качване" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:183 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:223 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:288 +msgid "Uptime" +msgstr "Ъптайм" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:9 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:84 +msgid "Wireless" +msgstr "Безжичен" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "no" +msgstr "не" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "yes" +msgstr "да" + +#~ msgid "Connected since" +#~ msgstr "Свързан от" diff --git a/luci-mod-dashboard/po/bn_BD/dashboard.po b/luci-mod-dashboard/po/bn_BD/dashboard.po new file mode 100644 index 000000000..b168d00a2 --- /dev/null +++ b/luci-mod-dashboard/po/bn_BD/dashboard.po @@ -0,0 +1,219 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"PO-Revision-Date: 2021-10-08 17:53+0000\n" +"Last-Translator: Rayhan Nabi \n" +"Language-Team: Bengali (Bangladesh) \n" +"Language: bn_BD\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.9-dev\n" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:163 +msgid "Active" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:308 +msgid "Architecture" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:181 +msgid "BSSID" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:175 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:243 +msgid "Bitrate" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:169 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:234 +msgid "Channel" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:177 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:217 +msgid "Connected" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:13 +msgid "DHCP Devices" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:207 +msgid "DNSv4" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:253 +msgid "DNSv6" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/luci/menu.d/luci-mod-dashboard.json:3 +msgid "Dashboard" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:134 +msgid "Devices" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:193 +msgid "Devices Connected" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Down." +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:129 +msgid "Download" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:187 +msgid "Encryption" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:313 +msgid "Firmware Version" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:171 +msgid "GHz" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:201 +msgid "GatewayV4" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:247 +msgid "GatewayV6" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:25 +msgid "Grant access to DHCP status display" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:12 +msgid "Grant access to main status display" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:3 +msgid "Grant access to the system route status" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:34 +msgid "Grant access to wireless status display" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:30 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:83 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:222 +msgid "Hostname" +msgstr "হোস্টনেম" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:31 +msgid "IP Address" +msgstr "আইপি এড্রেস" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:195 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:114 +msgid "IPv4" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:174 +msgid "IPv4 Internet" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:241 +msgid "IPv6" +msgstr "IPv6" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:214 +msgid "IPv6 Internet" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:235 +msgid "IPv6 prefix" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "Internet" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:298 +msgid "Kernel Version" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:293 +msgid "Local Time" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:32 +msgid "MAC" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:119 +msgid "Mac" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:177 +msgid "Mbit/s" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:303 +msgid "Model" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:153 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:160 +msgid "Not connected" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:189 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:229 +msgid "Protocol" +msgstr "প্রোটোকল" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:157 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:228 +msgid "SSID" +msgstr "SSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:85 +msgid "Signal" +msgstr "সংকেত" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "System" +msgstr "সিস্টেম" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Up." +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:124 +msgid "Upload" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:183 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:223 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:288 +msgid "Uptime" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:9 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:84 +msgid "Wireless" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "no" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "yes" +msgstr "" diff --git a/luci-mod-dashboard/po/ca/dashboard.po b/luci-mod-dashboard/po/ca/dashboard.po new file mode 100644 index 000000000..9f2a47c1d --- /dev/null +++ b/luci-mod-dashboard/po/ca/dashboard.po @@ -0,0 +1,219 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"PO-Revision-Date: 2023-03-08 10:38+0000\n" +"Last-Translator: Roger Pueyo Centelles \n" +"Language-Team: Catalan \n" +"Language: ca\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.16.2-dev\n" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:163 +msgid "Active" +msgstr "Actiu" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:308 +msgid "Architecture" +msgstr "Arquitectura" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:181 +msgid "BSSID" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:175 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:243 +msgid "Bitrate" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:169 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:234 +msgid "Channel" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:177 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:217 +msgid "Connected" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:13 +msgid "DHCP Devices" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:207 +msgid "DNSv4" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:253 +msgid "DNSv6" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/luci/menu.d/luci-mod-dashboard.json:3 +msgid "Dashboard" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:134 +msgid "Devices" +msgstr "Dispositius" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:193 +msgid "Devices Connected" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Down." +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:129 +msgid "Download" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:187 +msgid "Encryption" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:313 +msgid "Firmware Version" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:171 +msgid "GHz" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:201 +msgid "GatewayV4" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:247 +msgid "GatewayV6" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:25 +msgid "Grant access to DHCP status display" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:12 +msgid "Grant access to main status display" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:3 +msgid "Grant access to the system route status" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:34 +msgid "Grant access to wireless status display" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:30 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:83 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:222 +msgid "Hostname" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:31 +msgid "IP Address" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:195 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:114 +msgid "IPv4" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:174 +msgid "IPv4 Internet" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:241 +msgid "IPv6" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:214 +msgid "IPv6 Internet" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:235 +msgid "IPv6 prefix" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "Internet" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:298 +msgid "Kernel Version" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:293 +msgid "Local Time" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:32 +msgid "MAC" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:119 +msgid "Mac" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:177 +msgid "Mbit/s" +msgstr "Mbit/s" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:303 +msgid "Model" +msgstr "Model" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:153 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:160 +msgid "Not connected" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:189 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:229 +msgid "Protocol" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:157 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:228 +msgid "SSID" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:85 +msgid "Signal" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "System" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Up." +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:124 +msgid "Upload" +msgstr "Puja" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:183 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:223 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:288 +msgid "Uptime" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:9 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:84 +msgid "Wireless" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "no" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "yes" +msgstr "" diff --git a/luci-mod-dashboard/po/cs/dashboard.po b/luci-mod-dashboard/po/cs/dashboard.po new file mode 100644 index 000000000..1510f26db --- /dev/null +++ b/luci-mod-dashboard/po/cs/dashboard.po @@ -0,0 +1,222 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"PO-Revision-Date: 2023-01-18 00:56+0000\n" +"Last-Translator: Lukáš Wagner \n" +"Language-Team: Czech \n" +"Language: cs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" +"X-Generator: Weblate 4.15.1-dev\n" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:163 +msgid "Active" +msgstr "Aktivní" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:308 +msgid "Architecture" +msgstr "Architektura" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:181 +msgid "BSSID" +msgstr "BSSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:175 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:243 +msgid "Bitrate" +msgstr "Přenosová rychlost" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:169 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:234 +msgid "Channel" +msgstr "Kanál" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:177 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:217 +msgid "Connected" +msgstr "Připojeno" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:13 +msgid "DHCP Devices" +msgstr "DHCP zařízení" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:207 +msgid "DNSv4" +msgstr "DNSv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:253 +msgid "DNSv6" +msgstr "DNSv6" + +#: modules/luci-mod-dashboard/root/usr/share/luci/menu.d/luci-mod-dashboard.json:3 +msgid "Dashboard" +msgstr "Řídicí panel" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:134 +msgid "Devices" +msgstr "Zařízení" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:193 +msgid "Devices Connected" +msgstr "Připojená zařízení" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Down." +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:129 +msgid "Download" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:187 +msgid "Encryption" +msgstr "Šifrování" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:313 +msgid "Firmware Version" +msgstr "Verze firmware" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:171 +msgid "GHz" +msgstr "GHz" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:201 +msgid "GatewayV4" +msgstr "Brána v4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:247 +msgid "GatewayV6" +msgstr "Brána v6" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:25 +msgid "Grant access to DHCP status display" +msgstr "Poskytnout přístup k zobrazení stavu DHCP" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:12 +msgid "Grant access to main status display" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:3 +msgid "Grant access to the system route status" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:34 +msgid "Grant access to wireless status display" +msgstr "Poskytnout přístup k zobrazení stavu bezdrátové sítě" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:30 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:83 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:222 +msgid "Hostname" +msgstr "Název počítače" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:31 +msgid "IP Address" +msgstr "IP adresa" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:195 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:114 +msgid "IPv4" +msgstr "IPv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:174 +msgid "IPv4 Internet" +msgstr "IPv4 Internet" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:241 +msgid "IPv6" +msgstr "IPv6" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:214 +msgid "IPv6 Internet" +msgstr "IPv6 Internet" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:235 +msgid "IPv6 prefix" +msgstr "IPv6 prefix" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "Internet" +msgstr "Internet" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:298 +msgid "Kernel Version" +msgstr "Verze kernelu" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:293 +msgid "Local Time" +msgstr "Místní čas" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:32 +msgid "MAC" +msgstr "MAC" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:119 +msgid "Mac" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:177 +msgid "Mbit/s" +msgstr "Mbit/s" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:303 +msgid "Model" +msgstr "Model" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:153 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:160 +msgid "Not connected" +msgstr "Nepřipojeno" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:189 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:229 +msgid "Protocol" +msgstr "Protokol" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:157 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:228 +msgid "SSID" +msgstr "SSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:85 +msgid "Signal" +msgstr "Signál" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "System" +msgstr "Systém" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Up." +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:124 +msgid "Upload" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:183 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:223 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:288 +msgid "Uptime" +msgstr "Doba běhu" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:9 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:84 +msgid "Wireless" +msgstr "Bezdrátová síť" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "no" +msgstr "ne" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "yes" +msgstr "ano" + +#~ msgid "Connected since" +#~ msgstr "Připojeno od" diff --git a/luci-mod-dashboard/po/da/dashboard.po b/luci-mod-dashboard/po/da/dashboard.po new file mode 100644 index 000000000..7fe4cc1ec --- /dev/null +++ b/luci-mod-dashboard/po/da/dashboard.po @@ -0,0 +1,220 @@ +msgid "" +msgstr "" +"PO-Revision-Date: 2021-12-08 22:46+0000\n" +"Last-Translator: drax red \n" +"Language-Team: Danish \n" +"Language: da\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.10-dev\n" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:163 +msgid "Active" +msgstr "Aktiv" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:308 +msgid "Architecture" +msgstr "Arkitektur" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:181 +msgid "BSSID" +msgstr "BSSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:175 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:243 +msgid "Bitrate" +msgstr "Bitrate" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:169 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:234 +msgid "Channel" +msgstr "Kanal" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:177 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:217 +msgid "Connected" +msgstr "Tilsluttet" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:13 +msgid "DHCP Devices" +msgstr "DHCP-enheder" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:207 +msgid "DNSv4" +msgstr "DNSv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:253 +msgid "DNSv6" +msgstr "DNSv6" + +#: modules/luci-mod-dashboard/root/usr/share/luci/menu.d/luci-mod-dashboard.json:3 +msgid "Dashboard" +msgstr "Dashboard" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:134 +msgid "Devices" +msgstr "Enheder" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:193 +msgid "Devices Connected" +msgstr "Enheder tilsluttet" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Down." +msgstr "Ned." + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:129 +msgid "Download" +msgstr "Download" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:187 +msgid "Encryption" +msgstr "Kryptering" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:313 +msgid "Firmware Version" +msgstr "Firmware-version" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:171 +msgid "GHz" +msgstr "GHz" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:201 +msgid "GatewayV4" +msgstr "GatewayV4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:247 +msgid "GatewayV6" +msgstr "GatewayV6" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:25 +msgid "Grant access to DHCP status display" +msgstr "Giver adgang til visning af DHCP-status" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:12 +msgid "Grant access to main status display" +msgstr "Giver adgang til hovedstatusdisplayet" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:3 +msgid "Grant access to the system route status" +msgstr "Giv adgang til systemets rutestatus" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:34 +msgid "Grant access to wireless status display" +msgstr "Giv adgang til trådløs statusvisning" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:30 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:83 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:222 +msgid "Hostname" +msgstr "Værtsnavn" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:31 +msgid "IP Address" +msgstr "IP-adresse" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:195 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:114 +msgid "IPv4" +msgstr "IPv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:174 +msgid "IPv4 Internet" +msgstr "IPv4 Internet" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:241 +msgid "IPv6" +msgstr "IPv6" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:214 +msgid "IPv6 Internet" +msgstr "IPv6 Internet" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:235 +msgid "IPv6 prefix" +msgstr "IPv6-præfiks" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "Internet" +msgstr "Internet" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:298 +msgid "Kernel Version" +msgstr "Kerneversion" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:293 +msgid "Local Time" +msgstr "Lokal tid" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:32 +msgid "MAC" +msgstr "MAC" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:119 +msgid "Mac" +msgstr "Mac" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:177 +msgid "Mbit/s" +msgstr "Mbit/s" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:303 +msgid "Model" +msgstr "Model" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:153 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:160 +msgid "Not connected" +msgstr "Ikke tilsluttet" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:189 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:229 +msgid "Protocol" +msgstr "Protokol" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:157 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:228 +msgid "SSID" +msgstr "SSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:85 +msgid "Signal" +msgstr "Signal" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "System" +msgstr "System" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Up." +msgstr "Op." + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:124 +msgid "Upload" +msgstr "Upload" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:183 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:223 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:288 +msgid "Uptime" +msgstr "Oppetid" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:9 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:84 +msgid "Wireless" +msgstr "Trådløs" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "no" +msgstr "nej" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "yes" +msgstr "ja" + +#~ msgid "Connected since" +#~ msgstr "Tilsluttet siden" diff --git a/luci-mod-dashboard/po/de/dashboard.po b/luci-mod-dashboard/po/de/dashboard.po new file mode 100644 index 000000000..dbcd01a92 --- /dev/null +++ b/luci-mod-dashboard/po/de/dashboard.po @@ -0,0 +1,222 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"PO-Revision-Date: 2023-06-20 16:23+0000\n" +"Last-Translator: ssantos \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.18.1\n" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:163 +msgid "Active" +msgstr "Aktiv" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:308 +msgid "Architecture" +msgstr "Architektur" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:181 +msgid "BSSID" +msgstr "BSSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:175 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:243 +msgid "Bitrate" +msgstr "Bitrate" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:169 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:234 +msgid "Channel" +msgstr "Kanal" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:177 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:217 +msgid "Connected" +msgstr "Verbunden" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:13 +msgid "DHCP Devices" +msgstr "DHCP-Geräte" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:207 +msgid "DNSv4" +msgstr "DNSv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:253 +msgid "DNSv6" +msgstr "DNSv6" + +#: modules/luci-mod-dashboard/root/usr/share/luci/menu.d/luci-mod-dashboard.json:3 +msgid "Dashboard" +msgstr "Übersicht" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:134 +msgid "Devices" +msgstr "Geräte" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:193 +msgid "Devices Connected" +msgstr "Verbundene Geräte" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Down." +msgstr "Runter." + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:129 +msgid "Download" +msgstr "Herunterladen" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:187 +msgid "Encryption" +msgstr "Verschlüsselung" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:313 +msgid "Firmware Version" +msgstr "Firmware-Version" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:171 +msgid "GHz" +msgstr "GHz" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:201 +msgid "GatewayV4" +msgstr "GatewayV4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:247 +msgid "GatewayV6" +msgstr "GatewayV6" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:25 +msgid "Grant access to DHCP status display" +msgstr "Zugriff auf die DHCP-Statusanzeige gewähren" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:12 +msgid "Grant access to main status display" +msgstr "Zugriff zur Hauptstatusanzeige gewähren" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:3 +msgid "Grant access to the system route status" +msgstr "Zugriff auf den Status der Systemroute gewähren" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:34 +msgid "Grant access to wireless status display" +msgstr "Zugriff auf Wireless-Statusanzeige gewähren" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:30 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:83 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:222 +msgid "Hostname" +msgstr "Hostname" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:31 +msgid "IP Address" +msgstr "IP-Adresse" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:195 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:114 +msgid "IPv4" +msgstr "IPv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:174 +msgid "IPv4 Internet" +msgstr "IPv4-Internet" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:241 +msgid "IPv6" +msgstr "IPv6" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:214 +msgid "IPv6 Internet" +msgstr "IPv6-Internet" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:235 +msgid "IPv6 prefix" +msgstr "IPv6-Präfix" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "Internet" +msgstr "Internet" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:298 +msgid "Kernel Version" +msgstr "Kernel-Version" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:293 +msgid "Local Time" +msgstr "Ortszeit" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:32 +msgid "MAC" +msgstr "MAC" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:119 +msgid "Mac" +msgstr "Mac" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:177 +msgid "Mbit/s" +msgstr "Mbit/s" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:303 +msgid "Model" +msgstr "Modell" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:153 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:160 +msgid "Not connected" +msgstr "Nicht verbunden" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:189 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:229 +msgid "Protocol" +msgstr "Protokoll" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:157 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:228 +msgid "SSID" +msgstr "SSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:85 +msgid "Signal" +msgstr "Signal" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "System" +msgstr "System" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Up." +msgstr "Aktiv." + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:124 +msgid "Upload" +msgstr "Hochladen" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:183 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:223 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:288 +msgid "Uptime" +msgstr "Laufzeit" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:9 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:84 +msgid "Wireless" +msgstr "WLAN" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "no" +msgstr "nein" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "yes" +msgstr "ja" + +#~ msgid "Connected since" +#~ msgstr "Verbunden seit" diff --git a/luci-mod-dashboard/po/el/dashboard.po b/luci-mod-dashboard/po/el/dashboard.po new file mode 100644 index 000000000..905dc71db --- /dev/null +++ b/luci-mod-dashboard/po/el/dashboard.po @@ -0,0 +1,222 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"PO-Revision-Date: 2022-05-15 17:04+0000\n" +"Last-Translator: MarioK239 \n" +"Language-Team: Greek \n" +"Language: el\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.13-dev\n" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:163 +msgid "Active" +msgstr "Ενεργό" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:308 +msgid "Architecture" +msgstr "Αρχιτεκτονική" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:181 +msgid "BSSID" +msgstr "BSSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:175 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:243 +msgid "Bitrate" +msgstr "Ρυθμός bit" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:169 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:234 +msgid "Channel" +msgstr "Κανάλι" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:177 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:217 +msgid "Connected" +msgstr "Συνδεδεμένο" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:13 +msgid "DHCP Devices" +msgstr "Συσκευές DHCP" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:207 +msgid "DNSv4" +msgstr "DNSv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:253 +msgid "DNSv6" +msgstr "DNSv6" + +#: modules/luci-mod-dashboard/root/usr/share/luci/menu.d/luci-mod-dashboard.json:3 +msgid "Dashboard" +msgstr "Ταμπλό" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:134 +msgid "Devices" +msgstr "Συσκευές" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:193 +msgid "Devices Connected" +msgstr "Συσκευές Συνδεδεμένες" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Down." +msgstr "Κάτω." + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:129 +msgid "Download" +msgstr "Λήψη" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:187 +msgid "Encryption" +msgstr "Κρυπτογράφηση" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:313 +msgid "Firmware Version" +msgstr "Έκδοση υλικολογισμικού" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:171 +msgid "GHz" +msgstr "GHz" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:201 +msgid "GatewayV4" +msgstr "GatewayV4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:247 +msgid "GatewayV6" +msgstr "GatewayV6" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:25 +msgid "Grant access to DHCP status display" +msgstr "Παραχωρήστε πρόσβαση στην οθόνη κατάστασης DHCP" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:12 +msgid "Grant access to main status display" +msgstr "Παραχωρήστε πρόσβαση στην κύρια οθόνη κατάστασης" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:3 +msgid "Grant access to the system route status" +msgstr "Παραχωρήστε πρόσβαση στην κατάσταση διαδρομής συστήματος" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:34 +msgid "Grant access to wireless status display" +msgstr "Παραχωρήστε πρόσβαση στην οθόνη ασύρματης κατάστασης" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:30 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:83 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:222 +msgid "Hostname" +msgstr "Hostname" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:31 +msgid "IP Address" +msgstr "Διεύθυνση IP" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:195 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:114 +msgid "IPv4" +msgstr "IPv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:174 +msgid "IPv4 Internet" +msgstr "Ίντερνετ IPv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:241 +msgid "IPv6" +msgstr "IPv6" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:214 +msgid "IPv6 Internet" +msgstr "Ίντερνετ IPv6" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:235 +msgid "IPv6 prefix" +msgstr "Πρόθεμα IPv6" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "Internet" +msgstr "Διαδίκτυο" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:298 +msgid "Kernel Version" +msgstr "Έκδοση kernel" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:293 +msgid "Local Time" +msgstr "Τοπική ώρα" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:32 +msgid "MAC" +msgstr "MAC" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:119 +msgid "Mac" +msgstr "Mac" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:177 +msgid "Mbit/s" +msgstr "Mbit/s" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:303 +msgid "Model" +msgstr "Μοντέλο" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:153 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:160 +msgid "Not connected" +msgstr "Μη συνδεδεμένο" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:189 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:229 +msgid "Protocol" +msgstr "Πρωτόκολλο" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:157 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:228 +msgid "SSID" +msgstr "SSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:85 +msgid "Signal" +msgstr "Σήμα" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "System" +msgstr "Σύστημα" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Up." +msgstr "Πάνω." + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:124 +msgid "Upload" +msgstr "Μεταφόρτωση" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:183 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:223 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:288 +msgid "Uptime" +msgstr "Χρόνος λειτουργίας" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:9 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:84 +msgid "Wireless" +msgstr "Ασύρματο" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "no" +msgstr "όχι" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "yes" +msgstr "ναί" + +#~ msgid "Connected since" +#~ msgstr "Συνδεδεμένο από" diff --git a/luci-mod-dashboard/po/en/dashboard.po b/luci-mod-dashboard/po/en/dashboard.po new file mode 100644 index 000000000..80f51b65f --- /dev/null +++ b/luci-mod-dashboard/po/en/dashboard.po @@ -0,0 +1,222 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"PO-Revision-Date: 2021-06-24 07:45+0000\n" +"Last-Translator: Hannu Nyman \n" +"Language-Team: English \n" +"Language: en\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.7.1-dev\n" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:163 +msgid "Active" +msgstr "Active" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:308 +msgid "Architecture" +msgstr "Architecture" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:181 +msgid "BSSID" +msgstr "BSSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:175 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:243 +msgid "Bitrate" +msgstr "Bitrate" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:169 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:234 +msgid "Channel" +msgstr "Channel" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:177 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:217 +msgid "Connected" +msgstr "Connected" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:13 +msgid "DHCP Devices" +msgstr "DHCP Devices" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:207 +msgid "DNSv4" +msgstr "DNSv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:253 +msgid "DNSv6" +msgstr "DNSv6" + +#: modules/luci-mod-dashboard/root/usr/share/luci/menu.d/luci-mod-dashboard.json:3 +msgid "Dashboard" +msgstr "Dashboard" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:134 +msgid "Devices" +msgstr "Devices" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:193 +msgid "Devices Connected" +msgstr "Devices Connected" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Down." +msgstr "Down." + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:129 +msgid "Download" +msgstr "Download" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:187 +msgid "Encryption" +msgstr "Encryption" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:313 +msgid "Firmware Version" +msgstr "Firmware Version" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:171 +msgid "GHz" +msgstr "GHz" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:201 +msgid "GatewayV4" +msgstr "GatewayV4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:247 +msgid "GatewayV6" +msgstr "GatewayV6" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:25 +msgid "Grant access to DHCP status display" +msgstr "Grant access to DHCP status display" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:12 +msgid "Grant access to main status display" +msgstr "Grant access to main status display" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:3 +msgid "Grant access to the system route status" +msgstr "Grant access to the system route status" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:34 +msgid "Grant access to wireless status display" +msgstr "Grant access to wireless status display" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:30 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:83 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:222 +msgid "Hostname" +msgstr "Hostname" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:31 +msgid "IP Address" +msgstr "IP Address" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:195 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:114 +msgid "IPv4" +msgstr "IPv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:174 +msgid "IPv4 Internet" +msgstr "IPv4 Internet" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:241 +msgid "IPv6" +msgstr "IPv6" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:214 +msgid "IPv6 Internet" +msgstr "IPv6 Internet" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:235 +msgid "IPv6 prefix" +msgstr "IPv6 prefix" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "Internet" +msgstr "Internet" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:298 +msgid "Kernel Version" +msgstr "Kernel Version" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:293 +msgid "Local Time" +msgstr "Local Time" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:32 +msgid "MAC" +msgstr "MAC" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:119 +msgid "Mac" +msgstr "Mac" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:177 +msgid "Mbit/s" +msgstr "Mbit/s" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:303 +msgid "Model" +msgstr "Model" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:153 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:160 +msgid "Not connected" +msgstr "Not connected" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:189 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:229 +msgid "Protocol" +msgstr "Protocol" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:157 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:228 +msgid "SSID" +msgstr "SSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:85 +msgid "Signal" +msgstr "Signal" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "System" +msgstr "System" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Up." +msgstr "Up." + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:124 +msgid "Upload" +msgstr "Upload" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:183 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:223 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:288 +msgid "Uptime" +msgstr "Uptime" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:9 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:84 +msgid "Wireless" +msgstr "Wireless" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "no" +msgstr "no" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "yes" +msgstr "yes" + +#~ msgid "Connected since" +#~ msgstr "Connected since" diff --git a/luci-mod-dashboard/po/es/dashboard.po b/luci-mod-dashboard/po/es/dashboard.po new file mode 100644 index 000000000..ac5750e29 --- /dev/null +++ b/luci-mod-dashboard/po/es/dashboard.po @@ -0,0 +1,223 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"PO-Revision-Date: 2023-04-17 08:10+0000\n" +"Last-Translator: Juan \n" +"Language-Team: Spanish \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17-dev\n" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:163 +msgid "Active" +msgstr "Activo" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:308 +msgid "Architecture" +msgstr "Arquitectura" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:181 +msgid "BSSID" +msgstr "BSSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:175 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:243 +msgid "Bitrate" +msgstr "Tasa de bits" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:169 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:234 +msgid "Channel" +msgstr "Canal" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:177 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:217 +msgid "Connected" +msgstr "Conectado" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:13 +msgid "DHCP Devices" +msgstr "Dispositivos DHCP" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:207 +msgid "DNSv4" +msgstr "DNSv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:253 +msgid "DNSv6" +msgstr "DNSv6" + +#: modules/luci-mod-dashboard/root/usr/share/luci/menu.d/luci-mod-dashboard.json:3 +msgid "Dashboard" +msgstr "Tablero" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:134 +msgid "Devices" +msgstr "Dispositivos" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:193 +msgid "Devices Connected" +msgstr "Dispositivos conectados" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Down." +msgstr "Desc." + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:129 +msgid "Download" +msgstr "Descargar" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:187 +msgid "Encryption" +msgstr "Encriptación" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:313 +msgid "Firmware Version" +msgstr "Versión del firmware" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:171 +msgid "GHz" +msgstr "GHz" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:201 +msgid "GatewayV4" +msgstr "GatewayV4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:247 +msgid "GatewayV6" +msgstr "GatewayV6" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:25 +msgid "Grant access to DHCP status display" +msgstr "Otorgar acceso a la pantalla de estado de DHCP" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:12 +msgid "Grant access to main status display" +msgstr "Otorgar acceso a la pantalla de estado principal" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:3 +#, fuzzy +msgid "Grant access to the system route status" +msgstr "Otorgar acceso al estado de la ruta del sistema" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:34 +msgid "Grant access to wireless status display" +msgstr "Otorgar acceso a la pantalla de estado de Wi-Fi" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:30 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:83 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:222 +msgid "Hostname" +msgstr "Nombre de host" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:31 +msgid "IP Address" +msgstr "Dirección IP" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:195 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:114 +msgid "IPv4" +msgstr "IPv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:174 +msgid "IPv4 Internet" +msgstr "Internet IPv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:241 +msgid "IPv6" +msgstr "IPv6" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:214 +msgid "IPv6 Internet" +msgstr "Internet IPv6" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:235 +msgid "IPv6 prefix" +msgstr "Prefijo IPv6" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "Internet" +msgstr "Internet" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:298 +msgid "Kernel Version" +msgstr "Versión del núcleo" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:293 +msgid "Local Time" +msgstr "Hora local" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:32 +msgid "MAC" +msgstr "MAC" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:119 +msgid "Mac" +msgstr "Mac" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:177 +msgid "Mbit/s" +msgstr "Mbit/s" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:303 +msgid "Model" +msgstr "Modelo" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:153 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:160 +msgid "Not connected" +msgstr "No conectado" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:189 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:229 +msgid "Protocol" +msgstr "Protocolo" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:157 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:228 +msgid "SSID" +msgstr "SSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:85 +msgid "Signal" +msgstr "Señal" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "System" +msgstr "Sistema" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Up." +msgstr "Carga" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:124 +msgid "Upload" +msgstr "Cargar" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:183 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:223 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:288 +msgid "Uptime" +msgstr "Tiempo de actividad" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:9 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:84 +msgid "Wireless" +msgstr "Wi-Fi" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "no" +msgstr "no" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "yes" +msgstr "sí" + +#~ msgid "Connected since" +#~ msgstr "Conectado desde" diff --git a/luci-mod-dashboard/po/fi/dashboard.po b/luci-mod-dashboard/po/fi/dashboard.po new file mode 100644 index 000000000..7a0e80f4f --- /dev/null +++ b/luci-mod-dashboard/po/fi/dashboard.po @@ -0,0 +1,222 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"PO-Revision-Date: 2022-03-13 23:17+0000\n" +"Last-Translator: Jiri Grönroos \n" +"Language-Team: Finnish \n" +"Language: fi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.12-dev\n" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:163 +msgid "Active" +msgstr "Aktiivinen" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:308 +msgid "Architecture" +msgstr "Arkkitehtuuri" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:181 +msgid "BSSID" +msgstr "BSSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:175 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:243 +msgid "Bitrate" +msgstr "Bittinopeus" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:169 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:234 +msgid "Channel" +msgstr "Kanava" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:177 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:217 +msgid "Connected" +msgstr "Yhdistetty" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:13 +msgid "DHCP Devices" +msgstr "DHCP-laitteet" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:207 +msgid "DNSv4" +msgstr "DNSv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:253 +msgid "DNSv6" +msgstr "DNSv6" + +#: modules/luci-mod-dashboard/root/usr/share/luci/menu.d/luci-mod-dashboard.json:3 +msgid "Dashboard" +msgstr "Kojelauta" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:134 +msgid "Devices" +msgstr "Laitteet" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:193 +msgid "Devices Connected" +msgstr "Yhdisteyt laitteet" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Down." +msgstr "Lataus" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:129 +msgid "Download" +msgstr "Lataus" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:187 +msgid "Encryption" +msgstr "Salaus" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:313 +msgid "Firmware Version" +msgstr "Laiteohjelmiston versio" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:171 +msgid "GHz" +msgstr "GHz" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:201 +msgid "GatewayV4" +msgstr "GatewayV4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:247 +msgid "GatewayV6" +msgstr "GatewayV6" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:25 +msgid "Grant access to DHCP status display" +msgstr "Salli pääsy DHCP-tilanäyttöön" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:12 +msgid "Grant access to main status display" +msgstr "Salli pääsy päätilanäyttöön" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:3 +msgid "Grant access to the system route status" +msgstr "Salli pääsy järjestelmän reitin tilaan" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:34 +msgid "Grant access to wireless status display" +msgstr "Salli pääsy langattoman tilan näyttöön" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:30 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:83 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:222 +msgid "Hostname" +msgstr "Laitenimi" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:31 +msgid "IP Address" +msgstr "IP-osoite" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:195 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:114 +msgid "IPv4" +msgstr "IPv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:174 +msgid "IPv4 Internet" +msgstr "IPv4 Internet" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:241 +msgid "IPv6" +msgstr "IPv6" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:214 +msgid "IPv6 Internet" +msgstr "IPv6 Internet" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:235 +msgid "IPv6 prefix" +msgstr "IPv6-etuliite" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "Internet" +msgstr "Internet" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:298 +msgid "Kernel Version" +msgstr "Ytimen versio" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:293 +msgid "Local Time" +msgstr "Paikallinen aika" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:32 +msgid "MAC" +msgstr "MAC" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:119 +msgid "Mac" +msgstr "Mac" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:177 +msgid "Mbit/s" +msgstr "Mbit/s" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:303 +msgid "Model" +msgstr "Malli" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:153 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:160 +msgid "Not connected" +msgstr "Ei yhdistetty" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:189 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:229 +msgid "Protocol" +msgstr "Protokolla" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:157 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:228 +msgid "SSID" +msgstr "SSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:85 +msgid "Signal" +msgstr "Signaali" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "System" +msgstr "Järjestelmä" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Up." +msgstr "Lähetys" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:124 +msgid "Upload" +msgstr "Lähetys" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:183 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:223 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:288 +msgid "Uptime" +msgstr "Toiminta-aika" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:9 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:84 +msgid "Wireless" +msgstr "Langaton" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "no" +msgstr "ei" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "yes" +msgstr "kyllä" + +#~ msgid "Connected since" +#~ msgstr "Yhdistetty lähtien" diff --git a/luci-mod-dashboard/po/fr/dashboard.po b/luci-mod-dashboard/po/fr/dashboard.po old mode 100755 new mode 100644 index ee91c668b..b394ddff8 --- a/luci-mod-dashboard/po/fr/dashboard.po +++ b/luci-mod-dashboard/po/fr/dashboard.po @@ -1,223 +1,222 @@ msgid "" msgstr "" -"PO-Revision-Date: 2022-02-19 07:53+0000\n" -"Last-Translator: Weblate Admin \n" -"Language-Team: French \n" +"Project-Id-Version: \n" +"PO-Revision-Date: 2023-06-11 13:51+0000\n" +"Last-Translator: Edouard Choinière \n" +"Language-Team: French \n" "Language: fr\n" +"MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 4.6.1\n" +"X-Generator: Weblate 4.18-dev\n" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:165 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:163 msgid "Active" msgstr "Actif" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:368 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:308 msgid "Architecture" msgstr "Architecture" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:183 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:181 msgid "BSSID" msgstr "BSSID" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:177 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:245 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:175 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:243 msgid "Bitrate" msgstr "Débit" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:171 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:236 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:169 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:234 msgid "Channel" msgstr "Canal" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:277 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:293 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:177 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:217 msgid "Connected" msgstr "Connecté" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:13 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:13 msgid "DHCP Devices" -msgstr "Périphériques DHCP" +msgstr "Appareils DHCP" -#: luci-mod-dashboard/root/usr/share/luci/menu.d/luci-mod-dashboard.json:3 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:207 +msgid "DNSv4" +msgstr "DNSv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:253 +msgid "DNSv6" +msgstr "DNS v6" + +#: modules/luci-mod-dashboard/root/usr/share/luci/menu.d/luci-mod-dashboard.json:3 msgid "Dashboard" msgstr "Tableau de bord" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:136 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:134 msgid "Devices" -msgstr "Périphériques" +msgstr "Appareils" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:195 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:193 msgid "Devices Connected" -msgstr "Périphériques connectés" +msgstr "Appareils connectés" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 msgid "Down." -msgstr "En panne." +msgstr "Déconnecté." -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:131 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:129 msgid "Download" -msgstr "Téléchargement" +msgstr "Télécharger" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:189 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:187 msgid "Encryption" msgstr "Chiffrement" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:373 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:313 msgid "Firmware Version" msgstr "Version du micrologiciel" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:173 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:171 msgid "GHz" -msgstr "GHz" +msgstr "Ghz" -#: luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:25 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:201 +msgid "GatewayV4" +msgstr "Passerelle V4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:247 +msgid "GatewayV6" +msgstr "Passerelle V6" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:25 msgid "Grant access to DHCP status display" msgstr "Permettre l'accès à l'affichage de l'état DHCP" -#: luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:12 +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:12 msgid "Grant access to main status display" msgstr "Permettre l'accès à l'affichage de l'état principal" -#: luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:3 +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:3 msgid "Grant access to the system route status" -msgstr "Permettre l’accès au status de routage" +msgstr "Autoriser l'accès à l'état de l'itinéraire du système" -#: luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:34 +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:34 msgid "Grant access to wireless status display" -msgstr "Permettre l'accès du status WIFI" +msgstr "Permettre l'accès au status WIFI" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:30 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:83 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:224 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:30 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:83 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:222 msgid "Hostname" msgstr "Nom d'hôte" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:31 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:31 msgid "IP Address" msgstr "Adresse IP" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:283 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:116 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:195 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:114 msgid "IPv4" msgstr "IPv4" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:274 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:174 msgid "IPv4 Internet" msgstr "Internet IPv4" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:305 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:241 msgid "IPv6" msgstr "IPv6" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:290 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:214 msgid "IPv6 Internet" msgstr "Internet IPv6" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:299 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:235 msgid "IPv6 prefix" msgstr "Préfixe IPv6" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:41 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 msgid "Internet" msgstr "Internet" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:358 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:298 msgid "Kernel Version" msgstr "Version du noyau" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:241 -msgid "Load" -msgstr "Charge" - -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:353 -msgid "Load Average" -msgstr "Charge moyenne" - -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:348 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:293 msgid "Local Time" msgstr "Heure locale" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:32 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:32 msgid "MAC" msgstr "MAC" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:121 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:119 msgid "Mac" -msgstr "Mac" +msgstr "MAC" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:179 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:177 msgid "Mbit/s" msgstr "Mbit/s" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:363 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:303 msgid "Model" msgstr "Modèle" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:195 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:202 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:153 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:160 msgid "Not connected" msgstr "Non connecté" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:253 -msgid "Proxy traffic" -msgstr "Trafic proxy" +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:189 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:229 +msgid "Protocol" +msgstr "Protocole" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:159 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:230 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:157 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:228 msgid "SSID" msgstr "SSID" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:232 -msgid "Server" -msgstr "Serveur" - -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:85 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:85 msgid "Signal" msgstr "Signal" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:41 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 msgid "System" msgstr "Système" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:265 -msgid "Total traffic" -msgstr "Trafic total" - -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 msgid "Up." -msgstr "En ligne." +msgstr "Connecté." -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:126 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:124 msgid "Upload" msgstr "Téléverser" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:247 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:343 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:183 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:223 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:288 msgid "Uptime" -msgstr "Temps de service" +msgstr "Disponibilité" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:259 -msgid "VPN traffic" -msgstr "Trafic VPN" - -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:235 -msgid "Version" -msgstr "Version" - -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:9 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:84 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:9 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:84 msgid "Wireless" -msgstr "Sans-fil" +msgstr "Sans fil" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:101 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 msgid "no" msgstr "non" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:101 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 msgid "yes" msgstr "oui" + +#~ msgid "Connected since" +#~ msgstr "Connecté depuis" diff --git a/luci-mod-dashboard/po/he/dashboard.po b/luci-mod-dashboard/po/he/dashboard.po new file mode 100644 index 000000000..905bf7389 --- /dev/null +++ b/luci-mod-dashboard/po/he/dashboard.po @@ -0,0 +1,216 @@ +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" +"Project-Id-Version: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: he\n" +"MIME-Version: 1.0\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:163 +msgid "Active" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:308 +msgid "Architecture" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:181 +msgid "BSSID" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:175 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:243 +msgid "Bitrate" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:169 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:234 +msgid "Channel" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:177 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:217 +msgid "Connected" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:13 +msgid "DHCP Devices" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:207 +msgid "DNSv4" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:253 +msgid "DNSv6" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/luci/menu.d/luci-mod-dashboard.json:3 +msgid "Dashboard" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:134 +msgid "Devices" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:193 +msgid "Devices Connected" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Down." +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:129 +msgid "Download" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:187 +msgid "Encryption" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:313 +msgid "Firmware Version" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:171 +msgid "GHz" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:201 +msgid "GatewayV4" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:247 +msgid "GatewayV6" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:25 +msgid "Grant access to DHCP status display" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:12 +msgid "Grant access to main status display" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:3 +msgid "Grant access to the system route status" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:34 +msgid "Grant access to wireless status display" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:30 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:83 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:222 +msgid "Hostname" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:31 +msgid "IP Address" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:195 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:114 +msgid "IPv4" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:174 +msgid "IPv4 Internet" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:241 +msgid "IPv6" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:214 +msgid "IPv6 Internet" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:235 +msgid "IPv6 prefix" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "Internet" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:298 +msgid "Kernel Version" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:293 +msgid "Local Time" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:32 +msgid "MAC" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:119 +msgid "Mac" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:177 +msgid "Mbit/s" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:303 +msgid "Model" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:153 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:160 +msgid "Not connected" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:189 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:229 +msgid "Protocol" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:157 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:228 +msgid "SSID" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:85 +msgid "Signal" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "System" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Up." +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:124 +msgid "Upload" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:183 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:223 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:288 +msgid "Uptime" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:9 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:84 +msgid "Wireless" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "no" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "yes" +msgstr "" diff --git a/luci-mod-dashboard/po/hi/dashboard.po b/luci-mod-dashboard/po/hi/dashboard.po new file mode 100644 index 000000000..dd6968663 --- /dev/null +++ b/luci-mod-dashboard/po/hi/dashboard.po @@ -0,0 +1,215 @@ +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" +"Project-Id-Version: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: hi\n" +"MIME-Version: 1.0\n" +"Content-Transfer-Encoding: 8bit\n" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:163 +msgid "Active" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:308 +msgid "Architecture" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:181 +msgid "BSSID" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:175 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:243 +msgid "Bitrate" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:169 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:234 +msgid "Channel" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:177 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:217 +msgid "Connected" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:13 +msgid "DHCP Devices" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:207 +msgid "DNSv4" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:253 +msgid "DNSv6" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/luci/menu.d/luci-mod-dashboard.json:3 +msgid "Dashboard" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:134 +msgid "Devices" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:193 +msgid "Devices Connected" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Down." +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:129 +msgid "Download" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:187 +msgid "Encryption" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:313 +msgid "Firmware Version" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:171 +msgid "GHz" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:201 +msgid "GatewayV4" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:247 +msgid "GatewayV6" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:25 +msgid "Grant access to DHCP status display" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:12 +msgid "Grant access to main status display" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:3 +msgid "Grant access to the system route status" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:34 +msgid "Grant access to wireless status display" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:30 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:83 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:222 +msgid "Hostname" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:31 +msgid "IP Address" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:195 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:114 +msgid "IPv4" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:174 +msgid "IPv4 Internet" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:241 +msgid "IPv6" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:214 +msgid "IPv6 Internet" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:235 +msgid "IPv6 prefix" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "Internet" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:298 +msgid "Kernel Version" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:293 +msgid "Local Time" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:32 +msgid "MAC" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:119 +msgid "Mac" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:177 +msgid "Mbit/s" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:303 +msgid "Model" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:153 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:160 +msgid "Not connected" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:189 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:229 +msgid "Protocol" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:157 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:228 +msgid "SSID" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:85 +msgid "Signal" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "System" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Up." +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:124 +msgid "Upload" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:183 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:223 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:288 +msgid "Uptime" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:9 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:84 +msgid "Wireless" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "no" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "yes" +msgstr "" diff --git a/luci-mod-dashboard/po/hu/dashboard.po b/luci-mod-dashboard/po/hu/dashboard.po new file mode 100644 index 000000000..a1e2e9eca --- /dev/null +++ b/luci-mod-dashboard/po/hu/dashboard.po @@ -0,0 +1,223 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"PO-Revision-Date: 2021-08-12 12:55+0000\n" +"Last-Translator: Tudós Péter \n" +"Language-Team: Hungarian \n" +"Language: hu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.8-dev\n" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:163 +msgid "Active" +msgstr "Aktív" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:308 +msgid "Architecture" +msgstr "Architektúra" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:181 +msgid "BSSID" +msgstr "BSSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:175 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:243 +msgid "Bitrate" +msgstr "Bitráta" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:169 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:234 +msgid "Channel" +msgstr "Csatorna" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:177 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:217 +msgid "Connected" +msgstr "Csatlakoztatott" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:13 +msgid "DHCP Devices" +msgstr "DHCP eszközök" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:207 +msgid "DNSv4" +msgstr "DNSv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:253 +msgid "DNSv6" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/luci/menu.d/luci-mod-dashboard.json:3 +msgid "Dashboard" +msgstr "Kezelőfelület" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:134 +msgid "Devices" +msgstr "Eszközök" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:193 +msgid "Devices Connected" +msgstr "Csatlakozott eszközök" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Down." +msgstr "Le." + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:129 +msgid "Download" +msgstr "Letöltés" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:187 +msgid "Encryption" +msgstr "Titkosítás" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:313 +msgid "Firmware Version" +msgstr "Firmware verzió" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:171 +msgid "GHz" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:201 +msgid "GatewayV4" +msgstr "Átjáró V4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:247 +msgid "GatewayV6" +msgstr "Átjáró V6" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:25 +msgid "Grant access to DHCP status display" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:12 +msgid "Grant access to main status display" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:3 +msgid "Grant access to the system route status" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:34 +msgid "Grant access to wireless status display" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:30 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:83 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:222 +msgid "Hostname" +msgstr "Gépnév" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:31 +msgid "IP Address" +msgstr "IP cím" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:195 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:114 +msgid "IPv4" +msgstr "IPv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:174 +msgid "IPv4 Internet" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:241 +msgid "IPv6" +msgstr "IPv6" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:214 +msgid "IPv6 Internet" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:235 +msgid "IPv6 prefix" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "Internet" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:298 +msgid "Kernel Version" +msgstr "Kernel Verzió" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:293 +msgid "Local Time" +msgstr "Helyi idő" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:32 +msgid "MAC" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:119 +msgid "Mac" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:177 +msgid "Mbit/s" +msgstr "Mbit/s" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:303 +msgid "Model" +msgstr "Modell" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:153 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:160 +msgid "Not connected" +msgstr "Nincs csatlakoztatva" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:189 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:229 +msgid "Protocol" +msgstr "Protokol" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:157 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:228 +msgid "SSID" +msgstr "SSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:85 +msgid "Signal" +msgstr "Jel" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "System" +msgstr "Rendszer" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Up." +msgstr "Fel." + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:124 +msgid "Upload" +msgstr "Feltöltés" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:183 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:223 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:288 +msgid "Uptime" +msgstr "Futási idő" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:9 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:84 +msgid "Wireless" +msgstr "Vezeték nélküli" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "no" +msgstr "nem" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "yes" +msgstr "igen" + +#, fuzzy +#~ msgid "Connected since" +#~ msgstr "Ennyi ideje csatlakoztatva" diff --git a/luci-mod-dashboard/po/id/dashboard.po b/luci-mod-dashboard/po/id/dashboard.po new file mode 100644 index 000000000..084d40545 --- /dev/null +++ b/luci-mod-dashboard/po/id/dashboard.po @@ -0,0 +1,220 @@ +msgid "" +msgstr "" +"PO-Revision-Date: 2023-03-12 20:08+0000\n" +"Last-Translator: Biangkerok32 \n" +"Language-Team: Indonesian \n" +"Language: id\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Weblate 4.16.2-dev\n" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:163 +msgid "Active" +msgstr "Aktif" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:308 +msgid "Architecture" +msgstr "Arsitektur" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:181 +msgid "BSSID" +msgstr "BSSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:175 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:243 +msgid "Bitrate" +msgstr "Bitrate" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:169 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:234 +msgid "Channel" +msgstr "Kanal" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:177 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:217 +msgid "Connected" +msgstr "Terhubung" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:13 +msgid "DHCP Devices" +msgstr "Perangkat DHCP" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:207 +msgid "DNSv4" +msgstr "DNSv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:253 +msgid "DNSv6" +msgstr "DNSv6" + +#: modules/luci-mod-dashboard/root/usr/share/luci/menu.d/luci-mod-dashboard.json:3 +msgid "Dashboard" +msgstr "Dasbor" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:134 +msgid "Devices" +msgstr "Perangkat" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:193 +msgid "Devices Connected" +msgstr "Perangkat Terhubung" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Down." +msgstr "Turun." + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:129 +msgid "Download" +msgstr "Unduh" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:187 +msgid "Encryption" +msgstr "Enkripsi" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:313 +msgid "Firmware Version" +msgstr "Versi Firmware" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:171 +msgid "GHz" +msgstr "GHz" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:201 +msgid "GatewayV4" +msgstr "GatewayV4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:247 +msgid "GatewayV6" +msgstr "GatewayV6" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:25 +msgid "Grant access to DHCP status display" +msgstr "Berikan akses ke tampilan status DHCP" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:12 +msgid "Grant access to main status display" +msgstr "Berikan akses ke tampilan status utama" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:3 +msgid "Grant access to the system route status" +msgstr "Berikan akses ke status rute sistem" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:34 +msgid "Grant access to wireless status display" +msgstr "Berikan akses ke tampilan status wifi" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:30 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:83 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:222 +msgid "Hostname" +msgstr "Hostname" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:31 +msgid "IP Address" +msgstr "Alamat IP" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:195 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:114 +msgid "IPv4" +msgstr "IPv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:174 +msgid "IPv4 Internet" +msgstr "IPv4 Internet" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:241 +msgid "IPv6" +msgstr "IPv6" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:214 +msgid "IPv6 Internet" +msgstr "IPv6 Internet" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:235 +msgid "IPv6 prefix" +msgstr "IPv6 prefix" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "Internet" +msgstr "Internet" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:298 +msgid "Kernel Version" +msgstr "Versi Kernel" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:293 +msgid "Local Time" +msgstr "Waktu setempat" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:32 +msgid "MAC" +msgstr "MAC" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:119 +msgid "Mac" +msgstr "Mac" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:177 +msgid "Mbit/s" +msgstr "Mbit/detik" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:303 +msgid "Model" +msgstr "Model" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:153 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:160 +msgid "Not connected" +msgstr "Tidak terhubung" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:189 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:229 +msgid "Protocol" +msgstr "Protokol" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:157 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:228 +msgid "SSID" +msgstr "SSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:85 +msgid "Signal" +msgstr "Sinyal" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "System" +msgstr "Sistem" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Up." +msgstr "Naik." + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:124 +msgid "Upload" +msgstr "Upload" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:183 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:223 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:288 +msgid "Uptime" +msgstr "Waktu terkini" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:9 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:84 +msgid "Wireless" +msgstr "Wifi" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "no" +msgstr "tidak" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "yes" +msgstr "ya" + +#~ msgid "Connected since" +#~ msgstr "Terhubung sejak" diff --git a/luci-mod-dashboard/po/it/dashboard.po b/luci-mod-dashboard/po/it/dashboard.po new file mode 100644 index 000000000..7dae9b8bd --- /dev/null +++ b/luci-mod-dashboard/po/it/dashboard.po @@ -0,0 +1,222 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"PO-Revision-Date: 2022-12-26 08:48+0000\n" +"Last-Translator: Daniele Luisetto \n" +"Language-Team: Italian \n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.15.1-dev\n" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:163 +msgid "Active" +msgstr "Attivo" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:308 +msgid "Architecture" +msgstr "Architettura" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:181 +msgid "BSSID" +msgstr "BSSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:175 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:243 +msgid "Bitrate" +msgstr "Bitrate" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:169 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:234 +msgid "Channel" +msgstr "Canale" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:177 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:217 +msgid "Connected" +msgstr "Connesso" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:13 +msgid "DHCP Devices" +msgstr "Dispositivi DHCP" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:207 +msgid "DNSv4" +msgstr "DNSv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:253 +msgid "DNSv6" +msgstr "DNSv6" + +#: modules/luci-mod-dashboard/root/usr/share/luci/menu.d/luci-mod-dashboard.json:3 +msgid "Dashboard" +msgstr "Pannello di controllo" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:134 +msgid "Devices" +msgstr "Dispositivi" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:193 +msgid "Devices Connected" +msgstr "Dispositivi connessi" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Down." +msgstr "Disconesso." + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:129 +msgid "Download" +msgstr "Download" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:187 +msgid "Encryption" +msgstr "Crittografia" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:313 +msgid "Firmware Version" +msgstr "Versione del Firmware" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:171 +msgid "GHz" +msgstr "GHz" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:201 +msgid "GatewayV4" +msgstr "GatewayV4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:247 +msgid "GatewayV6" +msgstr "GatewayV6" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:25 +msgid "Grant access to DHCP status display" +msgstr "Consentire la visualizzazione dello stato del DHCP" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:12 +msgid "Grant access to main status display" +msgstr "Consentire la visualizzazione dello stato generale" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:3 +msgid "Grant access to the system route status" +msgstr "Consentire l'accesso allo stato delle route di sistema" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:34 +msgid "Grant access to wireless status display" +msgstr "Consentire la visualizzazione dello stato del wireless" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:30 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:83 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:222 +msgid "Hostname" +msgstr "Nome host" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:31 +msgid "IP Address" +msgstr "Indirizzo IP" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:195 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:114 +msgid "IPv4" +msgstr "IPv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:174 +msgid "IPv4 Internet" +msgstr "IPv4 Internet" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:241 +msgid "IPv6" +msgstr "IPv6" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:214 +msgid "IPv6 Internet" +msgstr "IPv6 Internet" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:235 +msgid "IPv6 prefix" +msgstr "Prefisso IPv6" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "Internet" +msgstr "Internet" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:298 +msgid "Kernel Version" +msgstr "Versione del Kernel" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:293 +msgid "Local Time" +msgstr "Data/ora locale" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:32 +msgid "MAC" +msgstr "MAC" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:119 +msgid "Mac" +msgstr "Mac" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:177 +msgid "Mbit/s" +msgstr "Mbit/s" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:303 +msgid "Model" +msgstr "Modello" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:153 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:160 +msgid "Not connected" +msgstr "Non connesso" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:189 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:229 +msgid "Protocol" +msgstr "Protocollo" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:157 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:228 +msgid "SSID" +msgstr "SSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:85 +msgid "Signal" +msgstr "Segnale" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "System" +msgstr "SIstema" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Up." +msgstr "In funzione." + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:124 +msgid "Upload" +msgstr "Carica" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:183 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:223 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:288 +msgid "Uptime" +msgstr "Tempo di attività" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:9 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:84 +msgid "Wireless" +msgstr "Wireless" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "no" +msgstr "no" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "yes" +msgstr "sì" + +#~ msgid "Connected since" +#~ msgstr "Connesso da" diff --git a/luci-mod-dashboard/po/ja/dashboard.po b/luci-mod-dashboard/po/ja/dashboard.po new file mode 100644 index 000000000..d451b876f --- /dev/null +++ b/luci-mod-dashboard/po/ja/dashboard.po @@ -0,0 +1,222 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"PO-Revision-Date: 2021-06-11 06:32+0000\n" +"Last-Translator: Satoru Yoshida \n" +"Language-Team: Japanese \n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Weblate 4.7-dev\n" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:163 +msgid "Active" +msgstr "アクティブ" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:308 +msgid "Architecture" +msgstr "アーキテクチャ" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:181 +msgid "BSSID" +msgstr "BSSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:175 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:243 +msgid "Bitrate" +msgstr "ビットレート" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:169 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:234 +msgid "Channel" +msgstr "チャンネル" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:177 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:217 +msgid "Connected" +msgstr "接続中" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:13 +msgid "DHCP Devices" +msgstr "DHCP デバイス" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:207 +msgid "DNSv4" +msgstr "DNS (v4)" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:253 +msgid "DNSv6" +msgstr "DNS (v6)" + +#: modules/luci-mod-dashboard/root/usr/share/luci/menu.d/luci-mod-dashboard.json:3 +msgid "Dashboard" +msgstr "ダッシュボード" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:134 +msgid "Devices" +msgstr "デバイス" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:193 +msgid "Devices Connected" +msgstr "接続中のデバイス" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Down." +msgstr "ダウン" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:129 +msgid "Download" +msgstr "ダウンロード" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:187 +msgid "Encryption" +msgstr "暗号化" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:313 +msgid "Firmware Version" +msgstr "ファームウェア バージョン" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:171 +msgid "GHz" +msgstr "GHz" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:201 +msgid "GatewayV4" +msgstr "ゲートウェイ (v4)" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:247 +msgid "GatewayV6" +msgstr "ゲートウェイ (v6)" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:25 +msgid "Grant access to DHCP status display" +msgstr "DHCPステータス表示へのアクセスを許可" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:12 +msgid "Grant access to main status display" +msgstr "メインステータス表示へのアクセスを許可" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:3 +msgid "Grant access to the system route status" +msgstr "システムルートステータスへのアクセスを許可" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:34 +msgid "Grant access to wireless status display" +msgstr "無線ステータス表示へのアクセスを許可" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:30 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:83 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:222 +msgid "Hostname" +msgstr "ホスト名" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:31 +msgid "IP Address" +msgstr "IP アドレス" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:195 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:114 +msgid "IPv4" +msgstr "IPv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:174 +msgid "IPv4 Internet" +msgstr "IPv4 インターネット" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:241 +msgid "IPv6" +msgstr "IPv6" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:214 +msgid "IPv6 Internet" +msgstr "IPv6 インターネット" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:235 +msgid "IPv6 prefix" +msgstr "IPv6 プレフィックス" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "Internet" +msgstr "インターネット" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:298 +msgid "Kernel Version" +msgstr "カーネル バージョン" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:293 +msgid "Local Time" +msgstr "時刻" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:32 +msgid "MAC" +msgstr "MAC" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:119 +msgid "Mac" +msgstr "MAC" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:177 +msgid "Mbit/s" +msgstr "Mbps" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:303 +msgid "Model" +msgstr "モデル" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:153 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:160 +msgid "Not connected" +msgstr "未接続" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:189 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:229 +msgid "Protocol" +msgstr "プロトコル" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:157 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:228 +msgid "SSID" +msgstr "SSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:85 +msgid "Signal" +msgstr "信号強度" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "System" +msgstr "システム" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Up." +msgstr "アップ" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:124 +msgid "Upload" +msgstr "アップロード" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:183 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:223 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:288 +msgid "Uptime" +msgstr "稼働時間" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:9 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:84 +msgid "Wireless" +msgstr "無線" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "no" +msgstr "いいえ" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "yes" +msgstr "はい" + +#~ msgid "Connected since" +#~ msgstr "接続時間" diff --git a/luci-mod-dashboard/po/ko/dashboard.po b/luci-mod-dashboard/po/ko/dashboard.po new file mode 100644 index 000000000..0b968c298 --- /dev/null +++ b/luci-mod-dashboard/po/ko/dashboard.po @@ -0,0 +1,219 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"PO-Revision-Date: 2023-01-10 10:50+0000\n" +"Last-Translator: TheNoFace \n" +"Language-Team: Korean \n" +"Language: ko\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Weblate 4.15.1-dev\n" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:163 +msgid "Active" +msgstr "활성화" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:308 +msgid "Architecture" +msgstr "아키텍처" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:181 +msgid "BSSID" +msgstr "BSSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:175 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:243 +msgid "Bitrate" +msgstr "비트레이트" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:169 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:234 +msgid "Channel" +msgstr "채널" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:177 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:217 +msgid "Connected" +msgstr "연결됨" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:13 +msgid "DHCP Devices" +msgstr "DHCP 장치" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:207 +msgid "DNSv4" +msgstr "DNSv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:253 +msgid "DNSv6" +msgstr "DNSv6" + +#: modules/luci-mod-dashboard/root/usr/share/luci/menu.d/luci-mod-dashboard.json:3 +msgid "Dashboard" +msgstr "대시보드" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:134 +msgid "Devices" +msgstr "장치" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:193 +msgid "Devices Connected" +msgstr "연결된 장치" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Down." +msgstr "다운." + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:129 +msgid "Download" +msgstr "다운로드" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:187 +msgid "Encryption" +msgstr "암호화" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:313 +msgid "Firmware Version" +msgstr "펌웨어 버전" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:171 +msgid "GHz" +msgstr "GHz" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:201 +msgid "GatewayV4" +msgstr "게이트웨이 IPv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:247 +msgid "GatewayV6" +msgstr "게이트웨이 IPv6" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:25 +msgid "Grant access to DHCP status display" +msgstr "DHCP 상태 표시 접근을 허가합니다" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:12 +msgid "Grant access to main status display" +msgstr "기본 상태 표시 접근을 허가합니다" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:3 +msgid "Grant access to the system route status" +msgstr "시스템 라우트 상태 접근을 허가합니다" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:34 +msgid "Grant access to wireless status display" +msgstr "무선 상태 표시 접근을 허가합니다" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:30 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:83 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:222 +msgid "Hostname" +msgstr "호스트명" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:31 +msgid "IP Address" +msgstr "IP 주소" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:195 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:114 +msgid "IPv4" +msgstr "IPv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:174 +msgid "IPv4 Internet" +msgstr "IPv4 인터넷" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:241 +msgid "IPv6" +msgstr "IPv6" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:214 +msgid "IPv6 Internet" +msgstr "IPv6 인터넷" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:235 +msgid "IPv6 prefix" +msgstr "IPv6 접두사" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "Internet" +msgstr "인터넷" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:298 +msgid "Kernel Version" +msgstr "커널 버전" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:293 +msgid "Local Time" +msgstr "로컬 시간" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:32 +msgid "MAC" +msgstr "MAC" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:119 +msgid "Mac" +msgstr "MAC" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:177 +msgid "Mbit/s" +msgstr "Mbit/s" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:303 +msgid "Model" +msgstr "모델" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:153 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:160 +msgid "Not connected" +msgstr "연결되지 않음" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:189 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:229 +msgid "Protocol" +msgstr "프로토콜" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:157 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:228 +msgid "SSID" +msgstr "SSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:85 +msgid "Signal" +msgstr "시그널" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "System" +msgstr "시스템" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Up." +msgstr "업." + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:124 +msgid "Upload" +msgstr "업로드" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:183 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:223 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:288 +msgid "Uptime" +msgstr "가동시간" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:9 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:84 +msgid "Wireless" +msgstr "무선" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "no" +msgstr "아니오" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "yes" +msgstr "예" diff --git a/luci-mod-dashboard/po/mr/dashboard.po b/luci-mod-dashboard/po/mr/dashboard.po new file mode 100644 index 000000000..149c99b6a --- /dev/null +++ b/luci-mod-dashboard/po/mr/dashboard.po @@ -0,0 +1,215 @@ +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" +"Project-Id-Version: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: mr\n" +"MIME-Version: 1.0\n" +"Content-Transfer-Encoding: 8bit\n" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:163 +msgid "Active" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:308 +msgid "Architecture" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:181 +msgid "BSSID" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:175 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:243 +msgid "Bitrate" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:169 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:234 +msgid "Channel" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:177 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:217 +msgid "Connected" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:13 +msgid "DHCP Devices" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:207 +msgid "DNSv4" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:253 +msgid "DNSv6" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/luci/menu.d/luci-mod-dashboard.json:3 +msgid "Dashboard" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:134 +msgid "Devices" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:193 +msgid "Devices Connected" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Down." +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:129 +msgid "Download" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:187 +msgid "Encryption" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:313 +msgid "Firmware Version" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:171 +msgid "GHz" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:201 +msgid "GatewayV4" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:247 +msgid "GatewayV6" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:25 +msgid "Grant access to DHCP status display" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:12 +msgid "Grant access to main status display" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:3 +msgid "Grant access to the system route status" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:34 +msgid "Grant access to wireless status display" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:30 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:83 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:222 +msgid "Hostname" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:31 +msgid "IP Address" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:195 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:114 +msgid "IPv4" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:174 +msgid "IPv4 Internet" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:241 +msgid "IPv6" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:214 +msgid "IPv6 Internet" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:235 +msgid "IPv6 prefix" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "Internet" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:298 +msgid "Kernel Version" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:293 +msgid "Local Time" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:32 +msgid "MAC" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:119 +msgid "Mac" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:177 +msgid "Mbit/s" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:303 +msgid "Model" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:153 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:160 +msgid "Not connected" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:189 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:229 +msgid "Protocol" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:157 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:228 +msgid "SSID" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:85 +msgid "Signal" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "System" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Up." +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:124 +msgid "Upload" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:183 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:223 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:288 +msgid "Uptime" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:9 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:84 +msgid "Wireless" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "no" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "yes" +msgstr "" diff --git a/luci-mod-dashboard/po/ms/dashboard.po b/luci-mod-dashboard/po/ms/dashboard.po new file mode 100644 index 000000000..bf5fa329a --- /dev/null +++ b/luci-mod-dashboard/po/ms/dashboard.po @@ -0,0 +1,215 @@ +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" +"Project-Id-Version: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: ms\n" +"MIME-Version: 1.0\n" +"Content-Transfer-Encoding: 8bit\n" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:163 +msgid "Active" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:308 +msgid "Architecture" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:181 +msgid "BSSID" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:175 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:243 +msgid "Bitrate" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:169 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:234 +msgid "Channel" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:177 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:217 +msgid "Connected" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:13 +msgid "DHCP Devices" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:207 +msgid "DNSv4" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:253 +msgid "DNSv6" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/luci/menu.d/luci-mod-dashboard.json:3 +msgid "Dashboard" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:134 +msgid "Devices" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:193 +msgid "Devices Connected" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Down." +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:129 +msgid "Download" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:187 +msgid "Encryption" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:313 +msgid "Firmware Version" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:171 +msgid "GHz" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:201 +msgid "GatewayV4" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:247 +msgid "GatewayV6" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:25 +msgid "Grant access to DHCP status display" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:12 +msgid "Grant access to main status display" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:3 +msgid "Grant access to the system route status" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:34 +msgid "Grant access to wireless status display" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:30 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:83 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:222 +msgid "Hostname" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:31 +msgid "IP Address" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:195 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:114 +msgid "IPv4" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:174 +msgid "IPv4 Internet" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:241 +msgid "IPv6" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:214 +msgid "IPv6 Internet" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:235 +msgid "IPv6 prefix" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "Internet" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:298 +msgid "Kernel Version" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:293 +msgid "Local Time" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:32 +msgid "MAC" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:119 +msgid "Mac" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:177 +msgid "Mbit/s" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:303 +msgid "Model" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:153 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:160 +msgid "Not connected" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:189 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:229 +msgid "Protocol" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:157 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:228 +msgid "SSID" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:85 +msgid "Signal" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "System" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Up." +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:124 +msgid "Upload" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:183 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:223 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:288 +msgid "Uptime" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:9 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:84 +msgid "Wireless" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "no" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "yes" +msgstr "" diff --git a/luci-mod-dashboard/po/nb_NO/dashboard.po b/luci-mod-dashboard/po/nb_NO/dashboard.po new file mode 100644 index 000000000..724152ae0 --- /dev/null +++ b/luci-mod-dashboard/po/nb_NO/dashboard.po @@ -0,0 +1,230 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"PO-Revision-Date: 2022-11-08 00:12+0000\n" +"Last-Translator: Allan Nordhøy \n" +"Language-Team: Norwegian Bokmål \n" +"Language: nb_NO\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.14.2\n" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:163 +#, fuzzy +msgid "Active" +msgstr "Aktiv" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:308 +msgid "Architecture" +msgstr "Arkitektur" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:181 +msgid "BSSID" +msgstr "BSSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:175 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:243 +msgid "Bitrate" +msgstr "Bitrate" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:169 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:234 +msgid "Channel" +msgstr "Kanal" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:177 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:217 +msgid "Connected" +msgstr "Tilkoblet" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:13 +msgid "DHCP Devices" +msgstr "DHCP-enheter" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:207 +msgid "DNSv4" +msgstr "DNSv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:253 +msgid "DNSv6" +msgstr "DNSv6" + +#: modules/luci-mod-dashboard/root/usr/share/luci/menu.d/luci-mod-dashboard.json:3 +msgid "Dashboard" +msgstr "Oversikt" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:134 +msgid "Devices" +msgstr "Enheter" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:193 +#, fuzzy +msgid "Devices Connected" +msgstr "Tilkoblede enheter" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Down." +msgstr "Nede." + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:129 +msgid "Download" +msgstr "Last ned" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:187 +msgid "Encryption" +msgstr "Kryptering" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:313 +msgid "Firmware Version" +msgstr "Fastvareversjon" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:171 +msgid "GHz" +msgstr "GHz" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:201 +#, fuzzy +msgid "GatewayV4" +msgstr "GatewayV4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:247 +#, fuzzy +msgid "GatewayV6" +msgstr "GatewayV6" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:25 +msgid "Grant access to DHCP status display" +msgstr "Innvilg tilgang til DHCP-statusskjerm" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:12 +msgid "Grant access to main status display" +msgstr "Innvilg tilgang til hovedstatusskjerm" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:3 +msgid "Grant access to the system route status" +msgstr "Innvilg tilgang til systemrutestatus" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:34 +msgid "Grant access to wireless status display" +msgstr "Innvilg tilgang til trådløs statusskjerm" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:30 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:83 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:222 +msgid "Hostname" +msgstr "Vertsnavn" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:31 +msgid "IP Address" +msgstr "IP-adresse" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:195 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:114 +msgid "IPv4" +msgstr "IPv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:174 +msgid "IPv4 Internet" +msgstr "IPv4-Internett" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:241 +msgid "IPv6" +msgstr "IPv6" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:214 +msgid "IPv6 Internet" +msgstr "IPv6-Internett" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:235 +msgid "IPv6 prefix" +msgstr "IPv6-prefiks" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "Internet" +msgstr "Internett" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:298 +msgid "Kernel Version" +msgstr "Kjerneversjon" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:293 +msgid "Local Time" +msgstr "Lokal tid" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:32 +msgid "MAC" +msgstr "MAC" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:119 +#, fuzzy +msgid "Mac" +msgstr "MAC" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:177 +msgid "Mbit/s" +msgstr "Mbit/s" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:303 +msgid "Model" +msgstr "Modell" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:153 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:160 +msgid "Not connected" +msgstr "Ikke tilkoblet" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:189 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:229 +msgid "Protocol" +msgstr "Protokoll" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:157 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:228 +msgid "SSID" +msgstr "SSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:85 +msgid "Signal" +msgstr "Signal" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "System" +msgstr "System" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +#, fuzzy +msgid "Up." +msgstr "Oppe." + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:124 +#, fuzzy +msgid "Upload" +msgstr "Last opp" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:183 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:223 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:288 +msgid "Uptime" +msgstr "Oppetid" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:9 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:84 +#, fuzzy +msgid "Wireless" +msgstr "Trådløst" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "no" +msgstr "nei" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "yes" +msgstr "ja" + +#~ msgid "Connected since" +#~ msgstr "Tilkoblet siden" diff --git a/luci-mod-dashboard/po/nl/dashboard.po b/luci-mod-dashboard/po/nl/dashboard.po new file mode 100644 index 000000000..6b516f9d8 --- /dev/null +++ b/luci-mod-dashboard/po/nl/dashboard.po @@ -0,0 +1,219 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"PO-Revision-Date: 2023-06-11 03:31+0000\n" +"Last-Translator: xtz1983 \n" +"Language-Team: Dutch \n" +"Language: nl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.18-dev\n" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:163 +msgid "Active" +msgstr "Actief" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:308 +msgid "Architecture" +msgstr "Architectuur" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:181 +msgid "BSSID" +msgstr "BSSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:175 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:243 +msgid "Bitrate" +msgstr "Bitrate" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:169 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:234 +msgid "Channel" +msgstr "Kanaal" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:177 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:217 +msgid "Connected" +msgstr "Verbonden" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:13 +msgid "DHCP Devices" +msgstr "DHCP Apparaten" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:207 +msgid "DNSv4" +msgstr "DNSv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:253 +msgid "DNSv6" +msgstr "DNSv6" + +#: modules/luci-mod-dashboard/root/usr/share/luci/menu.d/luci-mod-dashboard.json:3 +msgid "Dashboard" +msgstr "Dashboard" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:134 +msgid "Devices" +msgstr "Apparaten" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:193 +msgid "Devices Connected" +msgstr "Verbonden Apparaten" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Down." +msgstr "Uitgeschakeld." + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:129 +msgid "Download" +msgstr "Download" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:187 +msgid "Encryption" +msgstr "Versleuteling" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:313 +msgid "Firmware Version" +msgstr "Firmware Versie" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:171 +msgid "GHz" +msgstr "GHz" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:201 +msgid "GatewayV4" +msgstr "GatewayV4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:247 +msgid "GatewayV6" +msgstr "GatewayV6" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:25 +msgid "Grant access to DHCP status display" +msgstr "Toegang verlenen tot weergave van DHCP-status" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:12 +msgid "Grant access to main status display" +msgstr "Toegang verlenen tot hoofdstatusweergave" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:3 +msgid "Grant access to the system route status" +msgstr "Toegang verlenen tot de status van het systeemrouteringsproces" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:34 +msgid "Grant access to wireless status display" +msgstr "Toegang verlenen tot weergave van draadloze status" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:30 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:83 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:222 +msgid "Hostname" +msgstr "Hostnaam" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:31 +msgid "IP Address" +msgstr "IP Adres" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:195 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:114 +msgid "IPv4" +msgstr "IPv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:174 +msgid "IPv4 Internet" +msgstr "IPv4 Internet" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:241 +msgid "IPv6" +msgstr "IPv6" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:214 +msgid "IPv6 Internet" +msgstr "IPv6 Internet" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:235 +msgid "IPv6 prefix" +msgstr "IPv6 prefix" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "Internet" +msgstr "Internet" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:298 +msgid "Kernel Version" +msgstr "Kernel Versie" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:293 +msgid "Local Time" +msgstr "Lokale tijd" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:32 +msgid "MAC" +msgstr "MAC" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:119 +msgid "Mac" +msgstr "Mac" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:177 +msgid "Mbit/s" +msgstr "Mbit/s" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:303 +msgid "Model" +msgstr "Model" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:153 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:160 +msgid "Not connected" +msgstr "Geen verbinding" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:189 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:229 +msgid "Protocol" +msgstr "Protocol" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:157 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:228 +msgid "SSID" +msgstr "SSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:85 +msgid "Signal" +msgstr "Signaal" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "System" +msgstr "Systeem" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Up." +msgstr "Boven." + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:124 +msgid "Upload" +msgstr "Uploaden" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:183 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:223 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:288 +msgid "Uptime" +msgstr "Bedrijfstijd" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:9 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:84 +msgid "Wireless" +msgstr "Draadloos" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "no" +msgstr "nee" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "yes" +msgstr "ja" diff --git a/luci-mod-dashboard/po/pl/dashboard.po b/luci-mod-dashboard/po/pl/dashboard.po new file mode 100644 index 000000000..91c205b75 --- /dev/null +++ b/luci-mod-dashboard/po/pl/dashboard.po @@ -0,0 +1,223 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"PO-Revision-Date: 2023-06-03 11:51+0000\n" +"Last-Translator: Matthaiks \n" +"Language-Team: Polish \n" +"Language: pl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " +"|| n%100>=20) ? 1 : 2;\n" +"X-Generator: Weblate 4.18-dev\n" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:163 +msgid "Active" +msgstr "Aktywny" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:308 +msgid "Architecture" +msgstr "Architektura" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:181 +msgid "BSSID" +msgstr "BSSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:175 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:243 +msgid "Bitrate" +msgstr "Szybkość transmisji" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:169 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:234 +msgid "Channel" +msgstr "Kanał" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:177 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:217 +msgid "Connected" +msgstr "Połączony" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:13 +msgid "DHCP Devices" +msgstr "Urządzenia DHCP" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:207 +msgid "DNSv4" +msgstr "DNSv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:253 +msgid "DNSv6" +msgstr "DNSv6" + +#: modules/luci-mod-dashboard/root/usr/share/luci/menu.d/luci-mod-dashboard.json:3 +msgid "Dashboard" +msgstr "Info" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:134 +msgid "Devices" +msgstr "Urządzenia" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:193 +msgid "Devices Connected" +msgstr "Podłączone urządzenia" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Down." +msgstr "Pobieranie" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:129 +msgid "Download" +msgstr "Pobierz" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:187 +msgid "Encryption" +msgstr "Szyfrowanie" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:313 +msgid "Firmware Version" +msgstr "Wersja firmware" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:171 +msgid "GHz" +msgstr "GHz" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:201 +msgid "GatewayV4" +msgstr "BramaV4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:247 +msgid "GatewayV6" +msgstr "BramaV6" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:25 +msgid "Grant access to DHCP status display" +msgstr "Udziel dostępu do wyświetlania statusu DHCP" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:12 +msgid "Grant access to main status display" +msgstr "Udziel dostępu do głównego wyświetlacza stanu" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:3 +msgid "Grant access to the system route status" +msgstr "Udziel dostępu do statusu systemowych tras" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:34 +msgid "Grant access to wireless status display" +msgstr "Udziel dostępu do wyświetlania statusu sieci bezprzewodowej" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:30 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:83 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:222 +msgid "Hostname" +msgstr "Nazwa hosta" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:31 +msgid "IP Address" +msgstr "Adres IP" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:195 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:114 +msgid "IPv4" +msgstr "IPv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:174 +msgid "IPv4 Internet" +msgstr "Internet IPv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:241 +msgid "IPv6" +msgstr "IPv6" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:214 +msgid "IPv6 Internet" +msgstr "Internet IPv6" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:235 +msgid "IPv6 prefix" +msgstr "Prefiks IPv6" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "Internet" +msgstr "Internet" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:298 +msgid "Kernel Version" +msgstr "Wersja kernela" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:293 +msgid "Local Time" +msgstr "Czas lokalny" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:32 +msgid "MAC" +msgstr "MAC" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:119 +msgid "Mac" +msgstr "Mac" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:177 +msgid "Mbit/s" +msgstr "Mbit/s" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:303 +msgid "Model" +msgstr "Model" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:153 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:160 +msgid "Not connected" +msgstr "Nie podłączony" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:189 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:229 +msgid "Protocol" +msgstr "Protokół" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:157 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:228 +msgid "SSID" +msgstr "SSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:85 +msgid "Signal" +msgstr "Sygnał" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "System" +msgstr "System" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Up." +msgstr "Wysyłanie" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:124 +msgid "Upload" +msgstr "Wysyłanie" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:183 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:223 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:288 +msgid "Uptime" +msgstr "Czas pracy" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:9 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:84 +msgid "Wireless" +msgstr "Sieć bezprzewodowa" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "no" +msgstr "nie" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "yes" +msgstr "tak" + +#~ msgid "Connected since" +#~ msgstr "Czas połączenia" diff --git a/luci-mod-dashboard/po/pt/dashboard.po b/luci-mod-dashboard/po/pt/dashboard.po new file mode 100644 index 000000000..5e473dda5 --- /dev/null +++ b/luci-mod-dashboard/po/pt/dashboard.po @@ -0,0 +1,222 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"PO-Revision-Date: 2022-11-30 14:48+0000\n" +"Last-Translator: Gonçalo Pereira \n" +"Language-Team: Portuguese \n" +"Language: pt\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.15-dev\n" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:163 +msgid "Active" +msgstr "Ativo" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:308 +msgid "Architecture" +msgstr "Arquitectura" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:181 +msgid "BSSID" +msgstr "BSSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:175 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:243 +msgid "Bitrate" +msgstr "Taxa de bits" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:169 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:234 +msgid "Channel" +msgstr "Canal" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:177 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:217 +msgid "Connected" +msgstr "Ligado" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:13 +msgid "DHCP Devices" +msgstr "Dispositivos DHCP" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:207 +msgid "DNSv4" +msgstr "DNSv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:253 +msgid "DNSv6" +msgstr "DNSv6" + +#: modules/luci-mod-dashboard/root/usr/share/luci/menu.d/luci-mod-dashboard.json:3 +msgid "Dashboard" +msgstr "Painel de Controlo" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:134 +msgid "Devices" +msgstr "Dispositivos" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:193 +msgid "Devices Connected" +msgstr "Dispositivos ligados" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Down." +msgstr "Em Baixo." + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:129 +msgid "Download" +msgstr "Descarregar" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:187 +msgid "Encryption" +msgstr "Encriptação" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:313 +msgid "Firmware Version" +msgstr "Versão do firmware" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:171 +msgid "GHz" +msgstr "GHz" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:201 +msgid "GatewayV4" +msgstr "GatewayV4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:247 +msgid "GatewayV6" +msgstr "GatewayV6" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:25 +msgid "Grant access to DHCP status display" +msgstr "Conceder acesso à visualização do estado do DHCP" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:12 +msgid "Grant access to main status display" +msgstr "Conceder acesso à visualização do estado principal" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:3 +msgid "Grant access to the system route status" +msgstr "Conceder acesso ao estado da rota do sistema" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:34 +msgid "Grant access to wireless status display" +msgstr "Conceda acesso à visualização da condição do wireless" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:30 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:83 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:222 +msgid "Hostname" +msgstr "Nome do equipamento" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:31 +msgid "IP Address" +msgstr "Endereço IP" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:195 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:114 +msgid "IPv4" +msgstr "IPv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:174 +msgid "IPv4 Internet" +msgstr "Internet IPv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:241 +msgid "IPv6" +msgstr "IPv6" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:214 +msgid "IPv6 Internet" +msgstr "Internet IPv6" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:235 +msgid "IPv6 prefix" +msgstr "Prefixo IPv6" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "Internet" +msgstr "Internet" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:298 +msgid "Kernel Version" +msgstr "Versão do kernel" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:293 +msgid "Local Time" +msgstr "Hora local" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:32 +msgid "MAC" +msgstr "MAC" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:119 +msgid "Mac" +msgstr "Mac" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:177 +msgid "Mbit/s" +msgstr "Mbit/s" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:303 +msgid "Model" +msgstr "Modelo" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:153 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:160 +msgid "Not connected" +msgstr "Não conectado" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:189 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:229 +msgid "Protocol" +msgstr "Protocolo" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:157 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:228 +msgid "SSID" +msgstr "SSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:85 +msgid "Signal" +msgstr "Sinal" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "System" +msgstr "Sistema" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Up." +msgstr "Ativo." + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:124 +msgid "Upload" +msgstr "Enviar" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:183 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:223 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:288 +msgid "Uptime" +msgstr "Tempo de atividade" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:9 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:84 +msgid "Wireless" +msgstr "Rede sem fios" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "no" +msgstr "não" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "yes" +msgstr "sim" + +#~ msgid "Connected since" +#~ msgstr "Ligado desde" diff --git a/luci-mod-dashboard/po/pt_BR/dashboard.po b/luci-mod-dashboard/po/pt_BR/dashboard.po new file mode 100644 index 000000000..95d523512 --- /dev/null +++ b/luci-mod-dashboard/po/pt_BR/dashboard.po @@ -0,0 +1,222 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"PO-Revision-Date: 2023-06-05 03:51+0000\n" +"Last-Translator: Wellington Terumi Uemura \n" +"Language-Team: Portuguese (Brazil) \n" +"Language: pt_BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 4.18-dev\n" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:163 +msgid "Active" +msgstr "Ativo" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:308 +msgid "Architecture" +msgstr "Arquitetura" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:181 +msgid "BSSID" +msgstr "BSSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:175 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:243 +msgid "Bitrate" +msgstr "Taxa de bits" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:169 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:234 +msgid "Channel" +msgstr "Canal" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:177 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:217 +msgid "Connected" +msgstr "Conectado" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:13 +msgid "DHCP Devices" +msgstr "Dispositivos DHCP" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:207 +msgid "DNSv4" +msgstr "DNSv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:253 +msgid "DNSv6" +msgstr "DNSv6" + +#: modules/luci-mod-dashboard/root/usr/share/luci/menu.d/luci-mod-dashboard.json:3 +msgid "Dashboard" +msgstr "Painel de Controle" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:134 +msgid "Devices" +msgstr "Dispositivos" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:193 +msgid "Devices Connected" +msgstr "Dispositivos conectados" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Down." +msgstr "Baix." + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:129 +msgid "Download" +msgstr "Baixar" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:187 +msgid "Encryption" +msgstr "Criptografia" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:313 +msgid "Firmware Version" +msgstr "Versão do firmware" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:171 +msgid "GHz" +msgstr "GHz" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:201 +msgid "GatewayV4" +msgstr "GatewayV4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:247 +msgid "GatewayV6" +msgstr "GatewayV6" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:25 +msgid "Grant access to DHCP status display" +msgstr "Conceda acesso à visualização da condição do DHCP" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:12 +msgid "Grant access to main status display" +msgstr "Conceda acesso à exibição do status principal" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:3 +msgid "Grant access to the system route status" +msgstr "Conceda acesso à condição da rota do sistema" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:34 +msgid "Grant access to wireless status display" +msgstr "Conceda acesso à visualização da condição do wireless" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:30 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:83 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:222 +msgid "Hostname" +msgstr "Nome do equipamento" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:31 +msgid "IP Address" +msgstr "Endereço IP" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:195 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:114 +msgid "IPv4" +msgstr "IPv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:174 +msgid "IPv4 Internet" +msgstr "Internet IPv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:241 +msgid "IPv6" +msgstr "IPv6" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:214 +msgid "IPv6 Internet" +msgstr "Internet IPv6" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:235 +msgid "IPv6 prefix" +msgstr "Prefixo IPv6" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "Internet" +msgstr "Internet" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:298 +msgid "Kernel Version" +msgstr "Versão do kernel" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:293 +msgid "Local Time" +msgstr "Hora local" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:32 +msgid "MAC" +msgstr "MAC" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:119 +msgid "Mac" +msgstr "Mac" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:177 +msgid "Mbit/s" +msgstr "Mbit/s" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:303 +msgid "Model" +msgstr "Modelo" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:153 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:160 +msgid "Not connected" +msgstr "Não conectado" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:189 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:229 +msgid "Protocol" +msgstr "Protocolo" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:157 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:228 +msgid "SSID" +msgstr "SSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:85 +msgid "Signal" +msgstr "Sinal" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "System" +msgstr "Sistema" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Up." +msgstr "Envio" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:124 +msgid "Upload" +msgstr "Envio" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:183 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:223 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:288 +msgid "Uptime" +msgstr "Tempo de atividade" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:9 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:84 +msgid "Wireless" +msgstr "Rede sem fio" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "no" +msgstr "não" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "yes" +msgstr "sim" + +#~ msgid "Connected since" +#~ msgstr "Conectado desde" diff --git a/luci-mod-dashboard/po/ro/dashboard.po b/luci-mod-dashboard/po/ro/dashboard.po new file mode 100644 index 000000000..dd777daff --- /dev/null +++ b/luci-mod-dashboard/po/ro/dashboard.po @@ -0,0 +1,223 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"PO-Revision-Date: 2022-11-04 20:04+0000\n" +"Last-Translator: Simona Iacob \n" +"Language-Team: Romanian \n" +"Language: ro\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < " +"20)) ? 1 : 2;\n" +"X-Generator: Weblate 4.14.2-dev\n" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:163 +msgid "Active" +msgstr "Activ" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:308 +msgid "Architecture" +msgstr "Arhitectură" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:181 +msgid "BSSID" +msgstr "BSSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:175 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:243 +msgid "Bitrate" +msgstr "Rata de biți" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:169 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:234 +msgid "Channel" +msgstr "Canal" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:177 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:217 +msgid "Connected" +msgstr "Conectat" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:13 +msgid "DHCP Devices" +msgstr "Dispozitive DHCP" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:207 +msgid "DNSv4" +msgstr "DNSV4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:253 +msgid "DNSv6" +msgstr "DNSv6" + +#: modules/luci-mod-dashboard/root/usr/share/luci/menu.d/luci-mod-dashboard.json:3 +msgid "Dashboard" +msgstr "Tabloul de bord" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:134 +msgid "Devices" +msgstr "Dispozitive" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:193 +msgid "Devices Connected" +msgstr "Dispozitive conectate" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Down." +msgstr "Oprit." + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:129 +msgid "Download" +msgstr "Descărcați" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:187 +msgid "Encryption" +msgstr "Criptare" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:313 +msgid "Firmware Version" +msgstr "Versiunea Firmware-ului" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:171 +msgid "GHz" +msgstr "GHz" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:201 +msgid "GatewayV4" +msgstr "GatewayV4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:247 +msgid "GatewayV6" +msgstr "GatewayV6" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:25 +msgid "Grant access to DHCP status display" +msgstr "Acordați acces la afișarea stării DHCP" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:12 +msgid "Grant access to main status display" +msgstr "Acordați acces la afișarea principală a stării" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:3 +msgid "Grant access to the system route status" +msgstr "Acordați accesul la starea rutei sistemului" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:34 +msgid "Grant access to wireless status display" +msgstr "Acordați acces la afișarea stării wireless" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:30 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:83 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:222 +msgid "Hostname" +msgstr "Numele gazdei ( hostname )" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:31 +msgid "IP Address" +msgstr "Adresa IP" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:195 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:114 +msgid "IPv4" +msgstr "IPv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:174 +msgid "IPv4 Internet" +msgstr "Internet IPv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:241 +msgid "IPv6" +msgstr "IPv6" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:214 +msgid "IPv6 Internet" +msgstr "Internet IPv6" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:235 +msgid "IPv6 prefix" +msgstr "Prefix IPv6" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "Internet" +msgstr "Internet" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:298 +msgid "Kernel Version" +msgstr "Versiunea Kernel-ului" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:293 +msgid "Local Time" +msgstr "Ora locală" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:32 +msgid "MAC" +msgstr "MAC" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:119 +msgid "Mac" +msgstr "Mac" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:177 +msgid "Mbit/s" +msgstr "Mbit/s" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:303 +msgid "Model" +msgstr "Model" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:153 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:160 +msgid "Not connected" +msgstr "Nu este conectat" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:189 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:229 +msgid "Protocol" +msgstr "Protocol" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:157 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:228 +msgid "SSID" +msgstr "SSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:85 +msgid "Signal" +msgstr "Semnal" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "System" +msgstr "Sistem" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Up." +msgstr "Sus." + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:124 +msgid "Upload" +msgstr "Încărcați" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:183 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:223 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:288 +msgid "Uptime" +msgstr "Timp de funcționare" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:9 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:84 +msgid "Wireless" +msgstr "Fără fir" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "no" +msgstr "nu" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "yes" +msgstr "da" + +#~ msgid "Connected since" +#~ msgstr "Conectat de la" diff --git a/luci-mod-dashboard/po/ru/dashboard.po b/luci-mod-dashboard/po/ru/dashboard.po old mode 100755 new mode 100644 index 466e9ab42..77e35af2e --- a/luci-mod-dashboard/po/ru/dashboard.po +++ b/luci-mod-dashboard/po/ru/dashboard.po @@ -1,224 +1,223 @@ msgid "" msgstr "" -"PO-Revision-Date: 2021-06-16 10:51+0000\n" -"Last-Translator: Dmitry Galenko \n" -"Language-Team: Russian \n" +"Project-Id-Version: \n" +"PO-Revision-Date: 2023-04-16 06:28+0000\n" +"Last-Translator: st7105 \n" +"Language-Team: Russian \n" "Language: ru\n" +"MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" -"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 4.6.1\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " +"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"X-Generator: Weblate 4.17-dev\n" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:165 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:163 msgid "Active" -msgstr "Активный" +msgstr "Активно" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:368 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:308 msgid "Architecture" -msgstr "Процессор" +msgstr "Архитектура" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:183 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:181 msgid "BSSID" msgstr "BSSID" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:177 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:245 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:175 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:243 msgid "Bitrate" -msgstr "Скорость" +msgstr "Битрейт" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:171 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:236 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:169 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:234 msgid "Channel" msgstr "Канал" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:277 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:293 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:177 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:217 msgid "Connected" -msgstr "Подключено" +msgstr "Подключен" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:13 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:13 msgid "DHCP Devices" msgstr "Устройства DHCP" -#: luci-mod-dashboard/root/usr/share/luci/menu.d/luci-mod-dashboard.json:3 -msgid "Dashboard" -msgstr "Дашборд" +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:207 +msgid "DNSv4" +msgstr "DNSv4" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:136 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:253 +msgid "DNSv6" +msgstr "DNSv6" + +#: modules/luci-mod-dashboard/root/usr/share/luci/menu.d/luci-mod-dashboard.json:3 +msgid "Dashboard" +msgstr "Информационная панель" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:134 msgid "Devices" msgstr "Устройства" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:195 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:193 msgid "Devices Connected" msgstr "Подключенные устройства" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 msgid "Down." -msgstr "Не работает." +msgstr "Скач." -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:131 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:129 msgid "Download" -msgstr "Получение" +msgstr "Скачать" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:189 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:187 msgid "Encryption" msgstr "Шифрование" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:373 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:313 msgid "Firmware Version" -msgstr "Версия ПО" +msgstr "Версия прошивки" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:173 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:171 msgid "GHz" -msgstr "GHz" +msgstr "ГГц" -#: luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:25 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:201 +msgid "GatewayV4" +msgstr "GatewayV4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:247 +msgid "GatewayV6" +msgstr "GatewayV6" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:25 msgid "Grant access to DHCP status display" -msgstr "Разрешить просмотр информации о DHCP" +msgstr "Предоставить доступ к просмотру состояния DHCP" -#: luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:12 +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:12 msgid "Grant access to main status display" -msgstr "Разрешить просмотр информации основной информации" +msgstr "Предоставить доступ к отображению основного состояния" -#: luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:3 +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:3 msgid "Grant access to the system route status" -msgstr "Разрешить просмотр информации о маршрутах" +msgstr "Предоставить доступ к состоянию системных маршрутов" -#: luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:34 +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:34 msgid "Grant access to wireless status display" -msgstr "Разрешить просмотр информации о беспроводных сетях" +msgstr "Предоставить доступ к просмотру состояния беспроводных сетей" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:30 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:83 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:224 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:30 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:83 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:222 msgid "Hostname" msgstr "Имя хоста" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:31 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:31 msgid "IP Address" msgstr "IP-адрес" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:283 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:116 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:195 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:114 msgid "IPv4" msgstr "IPv4" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:274 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:174 msgid "IPv4 Internet" -msgstr "IPv4 Internet" +msgstr "IPv4 Интернет" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:305 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:241 msgid "IPv6" msgstr "IPv6" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:290 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:214 msgid "IPv6 Internet" -msgstr "IPv6 Internet" +msgstr "IPv6 Интернет" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:299 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:235 msgid "IPv6 prefix" msgstr "Префикс IPv6" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:41 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 msgid "Internet" -msgstr "Internet" +msgstr "Интернет" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:358 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:298 msgid "Kernel Version" msgstr "Версия ядра" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:241 -msgid "Load" -msgstr "Загрузка" - -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:353 -msgid "Load Average" -msgstr "Средняя загрузка" - -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:348 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:293 msgid "Local Time" -msgstr "Время хоста" +msgstr "Время" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:32 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:32 msgid "MAC" msgstr "MAC" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:121 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:119 msgid "Mac" msgstr "Mac" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:179 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:177 msgid "Mbit/s" -msgstr "Mbit/s" +msgstr "Мбит/с" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:363 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:303 msgid "Model" msgstr "Модель" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:195 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:202 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:153 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:160 msgid "Not connected" -msgstr "Не подключено" +msgstr "Не подключен" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:253 -msgid "Proxy traffic" -msgstr "Трафик через прокси" +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:189 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:229 +msgid "Protocol" +msgstr "Протокол" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:159 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:230 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:157 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:228 msgid "SSID" msgstr "SSID" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:232 -msgid "Server" -msgstr "Сервер" - -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:85 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:85 msgid "Signal" msgstr "Сигнал" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:41 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 msgid "System" msgstr "Система" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:265 -msgid "Total traffic" -msgstr "Трафик всего" - -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 msgid "Up." -msgstr "Работает." +msgstr "Загр." -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:126 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:124 msgid "Upload" -msgstr "Отправка" +msgstr "Загрузить" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:247 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:343 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:183 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:223 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:288 msgid "Uptime" -msgstr "Uptime" +msgstr "Время работы" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:259 -msgid "VPN traffic" -msgstr "Трафик VPN" - -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:235 -msgid "Version" -msgstr "Версия" - -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:9 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:84 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:9 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:84 msgid "Wireless" -msgstr "Безпроводной" +msgstr "Беспроводная сеть" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:101 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 msgid "no" msgstr "нет" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:101 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 msgid "yes" msgstr "да" + +#~ msgid "Connected since" +#~ msgstr "Подключено с" diff --git a/luci-mod-dashboard/po/sk/dashboard.po b/luci-mod-dashboard/po/sk/dashboard.po new file mode 100644 index 000000000..2776d0fee --- /dev/null +++ b/luci-mod-dashboard/po/sk/dashboard.po @@ -0,0 +1,219 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"PO-Revision-Date: 2023-06-15 17:44+0000\n" +"Last-Translator: MaycoH \n" +"Language-Team: Slovak \n" +"Language: sk\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" +"X-Generator: Weblate 4.18.1-dev\n" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:163 +msgid "Active" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:308 +msgid "Architecture" +msgstr "Architektúra" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:181 +msgid "BSSID" +msgstr "BSSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:175 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:243 +msgid "Bitrate" +msgstr "Bitová rýchlosť" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:169 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:234 +msgid "Channel" +msgstr "Kanál" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:177 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:217 +msgid "Connected" +msgstr "Pripojené" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:13 +msgid "DHCP Devices" +msgstr "Zariadenia DHCP" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:207 +msgid "DNSv4" +msgstr "DNSv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:253 +msgid "DNSv6" +msgstr "DNSv6" + +#: modules/luci-mod-dashboard/root/usr/share/luci/menu.d/luci-mod-dashboard.json:3 +msgid "Dashboard" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:134 +msgid "Devices" +msgstr "Zariadenia" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:193 +msgid "Devices Connected" +msgstr "Pripojené zariadenia" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Down." +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:129 +msgid "Download" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:187 +msgid "Encryption" +msgstr "Šifrovanie" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:313 +msgid "Firmware Version" +msgstr "Verzia firmvéru" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:171 +msgid "GHz" +msgstr "GHz" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:201 +msgid "GatewayV4" +msgstr "Brána v4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:247 +msgid "GatewayV6" +msgstr "Brána v6" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:25 +msgid "Grant access to DHCP status display" +msgstr "Udeliť prístup k zobrazeniu stavu DHCP" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:12 +msgid "Grant access to main status display" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:3 +msgid "Grant access to the system route status" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:34 +msgid "Grant access to wireless status display" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:30 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:83 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:222 +msgid "Hostname" +msgstr "Názov hostiteľa" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:31 +msgid "IP Address" +msgstr "Adresa IP" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:195 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:114 +msgid "IPv4" +msgstr "IPv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:174 +msgid "IPv4 Internet" +msgstr "Internet IPv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:241 +msgid "IPv6" +msgstr "IPv6" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:214 +msgid "IPv6 Internet" +msgstr "Internet IPv6" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:235 +msgid "IPv6 prefix" +msgstr "IPv6 prefix" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "Internet" +msgstr "Internet" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:298 +msgid "Kernel Version" +msgstr "Verzia jadra" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:293 +msgid "Local Time" +msgstr "Miestny čas" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:32 +msgid "MAC" +msgstr "MAC" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:119 +msgid "Mac" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:177 +msgid "Mbit/s" +msgstr "Mbit/s" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:303 +msgid "Model" +msgstr "Model" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:153 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:160 +msgid "Not connected" +msgstr "Nepripojené" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:189 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:229 +msgid "Protocol" +msgstr "Protokol" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:157 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:228 +msgid "SSID" +msgstr "SSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:85 +msgid "Signal" +msgstr "Signál" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "System" +msgstr "Systém" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Up." +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:124 +msgid "Upload" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:183 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:223 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:288 +msgid "Uptime" +msgstr "Doba spustenia" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:9 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:84 +msgid "Wireless" +msgstr "Bezdrôtová sieť" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "no" +msgstr "nie" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "yes" +msgstr "áno" diff --git a/luci-mod-dashboard/po/sv/dashboard.po b/luci-mod-dashboard/po/sv/dashboard.po new file mode 100644 index 000000000..066437213 --- /dev/null +++ b/luci-mod-dashboard/po/sv/dashboard.po @@ -0,0 +1,222 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"PO-Revision-Date: 2022-12-04 12:08+0000\n" +"Last-Translator: Kristoffer Grundström \n" +"Language-Team: Swedish \n" +"Language: sv\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.15-dev\n" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:163 +msgid "Active" +msgstr "Aktiv" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:308 +msgid "Architecture" +msgstr "Arkitektur" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:181 +msgid "BSSID" +msgstr "BSSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:175 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:243 +msgid "Bitrate" +msgstr "Bithastighet" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:169 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:234 +msgid "Channel" +msgstr "Kanal" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:177 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:217 +msgid "Connected" +msgstr "Ansluten" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:13 +msgid "DHCP Devices" +msgstr "DHCP enheter" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:207 +msgid "DNSv4" +msgstr "DNSv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:253 +msgid "DNSv6" +msgstr "DNSv6" + +#: modules/luci-mod-dashboard/root/usr/share/luci/menu.d/luci-mod-dashboard.json:3 +msgid "Dashboard" +msgstr "Instrumentbräda" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:134 +msgid "Devices" +msgstr "Enheter" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:193 +msgid "Devices Connected" +msgstr "Enheter anslutna" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Down." +msgstr "Ner." + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:129 +msgid "Download" +msgstr "Nedladdning" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:187 +msgid "Encryption" +msgstr "Kryptering" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:313 +msgid "Firmware Version" +msgstr "Firmware Version" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:171 +msgid "GHz" +msgstr "GHz" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:201 +msgid "GatewayV4" +msgstr "GatewayV4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:247 +msgid "GatewayV6" +msgstr "GatewayV6" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:25 +msgid "Grant access to DHCP status display" +msgstr "Ge åtkomst till DHCP-statusvisning" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:12 +msgid "Grant access to main status display" +msgstr "Ge åtkomst till huvudstatusvisning" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:3 +msgid "Grant access to the system route status" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:34 +msgid "Grant access to wireless status display" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:30 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:83 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:222 +msgid "Hostname" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:31 +msgid "IP Address" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:195 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:114 +msgid "IPv4" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:174 +msgid "IPv4 Internet" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:241 +msgid "IPv6" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:214 +msgid "IPv6 Internet" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:235 +msgid "IPv6 prefix" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "Internet" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:298 +msgid "Kernel Version" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:293 +msgid "Local Time" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:32 +msgid "MAC" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:119 +msgid "Mac" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:177 +msgid "Mbit/s" +msgstr "Mbit/s" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:303 +msgid "Model" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:153 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:160 +msgid "Not connected" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:189 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:229 +msgid "Protocol" +msgstr "Protokoll" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:157 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:228 +msgid "SSID" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:85 +msgid "Signal" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "System" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Up." +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:124 +msgid "Upload" +msgstr "Ladda upp" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:183 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:223 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:288 +msgid "Uptime" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:9 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:84 +msgid "Wireless" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "no" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "yes" +msgstr "" + +#~ msgid "Connected since" +#~ msgstr "Ansluten sedan" diff --git a/luci-mod-dashboard/po/templates/dashboard.pot b/luci-mod-dashboard/po/templates/dashboard.pot old mode 100755 new mode 100644 index 018a75101..005ed4014 --- a/luci-mod-dashboard/po/templates/dashboard.pot +++ b/luci-mod-dashboard/po/templates/dashboard.pot @@ -1,214 +1,208 @@ msgid "" msgstr "Content-Type: text/plain; charset=UTF-8" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:165 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:163 msgid "Active" msgstr "" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:368 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:308 msgid "Architecture" msgstr "" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:183 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:181 msgid "BSSID" msgstr "" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:177 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:245 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:175 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:243 msgid "Bitrate" msgstr "" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:171 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:236 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:169 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:234 msgid "Channel" msgstr "" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:277 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:293 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:177 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:217 msgid "Connected" msgstr "" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:13 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:13 msgid "DHCP Devices" msgstr "" -#: luci-mod-dashboard/root/usr/share/luci/menu.d/luci-mod-dashboard.json:3 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:207 +msgid "DNSv4" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:253 +msgid "DNSv6" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/luci/menu.d/luci-mod-dashboard.json:3 msgid "Dashboard" msgstr "" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:136 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:134 msgid "Devices" msgstr "" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:195 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:193 msgid "Devices Connected" msgstr "" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 msgid "Down." msgstr "" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:131 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:129 msgid "Download" msgstr "" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:189 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:187 msgid "Encryption" msgstr "" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:373 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:313 msgid "Firmware Version" msgstr "" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:173 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:171 msgid "GHz" msgstr "" -#: luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:25 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:201 +msgid "GatewayV4" +msgstr "" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:247 +msgid "GatewayV6" +msgstr "" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:25 msgid "Grant access to DHCP status display" msgstr "" -#: luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:12 +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:12 msgid "Grant access to main status display" msgstr "" -#: luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:3 +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:3 msgid "Grant access to the system route status" msgstr "" -#: luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:34 +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:34 msgid "Grant access to wireless status display" msgstr "" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:30 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:83 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:224 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:30 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:83 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:222 msgid "Hostname" msgstr "" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:31 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:31 msgid "IP Address" msgstr "" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:283 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:116 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:195 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:114 msgid "IPv4" msgstr "" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:274 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:174 msgid "IPv4 Internet" msgstr "" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:305 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:241 msgid "IPv6" msgstr "" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:290 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:214 msgid "IPv6 Internet" msgstr "" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:299 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:235 msgid "IPv6 prefix" msgstr "" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:41 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 msgid "Internet" msgstr "" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:358 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:298 msgid "Kernel Version" msgstr "" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:241 -msgid "Load" -msgstr "" - -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:353 -msgid "Load Average" -msgstr "" - -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:348 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:293 msgid "Local Time" msgstr "" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:32 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:32 msgid "MAC" msgstr "" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:121 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:119 msgid "Mac" msgstr "" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:179 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:177 msgid "Mbit/s" msgstr "" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:363 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:303 msgid "Model" msgstr "" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:195 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:202 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:153 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:160 msgid "Not connected" msgstr "" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:253 -msgid "Proxy traffic" +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:189 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:229 +msgid "Protocol" msgstr "" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:159 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:230 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:157 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:228 msgid "SSID" msgstr "" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:232 -msgid "Server" -msgstr "" - -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:85 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:85 msgid "Signal" msgstr "" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:41 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 msgid "System" msgstr "" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:265 -msgid "Total traffic" -msgstr "" - -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 msgid "Up." msgstr "" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:126 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:124 msgid "Upload" msgstr "" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:247 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:343 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:183 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:223 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:288 msgid "Uptime" msgstr "" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:259 -msgid "VPN traffic" -msgstr "" - -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:235 -msgid "Version" -msgstr "" - -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:9 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:84 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:9 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:84 msgid "Wireless" msgstr "" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:101 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 msgid "no" msgstr "" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:101 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 msgid "yes" msgstr "" diff --git a/luci-mod-dashboard/po/tr/dashboard.po b/luci-mod-dashboard/po/tr/dashboard.po new file mode 100644 index 000000000..d9ccc6cea --- /dev/null +++ b/luci-mod-dashboard/po/tr/dashboard.po @@ -0,0 +1,222 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"PO-Revision-Date: 2021-05-11 11:34+0000\n" +"Last-Translator: semih \n" +"Language-Team: Turkish \n" +"Language: tr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.7-dev\n" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:163 +msgid "Active" +msgstr "Etkin" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:308 +msgid "Architecture" +msgstr "Mimari" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:181 +msgid "BSSID" +msgstr "BSSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:175 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:243 +msgid "Bitrate" +msgstr "Bit hızı" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:169 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:234 +msgid "Channel" +msgstr "Kanal" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:177 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:217 +msgid "Connected" +msgstr "Bağlandı" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:13 +msgid "DHCP Devices" +msgstr "DHCP Aygıtları" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:207 +msgid "DNSv4" +msgstr "DNSv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:253 +msgid "DNSv6" +msgstr "DNSv6" + +#: modules/luci-mod-dashboard/root/usr/share/luci/menu.d/luci-mod-dashboard.json:3 +msgid "Dashboard" +msgstr "Denetim Paneli" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:134 +msgid "Devices" +msgstr "Aygıtlar" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:193 +msgid "Devices Connected" +msgstr "Bağlı Aygıtlar" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Down." +msgstr "İnd." + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:129 +msgid "Download" +msgstr "İndir" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:187 +msgid "Encryption" +msgstr "Şifreleme" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:313 +msgid "Firmware Version" +msgstr "Ürün Yazılımı Sürümü" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:171 +msgid "GHz" +msgstr "GHz" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:201 +msgid "GatewayV4" +msgstr "GatewayV4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:247 +msgid "GatewayV6" +msgstr "GatewayV6" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:25 +msgid "Grant access to DHCP status display" +msgstr "DHCP durum ekranına erişim izni verin" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:12 +msgid "Grant access to main status display" +msgstr "Ana durum ekranına erişim izni verin" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:3 +msgid "Grant access to the system route status" +msgstr "Sistem yönlendirme durumuna erişim izni verin" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:34 +msgid "Grant access to wireless status display" +msgstr "Kablosuz durum ekranına erişim izni verin" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:30 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:83 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:222 +msgid "Hostname" +msgstr "Sunucu adı" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:31 +msgid "IP Address" +msgstr "IP Adresi" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:195 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:114 +msgid "IPv4" +msgstr "IPv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:174 +msgid "IPv4 Internet" +msgstr "IPv4 İnternet" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:241 +msgid "IPv6" +msgstr "IPv6" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:214 +msgid "IPv6 Internet" +msgstr "IPv6 İnternet" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:235 +msgid "IPv6 prefix" +msgstr "IPv6 ön eki" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "Internet" +msgstr "İnternet" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:298 +msgid "Kernel Version" +msgstr "Çekirdek Sürümü" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:293 +msgid "Local Time" +msgstr "Yerel Zaman" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:32 +msgid "MAC" +msgstr "MAC" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:119 +msgid "Mac" +msgstr "Mac" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:177 +msgid "Mbit/s" +msgstr "Mbit/s" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:303 +msgid "Model" +msgstr "Model" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:153 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:160 +msgid "Not connected" +msgstr "Bağlı değil" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:189 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:229 +msgid "Protocol" +msgstr "Protokol" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:157 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:228 +msgid "SSID" +msgstr "SSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:85 +msgid "Signal" +msgstr "Sinyal" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "System" +msgstr "Sistem" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Up." +msgstr "Yük." + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:124 +msgid "Upload" +msgstr "Yükleme" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:183 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:223 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:288 +msgid "Uptime" +msgstr "Çalışma süresi" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:9 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:84 +msgid "Wireless" +msgstr "Kablosuz" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "no" +msgstr "hayır" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "yes" +msgstr "evet" + +#~ msgid "Connected since" +#~ msgstr "Şu tarihten beri bağlı" diff --git a/luci-mod-dashboard/po/uk/dashboard.po b/luci-mod-dashboard/po/uk/dashboard.po new file mode 100644 index 000000000..891a136ed --- /dev/null +++ b/luci-mod-dashboard/po/uk/dashboard.po @@ -0,0 +1,223 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"PO-Revision-Date: 2021-11-04 17:37+0000\n" +"Last-Translator: Paul Dee \n" +"Language-Team: Ukrainian \n" +"Language: uk\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"X-Generator: Weblate 4.9-dev\n" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:163 +msgid "Active" +msgstr "Активний" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:308 +msgid "Architecture" +msgstr "Архітектура" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:181 +msgid "BSSID" +msgstr "BSSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:175 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:243 +msgid "Bitrate" +msgstr "Бітрейт" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:169 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:234 +msgid "Channel" +msgstr "Канал" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:177 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:217 +msgid "Connected" +msgstr "Підключений" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:13 +msgid "DHCP Devices" +msgstr "DHCP-пристрої" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:207 +msgid "DNSv4" +msgstr "DNSv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:253 +msgid "DNSv6" +msgstr "DNSv6" + +#: modules/luci-mod-dashboard/root/usr/share/luci/menu.d/luci-mod-dashboard.json:3 +msgid "Dashboard" +msgstr "Панелі" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:134 +msgid "Devices" +msgstr "Пристрої" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:193 +msgid "Devices Connected" +msgstr "Пристрої, підключені" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Down." +msgstr "Вниз." + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:129 +msgid "Download" +msgstr "Завантажити" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:187 +msgid "Encryption" +msgstr "Шифрування" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:313 +msgid "Firmware Version" +msgstr "Версія прошивки" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:171 +msgid "GHz" +msgstr "Ггц" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:201 +msgid "GatewayV4" +msgstr "Шлюз V4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:247 +msgid "GatewayV6" +msgstr "Шлюз v6" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:25 +msgid "Grant access to DHCP status display" +msgstr "Надання доступу до відображення стану DHCP" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:12 +msgid "Grant access to main status display" +msgstr "Надання доступу до основного відображення стану" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:3 +msgid "Grant access to the system route status" +msgstr "Надати доступ до статусу системних маршрутів" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:34 +msgid "Grant access to wireless status display" +msgstr "Надати доступ до відображення статусу бездротових мереж" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:30 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:83 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:222 +msgid "Hostname" +msgstr "Ім'я хоста" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:31 +msgid "IP Address" +msgstr "IP-адреса" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:195 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:114 +msgid "IPv4" +msgstr "IPv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:174 +msgid "IPv4 Internet" +msgstr "Інтернет IPv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:241 +msgid "IPv6" +msgstr "IPv6" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:214 +msgid "IPv6 Internet" +msgstr "Інтернет IPv6" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:235 +msgid "IPv6 prefix" +msgstr "Префікс IPv6" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "Internet" +msgstr "Інтернет" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:298 +msgid "Kernel Version" +msgstr "Версія ядра" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:293 +msgid "Local Time" +msgstr "Місцевий час" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:32 +msgid "MAC" +msgstr "MAC" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:119 +msgid "Mac" +msgstr "Mac" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:177 +msgid "Mbit/s" +msgstr "Мбіт/с" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:303 +msgid "Model" +msgstr "Модель" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:153 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:160 +msgid "Not connected" +msgstr "Не підключено" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:189 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:229 +msgid "Protocol" +msgstr "Протокол" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:157 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:228 +msgid "SSID" +msgstr "SSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:85 +msgid "Signal" +msgstr "Сигнал" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "System" +msgstr "Система" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Up." +msgstr "Вгору." + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:124 +msgid "Upload" +msgstr "Завантажити" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:183 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:223 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:288 +msgid "Uptime" +msgstr "Час безвідмовної роботи" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:9 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:84 +msgid "Wireless" +msgstr "Бездротові мережі" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "no" +msgstr "Ні" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "yes" +msgstr "так" + +#~ msgid "Connected since" +#~ msgstr "Під'єднано з" diff --git a/luci-mod-dashboard/po/vi/dashboard.po b/luci-mod-dashboard/po/vi/dashboard.po new file mode 100644 index 000000000..92aa950e8 --- /dev/null +++ b/luci-mod-dashboard/po/vi/dashboard.po @@ -0,0 +1,219 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"PO-Revision-Date: 2023-06-20 13:52+0000\n" +"Last-Translator: Quy \n" +"Language-Team: Vietnamese \n" +"Language: vi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Weblate 4.18.1\n" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:163 +msgid "Active" +msgstr "Kích hoạt" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:308 +msgid "Architecture" +msgstr "Kiến trúc" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:181 +msgid "BSSID" +msgstr "BSSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:175 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:243 +msgid "Bitrate" +msgstr "Bitrate" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:169 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:234 +msgid "Channel" +msgstr "Kênh" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:177 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:217 +msgid "Connected" +msgstr "Đã kết nối" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:13 +msgid "DHCP Devices" +msgstr "Thiết bị DHCP" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:207 +msgid "DNSv4" +msgstr "DNSv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:253 +msgid "DNSv6" +msgstr "DNSv6" + +#: modules/luci-mod-dashboard/root/usr/share/luci/menu.d/luci-mod-dashboard.json:3 +msgid "Dashboard" +msgstr "Màn hình chính" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:134 +msgid "Devices" +msgstr "Các thiết bị" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:193 +msgid "Devices Connected" +msgstr "Thiết bị đã kết nối" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Down." +msgstr "Sập." + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:129 +msgid "Download" +msgstr "Tải xuống" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:187 +msgid "Encryption" +msgstr "Mã hóa" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:313 +msgid "Firmware Version" +msgstr "Phiên bản firmware" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:171 +msgid "GHz" +msgstr "GHz" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:201 +msgid "GatewayV4" +msgstr "GatewayV4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:247 +msgid "GatewayV6" +msgstr "GatewayV6" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:25 +msgid "Grant access to DHCP status display" +msgstr "Cấp quyền truy cập vào màn hình trạng thái DHCP" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:12 +msgid "Grant access to main status display" +msgstr "Cấp quyền truy cập vào màn hình trạng thái chính" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:3 +msgid "Grant access to the system route status" +msgstr "Cấp quyền truy cập vào trạng thái tuyến đường hệ thống" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:34 +msgid "Grant access to wireless status display" +msgstr "Cấp quyền truy cập vào hiển thị trạng thái không dây" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:30 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:83 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:222 +msgid "Hostname" +msgstr "Tên máy chủ (hostname)" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:31 +msgid "IP Address" +msgstr "Địa chỉ IP" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:195 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:114 +msgid "IPv4" +msgstr "IPv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:174 +msgid "IPv4 Internet" +msgstr "IPv4 Internet" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:241 +msgid "IPv6" +msgstr "IPv6" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:214 +msgid "IPv6 Internet" +msgstr "IPv6 Internet" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:235 +msgid "IPv6 prefix" +msgstr "IPv6 prefix" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "Internet" +msgstr "Internet" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:298 +msgid "Kernel Version" +msgstr "Phiên bản Kernel" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:293 +msgid "Local Time" +msgstr "Giờ địa phương" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:32 +msgid "MAC" +msgstr "MAC" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:119 +msgid "Mac" +msgstr "Mac" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:177 +msgid "Mbit/s" +msgstr "Mbit/s" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:303 +msgid "Model" +msgstr "Model" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:153 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:160 +msgid "Not connected" +msgstr "Không kết nối" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:189 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:229 +msgid "Protocol" +msgstr "Giao thức" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:157 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:228 +msgid "SSID" +msgstr "SSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:85 +msgid "Signal" +msgstr "Tín hiệu" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "System" +msgstr "Hệ thống" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Up." +msgstr "Đã mở." + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:124 +msgid "Upload" +msgstr "Tải lên" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:183 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:223 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:288 +msgid "Uptime" +msgstr "Thời gian hoạt động" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:9 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:84 +msgid "Wireless" +msgstr "Không dây" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "no" +msgstr "Không" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "yes" +msgstr "có" diff --git a/luci-mod-dashboard/po/zh_Hans/dashboard.po b/luci-mod-dashboard/po/zh_Hans/dashboard.po old mode 100755 new mode 100644 index 4da85b2c8..983910c44 --- a/luci-mod-dashboard/po/zh_Hans/dashboard.po +++ b/luci-mod-dashboard/po/zh_Hans/dashboard.po @@ -1,223 +1,220 @@ msgid "" msgstr "" -"PO-Revision-Date: 2021-06-02 09:51+0000\n" -"Last-Translator: antrouter \n" -"Language-Team: Chinese (Simplified) \n" +"PO-Revision-Date: 2022-05-07 19:19+0000\n" +"Last-Translator: 王攀 <41330784@qq.com>\n" +"Language-Team: Chinese (Simplified) \n" "Language: zh_Hans\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 4.6.1\n" +"X-Generator: Weblate 4.12.1\n" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:165 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:163 msgid "Active" -msgstr "激活" +msgstr "活跃" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:368 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:308 msgid "Architecture" -msgstr "构架" +msgstr "架构" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:183 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:181 msgid "BSSID" msgstr "BSSID" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:177 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:245 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:175 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:243 msgid "Bitrate" -msgstr "比特率" +msgstr "速率" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:171 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:236 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:169 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:234 msgid "Channel" -msgstr "频道" +msgstr "信道" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:277 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:293 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:177 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:217 msgid "Connected" -msgstr "连接" +msgstr "已连接" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:13 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:13 msgid "DHCP Devices" msgstr "DHCP 设备" -#: luci-mod-dashboard/root/usr/share/luci/menu.d/luci-mod-dashboard.json:3 -msgid "Dashboard" -msgstr "仪表盘" +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:207 +msgid "DNSv4" +msgstr "DNSv4" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:136 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:253 +msgid "DNSv6" +msgstr "DNSv6" + +#: modules/luci-mod-dashboard/root/usr/share/luci/menu.d/luci-mod-dashboard.json:3 +msgid "Dashboard" +msgstr "概览" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:134 msgid "Devices" msgstr "设备" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:195 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:193 msgid "Devices Connected" -msgstr "连接的设备" +msgstr "已连接设备" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 msgid "Down." -msgstr "下." +msgstr "下行." -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:131 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:129 msgid "Download" msgstr "下载" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:189 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:187 msgid "Encryption" msgstr "加密" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:373 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:313 msgid "Firmware Version" msgstr "固件版本" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:173 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:171 msgid "GHz" -msgstr "Ghz" +msgstr "GHz" -#: luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:25 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:201 +msgid "GatewayV4" +msgstr "IPv4 网关" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:247 +msgid "GatewayV6" +msgstr "IPv6 网关" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:25 msgid "Grant access to DHCP status display" -msgstr "授予访问 DHCP 状态显示的权限" +msgstr "授予访问 DHCP 状态展示的权限" -#: luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:12 +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:12 msgid "Grant access to main status display" -msgstr "授予访问主状态显示的权限" +msgstr "授予访问主状态展示的权限" -#: luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:3 +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:3 msgid "Grant access to the system route status" -msgstr "授予对系统路由状态的访问权限" +msgstr "授予访问系统路由状态的权限" -#: luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:34 +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:34 msgid "Grant access to wireless status display" -msgstr "授予访问无线状态显示的权限" +msgstr "授予访问无线状态展示的权限" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:30 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:83 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:224 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:30 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:83 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:222 msgid "Hostname" msgstr "主机名" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:31 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:31 msgid "IP Address" -msgstr "IP地址" +msgstr "IP 地址" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:283 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:116 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:195 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:114 msgid "IPv4" msgstr "IPv4" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:274 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:174 msgid "IPv4 Internet" -msgstr "IPv4互联网" +msgstr "IPv4 网络" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:305 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:241 msgid "IPv6" msgstr "IPv6" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:290 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:214 msgid "IPv6 Internet" -msgstr "IPv6互联网" +msgstr "IPv6 网络" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:299 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:235 msgid "IPv6 prefix" -msgstr "IPv6前缀" +msgstr "IPv6 前缀" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:41 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 msgid "Internet" msgstr "互联网" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:358 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:298 msgid "Kernel Version" msgstr "内核版本" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:241 -msgid "Load" -msgstr "负载" - -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:353 -msgid "Load Average" -msgstr "平均负载" - -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:348 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:293 msgid "Local Time" msgstr "本地时间" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:32 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:32 msgid "MAC" -msgstr "MAC地址" +msgstr "MAC" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:121 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:119 msgid "Mac" -msgstr "mac地址" +msgstr "Mac" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:179 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:177 msgid "Mbit/s" msgstr "Mbit/s" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:363 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:303 msgid "Model" msgstr "型号" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:195 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:202 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:153 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:160 msgid "Not connected" msgstr "未连接" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:253 -msgid "Proxy traffic" -msgstr "代理流量" +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:189 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:229 +msgid "Protocol" +msgstr "协议" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:159 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:230 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:157 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:228 msgid "SSID" msgstr "SSID" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:232 -msgid "Server" -msgstr "服务器" - -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:85 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:85 msgid "Signal" msgstr "信号" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:41 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 msgid "System" msgstr "系统" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:265 -msgid "Total traffic" -msgstr "总流量" - -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 msgid "Up." -msgstr "上." +msgstr "上行" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:126 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:124 msgid "Upload" msgstr "上传" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:247 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:343 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:183 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:223 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:288 msgid "Uptime" -msgstr "开机时间" +msgstr "运行时间" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:259 -msgid "VPN traffic" -msgstr "VPN流量" - -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:235 -msgid "Version" -msgstr "版本" - -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:9 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:84 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:9 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:84 msgid "Wireless" msgstr "无线" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:101 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 msgid "no" msgstr "否" -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:101 -#: luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 msgid "yes" msgstr "是" + +#~ msgid "Connected since" +#~ msgstr "连接开始时间" diff --git a/luci-mod-dashboard/po/zh_Hant/dashboard.po b/luci-mod-dashboard/po/zh_Hant/dashboard.po new file mode 100644 index 000000000..3135a40d7 --- /dev/null +++ b/luci-mod-dashboard/po/zh_Hant/dashboard.po @@ -0,0 +1,220 @@ +msgid "" +msgstr "" +"PO-Revision-Date: 2022-12-25 07:50+0000\n" +"Last-Translator: Hulen \n" +"Language-Team: Chinese (Traditional) \n" +"Language: zh_Hant\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Weblate 4.15.1-dev\n" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:163 +msgid "Active" +msgstr "已啓用" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:308 +msgid "Architecture" +msgstr "架構" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:181 +msgid "BSSID" +msgstr "BSSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:175 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:243 +msgid "Bitrate" +msgstr "位元率" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:169 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:234 +msgid "Channel" +msgstr "頻道" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:177 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:217 +msgid "Connected" +msgstr "已連線" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:13 +msgid "DHCP Devices" +msgstr "DHCP 裝置" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:207 +msgid "DNSv4" +msgstr "DNSv4" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:253 +msgid "DNSv6" +msgstr "DNSv6" + +#: modules/luci-mod-dashboard/root/usr/share/luci/menu.d/luci-mod-dashboard.json:3 +msgid "Dashboard" +msgstr "儀表板" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:134 +msgid "Devices" +msgstr "裝置" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:193 +msgid "Devices Connected" +msgstr "已連線裝置" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Down." +msgstr "下載." + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:129 +msgid "Download" +msgstr "下載" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:187 +msgid "Encryption" +msgstr "加密(Encryption)" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:313 +msgid "Firmware Version" +msgstr "韌體版本" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:171 +msgid "GHz" +msgstr "GHz" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:201 +msgid "GatewayV4" +msgstr "IPv4 閘道" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:247 +msgid "GatewayV6" +msgstr "IPv6 閘道" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:25 +msgid "Grant access to DHCP status display" +msgstr "授予存取 DHCP 狀態顯示的權限" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:12 +msgid "Grant access to main status display" +msgstr "授予存取主要狀態顯示的權限" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:3 +msgid "Grant access to the system route status" +msgstr "授予存取系統路由狀態的權限" + +#: modules/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json:34 +msgid "Grant access to wireless status display" +msgstr "授予存取無線狀態顯示的權限" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:30 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:83 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:222 +msgid "Hostname" +msgstr "主機名稱" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:31 +msgid "IP Address" +msgstr "IP 位址" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:195 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:114 +msgid "IPv4" +msgstr "IPv4 地址" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:174 +msgid "IPv4 Internet" +msgstr "IPv4 網路" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:241 +msgid "IPv6" +msgstr "IPv6" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:214 +msgid "IPv6 Internet" +msgstr "IPv6 網路" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:235 +msgid "IPv6 prefix" +msgstr "IPv6字首" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "Internet" +msgstr "網際網路" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:298 +msgid "Kernel Version" +msgstr "核心版本" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:293 +msgid "Local Time" +msgstr "本地時間" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:32 +msgid "MAC" +msgstr "MAC" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:119 +msgid "Mac" +msgstr "Mac" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:177 +msgid "Mbit/s" +msgstr "Mbit/s" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:303 +msgid "Model" +msgstr "裝置型號" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:153 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:160 +msgid "Not connected" +msgstr "尚未連線" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:189 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:229 +msgid "Protocol" +msgstr "協定" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:157 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:228 +msgid "SSID" +msgstr "SSID" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:85 +msgid "Signal" +msgstr "訊號" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:33 +msgid "System" +msgstr "系統" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:86 +msgid "Up." +msgstr "上傳" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/20_lan.js:124 +msgid "Upload" +msgstr "上傳" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:183 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:223 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:288 +msgid "Uptime" +msgstr "上線時間" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:9 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:84 +msgid "Wireless" +msgstr "無線" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "no" +msgstr "否" + +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/10_router.js:67 +#: modules/luci-mod-dashboard/htdocs/luci-static/resources/view/dashboard/include/30_wifi.js:65 +msgid "yes" +msgstr "是" + +#~ msgid "Connected since" +#~ msgstr "連線開始時間" diff --git a/luci-mod-dashboard/root/usr/share/luci/menu.d/luci-mod-dashboard.json b/luci-mod-dashboard/root/usr/share/luci/menu.d/luci-mod-dashboard.json old mode 100755 new mode 100644 diff --git a/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json b/luci-mod-dashboard/root/usr/share/rpcd/acl.d/luci-mod-dashboard.json old mode 100755 new mode 100644 diff --git a/luci-mod-network/Makefile b/luci-mod-network/Makefile old mode 100755 new mode 100644 index 6148f98b4..4820ffe28 --- a/luci-mod-network/Makefile +++ b/luci-mod-network/Makefile @@ -1,15 +1,13 @@ # # Copyright (C) 2008-2014 The LuCI Team -# Copyright (C) 2020-2021 Ycarus (Yannick Chabanois) for OpenMPTCProuter # # This is free software, licensed under the Apache License, Version 2.0 . # -# From https://github.com/openwrt/luci/commit/b88157e69a060ade618e48b30947729310935d61 include $(TOPDIR)/rules.mk LUCI_TITLE:=LuCI Network Administration -LUCI_DEPENDS:=+luci-base +libiwinfo-lua +rpcd-mod-iwinfo +LUCI_DEPENDS:=+luci-base +rpcd-mod-iwinfo PKG_LICENSE:=Apache-2.0 diff --git a/luci-mod-network/htdocs/luci-static/resources/tools/network.js b/luci-mod-network/htdocs/luci-static/resources/tools/network.js old mode 100755 new mode 100644 index 6f16713fe..092bbbc14 --- a/luci-mod-network/htdocs/luci-static/resources/tools/network.js +++ b/luci-mod-network/htdocs/luci-static/resources/tools/network.js @@ -1,4 +1,5 @@ 'use strict'; +'require fs'; 'require ui'; 'require dom'; 'require uci'; @@ -149,25 +150,77 @@ function updatePlaceholders(opt, section_id) { } } +var cbiFlagTristate = form.ListValue.extend({ + __init__: function(/* ... */) { + this.super('__init__', arguments); + this.keylist = [ '', '0!', '1!' ]; + this.vallist = [ _('automatic'), _('disabled'), _('enabled') ]; + }, + + load: function(section_id) { + var invert = false, sysfs = this.sysfs; + + if (sysfs) { + if (sysfs.charAt(0) == '!') { + invert = true; + sysfs = sysfs.substring(1); + } + + return L.resolveDefault(fs.read(sysfs), '').then(L.bind(function(res) { + res = (res || '').trim(); + + if (res == '0') + this.sysfs_default = invert; + else if (res == '1') + this.sysfs_default = !invert; + + return this.super('load', [section_id]); + }, this)); + } + + return this.super('load', [section_id]); + }, + + write: function(section_id, formvalue) { + if (formvalue == '1!') + return this.super('write', [section_id, '1']); + else if (formvalue == '0!') + return this.super('write', [section_id, '0']); + else + return this.super('remove', [section_id]); + }, + + renderWidget: function(section_id, option_index, cfgvalue) { + var sysdef = this.sysfs_default; + + if (this.sysfs_default !== null) { + this.keylist[0] = sysdef ? '1' : '0'; + this.vallist[0] = sysdef ? _('automatic (enabled)') : _('automatic (disabled)'); + } + + return this.super('renderWidget', [section_id, option_index, cfgvalue]); + } +}); + var cbiTagValue = form.Value.extend({ renderWidget: function(section_id, option_index, cfgvalue) { var widget = new ui.Dropdown(cfgvalue || ['-'], { '-': E([], [ E('span', { 'class': 'hide-open', 'style': 'font-family:monospace' }, [ '—' ]), - E('span', { 'class': 'hide-close' }, [ _('Do not participate', 'VLAN port state') ]) + E('span', { 'class': 'hide-close' }, [ _('Not Member', 'VLAN port state') ]) ]), 'u': E([], [ - E('span', { 'class': 'hide-open', 'style': 'font-family:monospace' }, [ 'u' ]), - E('span', { 'class': 'hide-close' }, [ _('Egress untagged', 'VLAN port state') ]) + E('span', { 'class': 'hide-open', 'style': 'font-family:monospace' }, [ 'U' ]), + E('span', { 'class': 'hide-close' }, [ _('Untagged', 'VLAN port state') ]) ]), 't': E([], [ - E('span', { 'class': 'hide-open', 'style': 'font-family:monospace' }, [ 't' ]), - E('span', { 'class': 'hide-close' }, [ _('Egress tagged', 'VLAN port state') ]) + E('span', { 'class': 'hide-open', 'style': 'font-family:monospace' }, [ 'T' ]), + E('span', { 'class': 'hide-close' }, [ _('Tagged', 'VLAN port state') ]) ]), '*': E([], [ E('span', { 'class': 'hide-open', 'style': 'font-family:monospace' }, [ '*' ]), - E('span', { 'class': 'hide-close' }, [ _('Primary VLAN ID', 'VLAN port state') ]) + E('span', { 'class': 'hide-close' }, [ _('Is Primary VLAN', 'VLAN port state') ]) ]) }, { id: this.cbid(section_id), @@ -274,7 +327,7 @@ var cbiTagValue = form.Value.extend({ var t = /t/.test(s[1] || '') ? 't' : 'u'; - return /\*/.test(s[1] || '') ? [t, '*'] : [t]; + return /\x2a/.test(s[1] || '') ? [t, '*'] : [t]; } return ['-']; @@ -304,7 +357,7 @@ var cbiTagValue = form.Value.extend({ } } - uci.set('network', section_id, 'ports', ports); + uci.set('network', section_id, 'ports', ports.length ? ports : null); }, remove: function() {} @@ -331,6 +384,7 @@ return baseclass.extend({ addDeviceOptions: function(s, dev, isNew) { var parent_dev = dev ? dev.getParent() : null, + devname = dev ? dev.getName() : null, o, ss; s.tab('devgeneral', _('General device options')); @@ -421,7 +475,7 @@ return baseclass.extend({ vid = this.section.formvalue(section_id, 'vid'), name = this.section.getUIElement(section_id, 'name_complex'); - if (base && vid && name && !name.isChanged()) { + if (base && vid && name && !name.isChanged() && isNew) { name.setValue('%s.%d'.format(base, vid)); name.triggerValidation(); } @@ -619,48 +673,16 @@ return baseclass.extend({ o.placeholder = dev ? dev._devstate('qlen') : ''; o.datatype = 'uinteger'; - o = this.replaceOption(s, 'devadvanced', form.Flag, 'promisc', _('Enable promiscuous mode')); - o.default = o.disabled; - - o = this.replaceOption(s, 'devadvanced', form.Flag, 'autoneg', _('Autonegociation')); - o.default = o.enabled; - - o = this.replaceOption(s, 'devadvanced', form.Flag, 'gro', _('Generic Receive Offload (GRO)')); - o.default = o.enabled; - - o = this.replaceOption(s, 'devadvanced', form.Flag, 'gso', _('Generic Segmentation Offload (GSO)')); - o.default = o.enabled; - - o = this.replaceOption(s, 'devadvanced', form.Flag, 'tso', _('TCP Segmentation Offload (TSO)')); - o.default = o.enabled; - - o = this.replaceOption(s, 'devadvanced', form.Flag, 'lro', _('Large Receive Offload (LRO)')); - o.default = o.enabled; - - o = this.replaceOption(s, 'devadvanced', form.Flag, 'ufo', _('UDP Fragmentation Offload (UFO)')); - o.default = o.enabled; - - o = this.replaceOption(s, 'devadvanced', form.Value, 'speed', _('Speed')); - o.placeholder = dev ? dev.getSpeed() : ''; - o.default = ''; - o.rmempty = true; - o.datatype = 'uinteger'; - o.depends('autoneg', '0'); - - o = this.replaceOption(s, 'devadvanced', form.ListValue, 'duplex', _('Duplex')); - o.default = ''; - o.value('', _('unknown')); - o.value('half', _('half')); - o.value('full', _('full')); - o.depends('autoneg', '0'); + o = this.replaceOption(s, 'devadvanced', cbiFlagTristate, 'promisc', _('Enable promiscuous mode')); + o.sysfs_default = (dev && dev.dev && dev.dev.flags) ? dev.dev.flags.promisc : null; o = this.replaceOption(s, 'devadvanced', form.ListValue, 'rpfilter', _('Reverse path filter')); o.default = ''; o.value('', _('disabled')); o.value('loose', _('Loose filtering')); o.value('strict', _('Strict filtering')); - o.cfgvalue = function(section_id) { - var val = form.ListValue.prototype.cfgvalue.apply(this, [section_id]); + o.cfgvalue = function(/* ... */) { + var val = form.ListValue.prototype.cfgvalue.apply(this, arguments); switch (val || '') { case 'loose': @@ -676,11 +698,17 @@ return baseclass.extend({ } }; - o = this.replaceOption(s, 'devadvanced', form.Flag, 'acceptlocal', _('Accept local'), _('Accept packets with local source addresses')); - o.default = o.disabled; + o = this.replaceOption(s, 'devadvanced', cbiFlagTristate, 'acceptlocal', _('Accept local'), _('Accept packets with local source addresses')); + o.sysfs = '/proc/sys/net/ipv4/conf/%s/accept_local'.format(devname || 'default'); - o = this.replaceOption(s, 'devadvanced', form.Flag, 'sendredirects', _('Send ICMP redirects')); - o.default = o.enabled; + o = this.replaceOption(s, 'devadvanced', cbiFlagTristate, 'sendredirects', _('Send ICMP redirects')); + o.sysfs = '/proc/sys/net/ipv4/conf/%s/send_redirects'.format(devname || 'default'); + + o = this.replaceOption(s, 'devadvanced', cbiFlagTristate, 'arp_accept ', _('Honor gratuitous ARP'), _('When enabled, new ARP table entries are added from received gratuitous APR requests or replies, otherwise only preexisting table entries are updated, but no new hosts are learned.')); + o.sysfs = '/proc/sys/net/ipv4/conf/%s/arp_accept'.format(devname || 'default'); + + o = this.replaceOption(s, 'devadvanced', cbiFlagTristate, 'drop_gratuitous_arp', _('Drop gratuitous ARP'), _('Drop all gratuitous ARP frames, for example if there’s a known good ARP proxy on the network and such frames need not be used or in the case of 802.11, must not be used to prevent attacks.')); + o.sysfs = '/proc/sys/net/ipv4/conf/%s/drop_gratuitous_arp'.format(devname || 'default'); o = this.replaceOption(s, 'devadvanced', form.Value, 'neighreachabletime', _('Neighbour cache validity'), _('Time in milliseconds')); o.placeholder = '30000'; @@ -694,63 +722,75 @@ return baseclass.extend({ o.placeholder = '0'; o.datatype = 'uinteger'; - o = this.replaceOption(s, 'devadvanced', form.Value, 'ttl', _('Force TTL'), _('Some LTE providers detect tethering by inspecting packet TTL values')); - o.placeholder = '65'; - o.datatype = 'uinteger'; - - o = this.replaceOption(s, 'devgeneral', form.Flag, 'ipv6', _('Enable IPv6')); + o = this.replaceOption(s, 'devgeneral', cbiFlagTristate, 'ipv6', _('Enable IPv6')); + o.sysfs = '!/proc/sys/net/ipv6/conf/%s/disable_ipv6'.format(devname || 'default'); o.migrate = false; - o.default = o.enabled; + + o = this.replaceOption(s, 'devadvanced', cbiFlagTristate, 'ip6segmentrouting', _('Enable IPv6 segment routing')); + o.sysfs = '/proc/sys/net/ipv6/conf/%s/seg6_enabled'.format(devname || 'default'); + o.depends('ipv6', /1/); + + o = this.replaceOption(s, 'devadvanced', cbiFlagTristate, 'drop_unsolicited_na', _('Drop unsolicited NA'), _('Drop all unsolicited neighbor advertisements, for example if there’s a known good NA proxy on the network and such frames need not be used or in the case of 802.11, must not be used to prevent attacks.')); + o.sysfs = '/proc/sys/net/ipv6/conf/%s/drop_unsolicited_na'.format(devname || 'default'); + o.depends('ipv6', /1/); o = this.replaceOption(s, 'devgeneral', form.Value, 'mtu6', _('IPv6 MTU')); o.datatype = 'max(9200)'; - o.depends('ipv6', '1'); + o.depends('ipv6', /1/); o = this.replaceOption(s, 'devgeneral', form.Value, 'dadtransmits', _('DAD transmits'), _('Amount of Duplicate Address Detection probes to send')); o.placeholder = '1'; o.datatype = 'uinteger'; - o.depends('ipv6', '1'); + o.depends('ipv6', /1/); - o = this.replaceOption(s, 'devadvanced', form.Flag, 'multicast', _('Enable multicast support')); - o.default = o.enabled; + o = this.replaceOption(s, 'devadvanced', cbiFlagTristate, 'multicast', _('Enable multicast support')); + o.sysfs_default = (dev && dev.dev && dev.dev.flags) ? dev.dev.flags.multicast : null; o = this.replaceOption(s, 'devadvanced', form.ListValue, 'igmpversion', _('Force IGMP version')); o.value('', _('No enforcement')); o.value('1', _('Enforce IGMPv1')); o.value('2', _('Enforce IGMPv2')); o.value('3', _('Enforce IGMPv3')); - o.depends('multicast', '1'); + o.depends('multicast', /1/); o = this.replaceOption(s, 'devadvanced', form.ListValue, 'mldversion', _('Force MLD version')); o.value('', _('No enforcement')); o.value('1', _('Enforce MLD version 1')); o.value('2', _('Enforce MLD version 2')); - o.depends('multicast', '1'); + o.depends('multicast', /1/); if (isBridgePort(dev)) { - o = this.replaceOption(s, 'brport', form.Flag, 'learning', _('Enable MAC address learning')); - o.default = o.enabled; + o = this.replaceOption(s, 'brport', cbiFlagTristate, 'learning', _('Enable MAC address learning')); + o.sysfs = '/sys/class/net/%s/brport/learning'.format(devname || 'default'); - o = this.replaceOption(s, 'brport', form.Flag, 'unicast_flood', _('Enable unicast flooding')); - o.default = o.enabled; + o = this.replaceOption(s, 'brport', cbiFlagTristate, 'unicast_flood', _('Enable unicast flooding')); + o.sysfs = '/sys/class/net/%s/brport/unicast_flood'.format(devname || 'default'); - o = this.replaceOption(s, 'brport', form.Flag, 'isolated', _('Port isolation'), _('Only allow communication with non-isolated bridge ports when enabled')); - o.default = o.disabled; + o = this.replaceOption(s, 'brport', cbiFlagTristate, 'isolate', _('Port isolation'), _('Only allow communication with non-isolated bridge ports when enabled')); + o.sysfs = '/sys/class/net/%s/brport/isolated'.format(devname || 'default'); o = this.replaceOption(s, 'brport', form.ListValue, 'multicast_router', _('Multicast routing')); o.value('', _('Never')); o.value('1', _('Learn')); o.value('2', _('Always')); - o.depends('multicast', '1'); + o.depends('multicast', /1/); - o = this.replaceOption(s, 'brport', form.Flag, 'multicast_to_unicast', _('Multicast to unicast'), _('Forward multicast packets as unicast packets on this device.')); - o.default = o.disabled; - o.depends('multicast', '1'); + o = this.replaceOption(s, 'brport', cbiFlagTristate, 'multicast_to_unicast', _('Multicast to unicast'), _('Forward multicast packets as unicast packets on this device.')); + o.sysfs = '/sys/class/net/%s/brport/multicast_to_unicast'.format(devname || 'default'); + o.depends('multicast', /1/); - o = this.replaceOption(s, 'brport', form.Flag, 'multicast_fast_leave', _('Enable multicast fast leave')); - o.default = o.disabled; - o.depends('multicast', '1'); + o = this.replaceOption(s, 'brport', cbiFlagTristate, 'multicast_fast_leave', _('Enable multicast fast leave')); + o.sysfs = '/sys/class/net/%s/brport/multicast_fast_leave'.format(devname || 'default'); + o.depends('multicast', /1/); + + o = this.replaceOption(s, 'brport', cbiFlagTristate, 'drop_v4_unicast_in_l2_multicast', _('Drop nested IPv4 unicast'), _('Drop layer 2 multicast frames containing IPv4 unicast packets.')); + o.sysfs = '/proc/sys/net/ipv4/conf/%s/drop_unicast_in_l2_multicast'.format(devname || 'default'); + o.depends('multicast', /1/); + + o = this.replaceOption(s, 'brport', cbiFlagTristate, 'drop_v6_unicast_in_l2_multicast', _('Drop nested IPv6 unicast'), _('Drop layer 2 multicast frames containing IPv6 unicast packets.')); + o.sysfs = '/proc/sys/net/ipv6/conf/%s/drop_unicast_in_l2_multicast'.format(devname || 'default'); + o.depends('multicast', /1/); } o = this.replaceOption(s, 'bridgevlan', form.Flag, 'vlan_filtering', _('Enable VLAN filtering')); @@ -816,6 +856,8 @@ return baseclass.extend({ return network.instantiateDevice(port) }).filter(function(dev) { return dev.getType() != 'wifi' || dev.isUp(); + }).sort(function(a, b) { + return L.naturalCompare(a.getName(), b.getName()); }); this.children = this.children.filter(function(opt) { return !opt.option.match(/^port_/) }); @@ -929,18 +971,6 @@ return baseclass.extend({ for (var port_name in seen_ports) ports.push(port_name); - ports.sort(function(a, b) { - var m1 = a.match(/^(.+?)([0-9]*)$/), - m2 = b.match(/^(.+?)([0-9]*)$/); - - if (m1[1] < m2[1]) - return -1; - else if (m1[1] > m2[1]) - return 1; - else - return +(m1[2] || 0) - +(m2[2] || 0); - }); - ss.updatePorts(ports); }, diff --git a/luci-mod-network/htdocs/luci-static/resources/view/network/dhcp.js b/luci-mod-network/htdocs/luci-static/resources/view/network/dhcp.js old mode 100755 new mode 100644 index 6c6163c7c..3a213a20c --- a/luci-mod-network/htdocs/luci-static/resources/view/network/dhcp.js +++ b/luci-mod-network/htdocs/luci-static/resources/view/network/dhcp.js @@ -5,7 +5,9 @@ 'require rpc'; 'require uci'; 'require form'; +'require network'; 'require validation'; +'require tools.widgets as widgets'; var callHostHints, callDUIDHints, callDHCPLeases, CBILeaseStatus, CBILease6Status; @@ -65,6 +67,58 @@ CBILease6Status = form.DummyValue.extend({ } }); +function calculateNetwork(addr, mask) { + addr = validation.parseIPv4(String(addr)); + + if (!isNaN(mask)) + mask = validation.parseIPv4(network.prefixToMask(+mask)); + else + mask = validation.parseIPv4(String(mask)); + + if (addr == null || mask == null) + return null; + + return [ + [ + addr[0] & (mask[0] >>> 0 & 255), + addr[1] & (mask[1] >>> 0 & 255), + addr[2] & (mask[2] >>> 0 & 255), + addr[3] & (mask[3] >>> 0 & 255) + ].join('.'), + mask.join('.') + ]; +} + +function getDHCPPools() { + return uci.load('dhcp').then(function() { + let sections = uci.sections('dhcp', 'dhcp'), + tasks = [], pools = []; + + for (var i = 0; i < sections.length; i++) { + if (sections[i].ignore == '1' || !sections[i].interface) + continue; + + tasks.push(network.getNetwork(sections[i].interface).then(L.bind(function(section_id, net) { + var cidr = net ? (net.getIPAddrs()[0] || '').split('/') : null; + + if (cidr && cidr.length == 2) { + var net_mask = calculateNetwork(cidr[0], cidr[1]); + + pools.push({ + section_id: section_id, + network: net_mask[0], + netmask: net_mask[1] + }); + } + }, null, sections[i]['.name']))); + } + + return Promise.all(tasks).then(function() { + return pools; + }); + }); +} + function validateHostname(sid, s) { if (s == null || s == '') return true; @@ -72,7 +126,7 @@ function validateHostname(sid, s) { if (s.length > 256) return _('Expecting: %s').format(_('valid hostname')); - var labels = s.replace(/^\.+|\.$/g, '').split(/\./); + var labels = s.replace(/^\*?\.?|\.$/g, '').split(/\./); for (var i = 0; i < labels.length; i++) if (!labels[i].match(/^[a-z0-9_](?:[a-z0-9-]{0,61}[a-z0-9])?$/i)) @@ -102,13 +156,15 @@ function validateServerSpec(sid, s) { if (s == null || s == '') return true; - var m = s.match(/^(?:\/(.+)\/)?(.*)$/); + var m = s.match(/^(\/.*\/)?(.*)$/); if (!m) return _('Expecting: %s').format(_('valid hostname')); - var res = validateAddressList(sid, m[1]); - if (res !== true) - return res; + if (m[1] != '//' && m[1] != '/#/') { + var res = validateAddressList(sid, m[1]); + if (res !== true) + return res; + } if (m[2] == '' || m[2] == '#') return true; @@ -138,274 +194,552 @@ function validateServerSpec(sid, s) { return true; } +function validateMACAddr(pools, sid, s) { + if (s == null || s == '') + return true; + + var leases = uci.sections('dhcp', 'host'), + this_macs = L.toArray(s).map(function(m) { return m.toUpperCase() }); + + for (var i = 0; i < pools.length; i++) { + var this_net_mask = calculateNetwork(this.section.formvalue(sid, 'ip'), pools[i].netmask); + + if (!this_net_mask) + continue; + + for (var j = 0; j < leases.length; j++) { + if (leases[j]['.name'] == sid || !leases[j].ip) + continue; + + var lease_net_mask = calculateNetwork(leases[j].ip, pools[i].netmask); + + if (!lease_net_mask || this_net_mask[0] != lease_net_mask[0]) + continue; + + var lease_macs = L.toArray(leases[j].mac).map(function(m) { return m.toUpperCase() }); + + for (var k = 0; k < lease_macs.length; k++) + for (var l = 0; l < this_macs.length; l++) + if (lease_macs[k] == this_macs[l]) + return _('The MAC address %h is already used by another static lease in the same DHCP pool').format(this_macs[l]); + } + } + + return true; +} + return view.extend({ load: function() { return Promise.all([ callHostHints(), - callDUIDHints() + callDUIDHints(), + getDHCPPools(), + network.getDevices() ]); }, - render: function(hosts_duids) { + render: function(hosts_duids_pools) { var has_dhcpv6 = L.hasSystemFeature('dnsmasq', 'dhcpv6') || L.hasSystemFeature('odhcpd'), - hosts = hosts_duids[0], - duids = hosts_duids[1], + hosts = hosts_duids_pools[0], + duids = hosts_duids_pools[1], + pools = hosts_duids_pools[2], + ndevs = hosts_duids_pools[3], m, s, o, ss, so; - m = new form.Map('dhcp', _('DHCP and DNS'), _('Dnsmasq is a combined DHCP-Server and DNS-Forwarder for NAT firewalls')); + m = new form.Map('dhcp', _('DHCP and DNS'), + _('Dnsmasq is a lightweight DHCP server and DNS forwarder.')); - s = m.section(form.TypedSection, 'dnsmasq', _('Server Settings')); + s = m.section(form.TypedSection, 'dnsmasq'); s.anonymous = true; s.addremove = false; s.tab('general', _('General Settings')); + s.tab('relay', _('Relay')); s.tab('files', _('Resolv and Hosts Files')); - s.tab('tftp', _('TFTP Settings')); + s.tab('pxe_tftp', _('PXE/TFTP Settings')); s.tab('advanced', _('Advanced Settings')); s.tab('leases', _('Static Leases')); + s.tab('hosts', _('Hostnames')); + s.tab('srvhosts', _('SRV')); + s.tab('mxhosts', _('MX')); + s.tab('ipsets', _('IP Sets')); s.taboption('general', form.Flag, 'domainneeded', _('Domain required'), - _('Don\'t forward DNS-Requests without DNS-Name')); + _('Do not forward DNS queries without dots or domain parts.')); s.taboption('general', form.Flag, 'authoritative', _('Authoritative'), - _('This is the only DHCP in the local network')); - - - s.taboption('files', form.Flag, 'readethers', - _('Use /etc/ethers'), - _('Read /etc/ethers to configure the DHCP-Server')); - - s.taboption('files', form.Value, 'leasefile', - _('Leasefile'), - _('file where given DHCP-leases will be stored')); - - s.taboption('files', form.Flag, 'noresolv', - _('Ignore resolve file')).optional = true; - - o = s.taboption('files', form.Value, 'resolvfile', - _('Resolve file'), - _('local DNS file')); - - o.depends('noresolv', '0'); - o.placeholder = '/tmp/resolv.conf.d/resolv.conf.auto'; - o.optional = true; - - - s.taboption('files', form.Flag, 'nohosts', - _('Ignore /etc/hosts')).optional = true; - - s.taboption('files', form.DynamicList, 'addnhosts', - _('Additional Hosts files')).optional = true; - - o = s.taboption('advanced', form.Flag, 'quietdhcp', - _('Suppress logging'), - _('Suppress logging of the routine operation of these protocols')); - o.optional = true; - - o = s.taboption('advanced', form.Flag, 'sequential_ip', - _('Allocate IP sequentially'), - _('Allocate IP addresses sequentially, starting from the lowest available address')); - o.optional = true; - - o = s.taboption('advanced', form.Flag, 'boguspriv', - _('Filter private'), - _('Do not forward reverse lookups for local networks')); - o.default = o.enabled; - - s.taboption('advanced', form.Flag, 'filterwin2k', - _('Filter useless'), - _('Do not forward requests that cannot be answered by public name servers')); - - - s.taboption('advanced', form.Flag, 'localise_queries', - _('Localise queries'), - _('Localise hostname depending on the requesting subnet if multiple IPs are available')); - - if (L.hasSystemFeature('dnsmasq', 'dnssec')) { - o = s.taboption('advanced', form.Flag, 'dnssec', - _('DNSSEC')); - o.optional = true; - - o = s.taboption('advanced', form.Flag, 'dnsseccheckunsigned', - _('DNSSEC check unsigned'), - _('Requires upstream supports DNSSEC; verify unsigned domain responses really come from unsigned domains')); - o.default = o.enabled; - o.optional = true; - } + _('This is the only DHCP server in the local network.')); s.taboption('general', form.Value, 'local', _('Local server'), - _('Local domain specification. Names matching this domain are never forwarded and are resolved from DHCP or hosts files only')); + _('Never forward matching domains and subdomains, resolve from DHCP or hosts files only.')); s.taboption('general', form.Value, 'domain', _('Local domain'), - _('Local domain suffix appended to DHCP names and hosts file entries')); + _('Local domain suffix appended to DHCP names and hosts file entries.')); - s.taboption('advanced', form.Flag, 'expandhosts', - _('Expand hosts'), - _('Add local domain suffix to names served from hosts files')); - - s.taboption('advanced', form.Flag, 'nonegcache', - _('No negative cache'), - _('Do not cache negative replies, e.g. for not existing domains')); - - s.taboption('advanced', form.Value, 'serversfile', - _('Additional servers file'), - _('This file may contain lines like \'server=/domain/1.2.3.4\' or \'server=1.2.3.4\' for domain-specific or full upstream DNS servers.')); - - s.taboption('advanced', form.Flag, 'strictorder', - _('Strict order'), - _('DNS servers will be queried in the order of the resolvfile')).optional = true; - - s.taboption('advanced', form.Flag, 'allservers', - _('All Servers'), - _('Query all available upstream DNS servers')).optional = true; - - o = s.taboption('advanced', form.DynamicList, 'bogusnxdomain', _('Bogus NX Domain Override'), - _('List of hosts that supply bogus NX domain results')); - - o.optional = true; - o.placeholder = '67.215.65.132'; - - - s.taboption('general', form.Flag, 'logqueries', + o = s.taboption('general', form.Flag, 'logqueries', _('Log queries'), - _('Write received DNS requests to syslog')).optional = true; - - o = s.taboption('general', form.DynamicList, 'server', _('DNS forwardings'), - _('List of DNS servers to forward requests to')); + _('Write received DNS queries to syslog.')); + o.optional = true; + o = s.taboption('general', form.DynamicList, 'server', + _('DNS forwardings'), + _('List of upstream resolvers to forward queries to.')); o.optional = true; o.placeholder = '/example.org/10.1.2.3'; o.validate = validateServerSpec; - - o = s.taboption('general', form.DynamicList, 'address', _('Addresses'), - _('List of domains to force to an IP address.')); - + o = s.taboption('general', form.DynamicList, 'address', + _('Addresses'), + _('Resolve specified FQDNs to an IP.') + '
' + + _('Syntax: /fqdn[/fqdn…]/[ipaddr].') + '
' + + _('/#/ matches any domain. /example.com/ returns NXDOMAIN.') + '
' + + _('/example.com/# returns NULL addresses (0.0.0.0 and ::) for example.com and its subdomains.')); o.optional = true; - o.placeholder = '/router.local/192.168.0.1'; + o.placeholder = '/router.local/router.lan/192.168.0.1'; + o = s.taboption('general', form.DynamicList, 'ipset', + _('IP sets'), + _('List of IP sets to populate with the IPs of DNS lookup results of the FQDNs also specified here.')); + o.optional = true; + o.placeholder = '/example.org/ipset,ipset6'; o = s.taboption('general', form.Flag, 'rebind_protection', _('Rebind protection'), - _('Discard upstream RFC1918 responses')); - + _('Discard upstream responses containing RFC1918 addresses.').format('https://datatracker.ietf.org/doc/html/rfc1918')); o.rmempty = false; - o = s.taboption('general', form.Flag, 'rebind_localhost', _('Allow localhost'), - _('Allow upstream responses in the 127.0.0.0/8 range, e.g. for RBL services')); - + _('Exempt 127.0.0.0/8 and ::1 from rebinding checks, e.g. for RBL services.')); o.depends('rebind_protection', '1'); - o = s.taboption('general', form.DynamicList, 'rebind_domain', _('Domain whitelist'), - _('List of domains to allow RFC1918 responses for')); - o.optional = true; - + _('List of domains to allow RFC1918 responses for.')); o.depends('rebind_protection', '1'); + o.optional = true; o.placeholder = 'ihost.netflix.com'; o.validate = validateAddressList; + o = s.taboption('general', form.Flag, 'localservice', + _('Local service only'), + _('Accept DNS queries only from hosts whose address is on a local subnet.')); + o.optional = false; + o.rmempty = false; + + o = s.taboption('general', form.Flag, 'nonwildcard', + _('Non-wildcard'), + _('Bind dynamically to interfaces rather than wildcard address.')); + o.default = o.enabled; + o.optional = false; + o.rmempty = true; + + o = s.taboption('general', form.DynamicList, 'interface', + _('Listen interfaces'), + _('Listen only on the specified interfaces, and loopback if not excluded explicitly.')); + o.optional = true; + o.placeholder = 'lan'; + + o = s.taboption('general', form.DynamicList, 'notinterface', + _('Exclude interfaces'), + _('Do not listen on the specified interfaces.')); + o.optional = true; + o.placeholder = 'loopback'; + + o = s.taboption('relay', form.SectionValue, '__relays__', form.TableSection, 'relay', null, + _('Relay DHCP requests elsewhere. OK: v4↔v4, v6↔v6. Not OK: v4↔v6, v6↔v4.') + + '
' + _('Note: you may also need a DHCP Proxy (currently unavailable) when specifying a non-standard Relay To port(addr#port).') + + '
' + _('You may add multiple unique Relay To on the same Listen addr.')); + + ss = o.subsection; + + ss.addremove = true; + ss.anonymous = true; + ss.sortable = true; + ss.rowcolors = true; + ss.nodescriptions = true; + + so = ss.option(form.Value, 'id', _('ID')); + so.rmempty = false; + so.optional = true; + + so = ss.option(widgets.NetworkSelect, 'interface', _('Interface')); + so.optional = true; + so.rmempty = false; + so.placeholder = 'lan'; + + so = ss.option(form.Value, 'local_addr', _('Listen address')); + so.rmempty = false; + so.datatype = 'ipaddr'; + + for (var family = 4; family <= 6; family += 2) { + for (var i = 0; i < ndevs.length; i++) { + var addrs = (family == 6) ? ndevs[i].getIP6Addrs() : ndevs[i].getIPAddrs(); + for (var j = 0; j < addrs.length; j++) + so.value(addrs[j].split('/')[0]); + } + } + + so = ss.option(form.Value, 'server_addr', _('Relay To address')); + so.rmempty = false; + so.optional = false; + so.placeholder = '192.168.10.1#535'; + + so.validate = function(section, value) { + var m = this.section.formvalue(section, 'local_addr'), + n = this.section.formvalue(section, 'server_addr'), + p; + if (n != null && n != '') + p = n.split('#'); + if (p.length > 1 && !/^[0-9]+$/.test(p[1])) + return _('Expected port number.'); + else + n = p[0]; + + if ((m == null || m == '') && (n == null || n == '')) + return _('Both Listen addr and Relay To must be specified.'); + + if ((validation.parseIPv6(m) && validation.parseIPv6(n)) || + validation.parseIPv4(m) && validation.parseIPv4(n)) + return true; + else + return _('Listen and Relay To IP family must be homogeneous.') + }; + + s.taboption('files', form.Flag, 'readethers', + _('Use /etc/ethers'), + _('Read /etc/ethers to configure the DHCP server.')); + + s.taboption('files', form.Value, 'leasefile', + _('Lease file'), + _('File to store DHCP lease information.')); + + o = s.taboption('files', form.Flag, 'noresolv', + _('Ignore resolv file')); + o.optional = true; + + o = s.taboption('files', form.Value, 'resolvfile', + _('Resolv file'), + _('File with upstream resolvers.')); + o.depends('noresolv', '0'); + o.placeholder = '/tmp/resolv.conf.d/resolv.conf.auto'; + o.optional = true; + + o = s.taboption('files', form.Flag, 'nohosts', + _('Ignore /etc/hosts')); + o.optional = true; + + o = s.taboption('files', form.DynamicList, 'addnhosts', + _('Additional hosts files')); + o.optional = true; + o.placeholder = '/etc/dnsmasq.hosts'; + + o = s.taboption('advanced', form.Flag, 'quietdhcp', + _('Suppress logging'), + _('Suppress logging of the routine operation for the DHCP protocol.')); + o.optional = true; + + o = s.taboption('advanced', form.Flag, 'sequential_ip', + _('Allocate IPs sequentially'), + _('Allocate IP addresses sequentially, starting from the lowest available address.')); + o.optional = true; + + o = s.taboption('advanced', form.Flag, 'boguspriv', + _('Filter private'), + _('Do not forward reverse lookups for local networks.')); + o.default = o.enabled; + + s.taboption('advanced', form.Flag, 'filterwin2k', + _('Filter SRV/SOA service discovery'), + _('Filters SRV/SOA service discovery, to avoid triggering dial-on-demand links.') + '
' + + _('May prevent VoIP or other services from working.')); + + o = s.taboption('advanced', form.Flag, 'filter_aaaa', + _('Filter IPv6 AAAA records'), + _('Remove IPv6 addresses from the results and only return IPv4 addresses.') + '
' + + _('Can be useful if ISP has IPv6 nameservers but does not provide IPv6 routing.')); + o.optional = true; + + o = s.taboption('advanced', form.Flag, 'filter_a', + _('Filter IPv4 A records'), + _('Remove IPv4 addresses from the results and only return IPv6 addresses.')); + o.optional = true; + + s.taboption('advanced', form.Flag, 'localise_queries', + _('Localise queries'), + _('Return answers to DNS queries matching the subnet from which the query was received if multiple IPs are available.')); + + if (L.hasSystemFeature('dnsmasq', 'dnssec')) { + o = s.taboption('advanced', form.Flag, 'dnssec', + _('DNSSEC'), + _('Validate DNS replies and cache DNSSEC data, requires upstream to support DNSSEC.')); + o.optional = true; + + o = s.taboption('advanced', form.Flag, 'dnsseccheckunsigned', + _('DNSSEC check unsigned'), + _('Verify unsigned domain responses really come from unsigned domains.')); + o.default = o.enabled; + o.optional = true; + } + + s.taboption('advanced', form.Flag, 'expandhosts', + _('Expand hosts'), + _('Add local domain suffix to names served from hosts files.')); + + s.taboption('advanced', form.Flag, 'nonegcache', + _('No negative cache'), + _('Do not cache negative replies, e.g. for non-existent domains.')); + + o = s.taboption('advanced', form.Value, 'serversfile', + _('Additional servers file'), + _('File listing upstream resolvers, optionally domain-specific, e.g. server=1.2.3.4, server=/domain/1.2.3.4.')); + o.placeholder = '/etc/dnsmasq.servers'; + + o = s.taboption('advanced', form.Flag, 'strictorder', + _('Strict order'), + _('Upstream resolvers will be queried in the order of the resolv file.')); + o.optional = true; + + o = s.taboption('advanced', form.Flag, 'allservers', + _('All servers'), + _('Query all available upstream resolvers.')); + o.optional = true; + + o = s.taboption('advanced', form.DynamicList, 'bogusnxdomain', + _('IPs to override with NXDOMAIN'), + _('List of IP addresses to convert into NXDOMAIN responses.')); + o.optional = true; + o.placeholder = '64.94.110.11'; o = s.taboption('advanced', form.Value, 'port', - _('DNS server port'), - _('Listening port for inbound DNS queries')); - + _('DNS server port'), + _('Listening port for inbound DNS queries.')); o.optional = true; o.datatype = 'port'; o.placeholder = 53; - o = s.taboption('advanced', form.Value, 'queryport', - _('DNS query port'), - _('Fixed source port for outbound DNS queries')); - + _('DNS query port'), + _('Fixed source port for outbound DNS queries.')); o.optional = true; o.datatype = 'port'; o.placeholder = _('any'); - o = s.taboption('advanced', form.Value, 'dhcpleasemax', - _('Max. DHCP leases'), - _('Maximum allowed number of active DHCP leases')); - + _('Max. DHCP leases'), + _('Maximum allowed number of active DHCP leases.')); o.optional = true; o.datatype = 'uinteger'; o.placeholder = _('unlimited'); - o = s.taboption('advanced', form.Value, 'ednspacket_max', - _('Max. EDNS0 packet size'), - _('Maximum allowed size of EDNS.0 UDP packets')); - + _('Max. EDNS0 packet size'), + _('Maximum allowed size of EDNS0 UDP packets.')); o.optional = true; o.datatype = 'uinteger'; o.placeholder = 1280; - o = s.taboption('advanced', form.Value, 'dnsforwardmax', - _('Max. concurrent queries'), - _('Maximum allowed number of concurrent DNS queries')); - + _('Max. concurrent queries'), + _('Maximum allowed number of concurrent DNS queries.')); o.optional = true; o.datatype = 'uinteger'; o.placeholder = 150; o = s.taboption('advanced', form.Value, 'cachesize', _('Size of DNS query cache'), - _('Number of cached DNS entries (max is 10000, 0 is no caching)')); + _('Number of cached DNS entries, 10000 is maximum, 0 is no caching.')); o.optional = true; o.datatype = 'range(0,10000)'; - o.placeholder = 150; - - s.taboption('tftp', form.Flag, 'enable_tftp', - _('Enable TFTP server')).optional = true; - - o = s.taboption('tftp', form.Value, 'tftp_root', - _('TFTP server root'), - _('Root directory for files served via TFTP')); + o.placeholder = 1000; + o = s.taboption('pxe_tftp', form.Flag, 'enable_tftp', + _('Enable TFTP server'), + _('Enable the built-in single-instance TFTP server.')); o.optional = true; + + o = s.taboption('pxe_tftp', form.Value, 'tftp_root', + _('TFTP server root'), + _('Root directory for files served via TFTP. Enable TFTP server and TFTP server root turn on the TFTP server and serve files from TFTP server root.')); o.depends('enable_tftp', '1'); + o.optional = true; o.placeholder = '/'; - - o = s.taboption('tftp', form.Value, 'dhcp_boot', + o = s.taboption('pxe_tftp', form.Value, 'dhcp_boot', _('Network boot image'), - _('Filename of the boot image advertised to clients')); - - o.optional = true; + _('Filename of the boot image advertised to clients.')); o.depends('enable_tftp', '1'); + o.optional = true; o.placeholder = 'pxelinux.0'; - o = s.taboption('general', form.Flag, 'localservice', - _('Local Service Only'), - _('Limit DNS service to subnets interfaces on which we are serving DNS.')); - o.optional = false; - o.rmempty = false; + /* PXE - https://openwrt.org/docs/guide-user/base-system/dhcp#booting_options */ + o = s.taboption('pxe_tftp', form.SectionValue, '__pxe__', form.GridSection, 'boot', null, + _('Special PXE boot options for Dnsmasq.')); + ss = o.subsection; + ss.addremove = true; + ss.anonymous = true; + ss.nodescriptions = true; - o = s.taboption('general', form.Flag, 'nonwildcard', - _('Non-wildcard'), - _('Bind dynamically to interfaces rather than wildcard address (recommended as linux default)')); - o.default = o.enabled; - o.optional = false; - o.rmempty = true; + so = ss.option(form.Value, 'filename', + _('Filename'), + _('Host requests this filename from the boot server.')); + so.optional = false; + so.placeholder = 'pxelinux.0'; - o = s.taboption('general', form.DynamicList, 'interface', - _('Listen Interfaces'), - _('Limit listening to these interfaces, and loopback.')); - o.optional = true; + so = ss.option(form.Value, 'servername', + _('Server name'), + _('The hostname of the boot server')); + so.optional = false; + so.placeholder = 'myNAS'; - o = s.taboption('general', form.DynamicList, 'notinterface', - _('Exclude interfaces'), - _('Prevent listening on these interfaces.')); - o.optional = true; + so = ss.option(form.Value, 'serveraddress', + _('Server address'), + _('The IP address of the boot server')); + so.optional = false; + so.placeholder = '192.168.1.2'; + + so = ss.option(form.DynamicList, 'dhcp_option', + _('DHCP Options'), + _('Options for the Network-ID. (Note: needs also Network-ID.) E.g. "42,192.168.1.4" for NTP server, "3,192.168.4.4" for default route. 0.0.0.0 means "the address of the system running dnsmasq".')); + so.optional = true; + so.placeholder = '42,192.168.1.4'; + + so = ss.option(widgets.DeviceSelect, 'networkid', + _('Network-ID'), + _('Apply DHCP Options to this net. (Empty = all clients).')); + so.optional = true; + so.noaliases = true; + + so = ss.option(form.Flag, 'force', + _('Force'), + _('Always send DHCP Options. Sometimes needed, with e.g. PXELinux.')); + so.optional = true; + + so = ss.option(form.Value, 'instance', + _('Instance'), + _('Dnsmasq instance to which this boot section is bound. If unspecified, the section is valid for all dnsmasq instances.')); + so.optional = true; + + Object.values(L.uci.sections('dhcp', 'dnsmasq')).forEach(function(val, index) { + so.value(index, '%s (Domain: %s, Local: %s)'.format(index, val.domain || '?', val.local || '?')); + }); + + o = s.taboption('srvhosts', form.SectionValue, '__srvhosts__', form.TableSection, 'srvhost', null, + _('Bind service records to a domain name: specify the location of services. See RFC2782.').format('https://datatracker.ietf.org/doc/html/rfc2782') + + '
' + _('_service: _sip, _ldap, _imap, _stun, _xmpp-client, … . (Note: while _http is possible, no browsers support SRV records.)') + + '
' + _('_proto: _tcp, _udp, _sctp, _quic, … .') + + '
' + _('You may add multiple records for the same Target.') + + '
' + _('Larger weights (of the same prio) are given a proportionately higher probability of being selected.')); + + ss = o.subsection; + + ss.addremove = true; + ss.anonymous = true; + ss.sortable = true; + ss.rowcolors = true; + + so = ss.option(form.Value, 'srv', _('SRV'), _('Syntax: _service._proto.example.com.')); + so.rmempty = false; + so.datatype = 'hostname'; + so.placeholder = '_sip._tcp.example.com'; + + so = ss.option(form.Value, 'target', _('Target'), _('CNAME or fqdn')); + so.rmempty = false; + so.datatype = 'hostname'; + so.placeholder = 'sip.example.com'; + + so = ss.option(form.Value, 'port', _('Port')); + so.rmempty = false; + so.datatype = 'port'; + so.placeholder = '5060'; + + so = ss.option(form.Value, 'class', _('Priority'), _('Ordinal: lower comes first.')); + so.rmempty = true; + so.datatype = 'range(0,65535)'; + so.placeholder = '10'; + + so = ss.option(form.Value, 'weight', _('Weight')); + so.rmempty = true; + so.datatype = 'range(0,65535)'; + so.placeholder = '50'; + + o = s.taboption('mxhosts', form.SectionValue, '__mxhosts__', form.TableSection, 'mxhost', null, + _('Bind service records to a domain name: specify the location of services.') + + '
' + _('You may add multiple records for the same domain.')); + + ss = o.subsection; + + ss.addremove = true; + ss.anonymous = true; + ss.sortable = true; + ss.rowcolors = true; + ss.nodescriptions = true; + + so = ss.option(form.Value, 'domain', _('Domain')); + so.rmempty = false; + so.datatype = 'hostname'; + so.placeholder = 'example.com'; + + so = ss.option(form.Value, 'relay', _('Relay')); + so.rmempty = false; + so.datatype = 'hostname'; + so.placeholder = 'relay.example.com'; + + so = ss.option(form.Value, 'pref', _('Priority'), _('Ordinal: lower comes first.')); + so.rmempty = true; + so.datatype = 'range(0,65535)'; + so.placeholder = '0'; + + o = s.taboption('hosts', form.SectionValue, '__hosts__', form.GridSection, 'domain', null, + _('Hostnames are used to bind a domain name to an IP address. This setting is redundant for hostnames already configured with static leases, but it can be useful to rebind an FQDN.')); + + ss = o.subsection; + + ss.addremove = true; + ss.anonymous = true; + ss.sortable = true; + + so = ss.option(form.Value, 'name', _('Hostname')); + so.rmempty = false; + so.datatype = 'hostname'; + + so = ss.option(form.Value, 'ip', _('IP address')); + so.rmempty = false; + so.datatype = 'ipaddr'; + + var ipaddrs = {}; + + Object.keys(hosts).forEach(function(mac) { + var addrs = L.toArray(hosts[mac].ipaddrs || hosts[mac].ipv4); + + for (var i = 0; i < addrs.length; i++) + ipaddrs[addrs[i]] = hosts[mac].name || mac; + }); + + L.sortedKeys(ipaddrs, null, 'addr').forEach(function(ipv4) { + so.value(ipv4, '%s (%s)'.format(ipv4, ipaddrs[ipv4])); + }); + + o = s.taboption('ipsets', form.SectionValue, '__ipsets__', form.GridSection, 'ipset', null, + _('List of IP sets to populate with the IPs of DNS lookup results of the FQDNs also specified here.')); + + ss = o.subsection; + + ss.addremove = true; + ss.anonymous = true; + ss.sortable = true; + + so = ss.option(form.DynamicList, 'name', _('IP set')); + so.rmempty = false; + so.datatype = 'string'; + + so = ss.option(form.DynamicList, 'domain', _('Domain')); + so.rmempty = false; + so.datatype = 'hostname'; o = s.taboption('leases', form.SectionValue, '__leases__', form.GridSection, 'host', null, _('Static leases are used to assign fixed IP addresses and symbolic hostnames to DHCP clients. They are also required for non-dynamic interface configurations where only hosts with a corresponding lease are served.') + '
' + @@ -415,6 +749,7 @@ return view.extend({ ss.addremove = true; ss.anonymous = true; + ss.sortable = true; so = ss.option(form.Value, 'name', _('Hostname')); so.validate = validateHostname; @@ -428,8 +763,8 @@ return view.extend({ uci.unset('dhcp', section, 'dns'); }; - so = ss.option(form.Value, 'mac', _('MAC-Address')); - so.datatype = 'list(unique(macaddr))'; + so = ss.option(form.Value, 'mac', _('MAC address')); + so.datatype = 'list(macaddr)'; so.rmempty = true; so.cfgvalue = function(section) { var macs = L.toArray(uci.get('dhcp', section, 'mac')), @@ -468,75 +803,54 @@ return view.extend({ return node; }; + so.validate = validateMACAddr.bind(so, pools); Object.keys(hosts).forEach(function(mac) { var hint = hosts[mac].name || L.toArray(hosts[mac].ipaddrs || hosts[mac].ipv4)[0]; so.value(mac, hint ? '%s (%s)'.format(mac, hint) : mac); }); - so.write = function(section, value) { - var ip = this.map.lookupOption('ip', section)[0].formvalue(section); - var hosts = uci.sections('dhcp', 'host'); - var section_removed = false; - - for (var i = 0; i < hosts.length; i++) { - if (ip == hosts[i].ip) { - uci.set('dhcp', hosts[i]['.name'], 'mac', [hosts[i].mac, value].join(' ')); - uci.remove('dhcp', section); - section_removed = true; - break; - } - } - - if (!section_removed) { - uci.set('dhcp', section, 'mac', value); - } - } - - so = ss.option(form.Value, 'ip', _('IPv4-Address')); + so = ss.option(form.Value, 'ip', _('IPv4 address')); so.datatype = 'or(ip4addr,"ignore")'; so.validate = function(section, value) { - var mac = this.map.lookupOption('mac', section), - name = this.map.lookupOption('name', section), - m = mac ? mac[0].formvalue(section) : null, - n = name ? name[0].formvalue(section) : null; + var m = this.section.formvalue(section, 'mac'), + n = this.section.formvalue(section, 'name'); if ((m == null || m == '') && (n == null || n == '')) - return _('One of hostname or mac address must be specified!'); + return _('One of hostname or MAC address must be specified!'); - return true; + if (value == null || value == '' || value == 'ignore') + return true; + + var leases = uci.sections('dhcp', 'host'); + + for (var i = 0; i < leases.length; i++) + if (leases[i]['.name'] != section && leases[i].ip == value) + return _('The IP address %h is already used by another static lease').format(value); + + for (var i = 0; i < pools.length; i++) { + var net_mask = calculateNetwork(value, pools[i].netmask); + + if (net_mask && net_mask[0] == pools[i].network) + return true; + } + + return _('The IP address is outside of any DHCP pool address range'); }; - var ipaddrs = {}; - - Object.keys(hosts).forEach(function(mac) { - var addrs = L.toArray(hosts[mac].ipaddrs || hosts[mac].ipv4); - - for (var i = 0; i < addrs.length; i++) - ipaddrs[addrs[i]] = hosts[mac].name; - }); - L.sortedKeys(ipaddrs, null, 'addr').forEach(function(ipv4) { so.value(ipv4, ipaddrs[ipv4] ? '%s (%s)'.format(ipv4, ipaddrs[ipv4]) : ipv4); }); - so = ss.option(form.Value, 'gw', _('Gateway IPv4 Address')); - so.rmempty = true; - so.datatype = 'or(ip4addr,"ignore")'; - Object.keys(hosts).forEach(function(mac) { - if (hosts[mac].ipv4) - so.value(hosts[mac].ipv4); - }); - so = ss.option(form.Value, 'leasetime', _('Lease time')); so.rmempty = true; - so = ss.option(form.Value, 'duid', _('DUID')); + so = ss.option(form.Value, 'duid', _('DUID')); so.datatype = 'and(rangelength(20,36),hexstring)'; Object.keys(duids).forEach(function(duid) { so.value(duid, '%s (%s)'.format(duid, duids[duid].hostname || duids[duid].macaddr || duids[duid].ip6addr || '?')); }); - so = ss.option(form.Value, 'hostid', _('IPv6-Suffix (hex)')); + so = ss.option(form.Value, 'hostid', _('IPv6 suffix (hex)')); o = s.taboption('leases', CBILeaseStatus, '__status__'); @@ -560,8 +874,17 @@ return view.extend({ else exp = '%t'.format(lease.expires); + var hint = lease.macaddr ? hosts[lease.macaddr] : null, + name = hint ? hint.name : null, + host = null; + + if (name && lease.hostname && lease.hostname != name) + host = '%s (%s)'.format(lease.hostname, name); + else if (lease.hostname) + host = lease.hostname; + return [ - lease.hostname || '?', + host || '-', lease.ipaddr, lease.macaddr, exp diff --git a/luci-mod-network/htdocs/luci-static/resources/view/network/diagnostics.js b/luci-mod-network/htdocs/luci-static/resources/view/network/diagnostics.js old mode 100755 new mode 100644 index 5d6bd4765..1bfa95501 --- a/luci-mod-network/htdocs/luci-static/resources/view/network/diagnostics.js +++ b/luci-mod-network/htdocs/luci-static/resources/view/network/diagnostics.js @@ -4,6 +4,7 @@ 'require fs'; 'require ui'; 'require uci'; +'require network'; return view.extend({ handleCommand: function(exec, args) { @@ -13,8 +14,7 @@ return view.extend({ buttons[i].setAttribute('disabled', 'true'); return fs.exec(exec, args).then(function(res) { - var out = document.querySelector('.command-output'); - out.style.display = ''; + var out = document.querySelector('textarea'); dom.content(out, [ res.stdout || '', res.stderr || '' ]); }).catch(function(err) { @@ -36,7 +36,7 @@ return view.extend({ handleTraceroute: function(ev, cmd) { var exec = cmd || 'traceroute', addr = ev.currentTarget.parentNode.previousSibling.value, - args = (exec == 'traceroute') ? [ '-q', '1', '-w', '1', '-n', addr ] : [ '-q', '1', '-w', '2', '-n', addr ]; + args = (exec == 'traceroute') ? [ '-4', '-q', '1', '-w', '1', '-n', '-m', String(L.env.rpctimeout || 20), addr ] : [ '-q', '1', '-w', '2', '-n', addr ]; return this.handleCommand(exec, args); }, @@ -47,12 +47,20 @@ return view.extend({ return this.handleCommand('nslookup', [ addr ]); }, + handleArpScan: function(ev, cmd) { + var addr = ev.currentTarget.parentNode.previousSibling.value; + + return this.handleCommand('arp-scan', [ '-l', '-I', addr ]); + }, + load: function() { return Promise.all([ L.resolveDefault(fs.stat('/bin/ping6'), {}), L.resolveDefault(fs.stat('/usr/bin/ping6'), {}), L.resolveDefault(fs.stat('/bin/traceroute6'), {}), L.resolveDefault(fs.stat('/usr/bin/traceroute6'), {}), + L.resolveDefault(fs.stat('/usr/bin/arp-scan'), {}), + network.getDevices(), uci.load('luci') ]); }, @@ -60,15 +68,15 @@ return view.extend({ render: function(res) { var has_ping6 = res[0].path || res[1].path, has_traceroute6 = res[2].path || res[3].path, + has_arpscan = res[4].path, + devices = res[5], dns_host = uci.get('luci', 'diag', 'dns') || 'openwrt.org', ping_host = uci.get('luci', 'diag', 'ping') || 'openwrt.org', route_host = uci.get('luci', 'diag', 'route') || 'openwrt.org'; - return E([], [ - E('h2', {}, [ _('Network Utilities') ]), - E('table', { 'class': 'table' }, [ + var table = E('table', { 'class': 'table' }, [ E('tr', { 'class': 'tr' }, [ - E('td', { 'class': 'td left' }, [ + E('td', { 'class': 'td left', 'style': 'overflow:initial' }, [ E('input', { 'style': 'margin:5px 0', 'type': 'text', @@ -91,7 +99,7 @@ return view.extend({ ]) ]), - E('td', { 'class': 'td left' }, [ + E('td', { 'class': 'td left', 'style': 'overflow:initial' }, [ E('input', { 'style': 'margin:5px 0', 'type': 'text', @@ -126,11 +134,45 @@ return view.extend({ 'click': ui.createHandlerFn(this, 'handleNslookup') }, [ _('Nslookup') ]) ]) - ]) + ]), + + has_arpscan ? E('td', { 'class': 'td left' }, [ + E('select', { + 'style': 'margin:5px 0' + }, devices.map(function(device) { + if (!device.isUp()) + return E([]); + + return E('option', { 'value': device.getName() }, [ device.getI18n() ]); + })), + E('span', { 'class': 'diag-action' }, [ + E('button', { + 'class': 'cbi-button cbi-button-action', + 'click': ui.createHandlerFn(this, 'handleArpScan') + }, [ _('Arp-scan') ]) + ]) + ]) : E([]), ]) - ]), - E('pre', { 'class': 'command-output', 'style': 'display:none' }) + ]); + + var view = E('div', { 'class': 'cbi-map'}, [ + E('h2', {}, [ _('Diagnostics') ]), + E('div', { 'class': 'cbi-map-descr'}, _('Execution of various network commands to check the connection and name resolution to other systems.')), + table, + E('div', {'class': 'cbi-section'}, [ + E('div', { 'id' : 'command-output'}, + E('textarea', { + 'id': 'widget.command-output', + 'style': 'width: 100%; font-family:monospace; white-space:pre', + 'readonly': true, + 'wrap': 'off', + 'rows': '20' + }) + ) + ]) ]); + + return view; }, handleSaveApply: null, diff --git a/luci-mod-network/htdocs/luci-static/resources/view/network/hosts.js b/luci-mod-network/htdocs/luci-static/resources/view/network/hosts.js deleted file mode 100755 index 93ebf5ba6..000000000 --- a/luci-mod-network/htdocs/luci-static/resources/view/network/hosts.js +++ /dev/null @@ -1,50 +0,0 @@ -'use strict'; -'require view'; -'require rpc'; -'require form'; - -return view.extend({ - callHostHints: rpc.declare({ - object: 'luci-rpc', - method: 'getHostHints', - expect: { '': {} } - }), - - load: function() { - return this.callHostHints(); - }, - - render: function(hosts) { - var m, s, o; - - m = new form.Map('dhcp', _('Hostnames')); - - s = m.section(form.GridSection, 'domain', _('Host entries')); - s.addremove = true; - s.anonymous = true; - s.sortable = true; - - o = s.option(form.Value, 'name', _('Hostname')); - o.datatype = 'hostname'; - o.rmempty = true; - - o = s.option(form.Value, 'ip', _('IP address')); - o.datatype = 'ipaddr'; - o.rmempty = true; - - var ipaddrs = {}; - - Object.keys(hosts).forEach(function(mac) { - var addrs = L.toArray(hosts[mac].ipaddrs || hosts[mac].ipv4); - - for (var i = 0; i < addrs.length; i++) - ipaddrs[addrs[i]] = hosts[mac].name || mac; - }); - - L.sortedKeys(ipaddrs, null, 'addr').forEach(function(ipv4) { - o.value(ipv4, '%s (%s)'.format(ipv4, ipaddrs[ipv4])); - }); - - return m.render(); - } -}); diff --git a/luci-mod-network/htdocs/luci-static/resources/view/network/interfaces.js b/luci-mod-network/htdocs/luci-static/resources/view/network/interfaces.js old mode 100755 new mode 100644 index ff179d404..ebd9c05c5 --- a/luci-mod-network/htdocs/luci-static/resources/view/network/interfaces.js +++ b/luci-mod-network/htdocs/luci-static/resources/view/network/interfaces.js @@ -228,6 +228,23 @@ function get_netmask(s, use_cfgvalue) { return subnetmask; } +function has_peerdns(proto) { + switch (proto) { + case 'dhcp': + case 'dhcpv6': + case 'qmi': + case 'ppp': + case 'pppoe': + case 'pppoa': + case 'pptp': + case 'openvpn': + case 'sstp': + return true; + } + + return false; +} + var cbiRichListValue = form.ListValue.extend({ renderWidget: function(section_id, option_index, cfgvalue) { var choices = this.transformChoices(); @@ -488,7 +505,7 @@ return view.extend({ }; s.modaltitle = function(section_id) { - return _('Interfaces') + ' » ' + section_id.toUpperCase(); + return _('Interfaces') + ' » ' + section_id; }; s.renderRowActions = function(section_id) { @@ -535,7 +552,7 @@ return view.extend({ var protocols = network.getProtocols(); protocols.sort(function(a, b) { - return a.getProtocol() > b.getProtocol(); + return L.naturalCompare(a.getProtocol(), b.getProtocol()); }); o = s.taboption('general', form.DummyValue, '_ifacestat_modal', _('Status')); @@ -643,7 +660,7 @@ return view.extend({ E('p', _('No DHCP Server configured for this interface') + '   '), E('button', { 'class': 'cbi-button cbi-button-add', - 'title': _('Setup DHCP Server'), + 'title': _('Set up DHCP Server'), 'click': ui.createHandlerFn(this, function(section_id, ev) { this.map.save(function() { uci.add('dhcp', 'dhcp', section_id); @@ -659,7 +676,7 @@ return view.extend({ } }); }, ifc.getName()) - }, _('Setup DHCP Server')) + }, _('Set up DHCP Server')) ]); }; @@ -805,7 +822,14 @@ return view.extend({ return flags.length ? flags : [ 'other-config' ]; }; so.remove = function(section_id) { - uci.set('dhcp', section_id, 'ra_flags', [ 'none' ]); + var existing = L.toArray(uci.get('dhcp', section_id, 'ra_flags')); + if (this.isActive(section_id)) { + if (existing.length != 1 || existing[0] != 'none') + uci.set('dhcp', section_id, 'ra_flags', [ 'none' ]); + } + else if (existing.length) { + uci.unset('dhcp', section_id, 'ra_flags'); + } }; so = ss.taboption('ipv6-ra', form.Value, 'ra_maxinterval', _('Max RA interval'), _('Maximum time allowed between sending unsolicited RA. Default is 600 seconds.')); @@ -835,15 +859,17 @@ return view.extend({ so.depends('ra', 'server'); so.depends({ ra: 'hybrid', master: '0' }); so.load = function(section_id) { - var dev = ifc.getL3Device(); + var dev = ifc.getL3Device(), + path = dev ? "/proc/sys/net/ipv6/conf/%s/mtu".format(dev.getName()) : null; - if (dev) { - var path = "/proc/sys/net/ipv6/conf/%s/mtu".format(dev.getName()); + return Promise.all([ + dev ? L.resolveDefault(fs.read(path), dev.getMTU()) : null, + this.super('load', [section_id]) + ]).then(L.bind(function(res) { + this.placeholder = +res[0]; - return L.resolveDefault(fs.read(path), dev.getMTU()).then(L.bind(function(data) { - this.placeholder = data; - }, this)); - } + return res[1]; + }, this)); }; so = ss.taboption('ipv6-ra', form.Value, 'ra_hoplimit', _('RA Hop Limit'), _('The maximum hops to be published in RA messages. Maximum is 255 hops.')); @@ -852,15 +878,17 @@ return view.extend({ so.depends('ra', 'server'); so.depends({ ra: 'hybrid', master: '0' }); so.load = function(section_id) { - var dev = ifc.getL3Device(); + var dev = ifc.getL3Device(), + path = dev ? "/proc/sys/net/ipv6/conf/%s/hop_limit".format(dev.getName()) : null; - if (dev) { - var path = "/proc/sys/net/ipv6/conf/%s/hop_limit".format(dev.getName()); + return Promise.all([ + dev ? L.resolveDefault(fs.read(path), 64) : null, + this.super('load', [section_id]) + ]).then(L.bind(function(res) { + this.placeholder = +res[0]; - return L.resolveDefault(fs.read(path), 64).then(L.bind(function(data) { - this.placeholder = data; - }, this)); - } + return res[1]; + }, this)); }; @@ -878,18 +906,24 @@ return view.extend({ so = ss.taboption('ipv6', form.DynamicList, 'dns', _('Announced IPv6 DNS servers'), _('Specifies a fixed list of IPv6 DNS server addresses to announce via DHCPv6. If left unspecified, the device will announce itself as IPv6 DNS server unless the Local IPv6 DNS server option is disabled.')); so.datatype = 'ip6addr("nomask")'; /* restrict to IPv6 only for now since dnsmasq (DHCPv4) does not honour this option */ + so.depends('ra', 'server'); + so.depends({ ra: 'hybrid', master: '0' }); so.depends('dhcpv6', 'server'); so.depends({ dhcpv6: 'hybrid', master: '0' }); so = ss.taboption('ipv6', form.Flag, 'dns_service', _('Local IPv6 DNS server'), _('Announce this device as IPv6 DNS server.')); so.default = so.enabled; + so.depends({ ra: 'server', dns: /^$/ }); + so.depends({ ra: 'hybrid', dns: /^$/, master: '0' }); so.depends({ dhcpv6: 'server', dns: /^$/ }); so.depends({ dhcpv6: 'hybrid', dns: /^$/, master: '0' }); so = ss.taboption('ipv6', form.DynamicList, 'domain', _('Announced DNS domains'), _('Specifies a fixed list of DNS search domains to announce via DHCPv6. If left unspecified, the local device DNS search domain will be announced.')); so.datatype = 'hostname'; + so.depends('ra', 'server'); + so.depends({ ra: 'hybrid', master: '0' }); so.depends('dhcpv6', 'server'); so.depends({ dhcpv6: 'hybrid', master: '0' }); @@ -919,13 +953,13 @@ return view.extend({ o = nettools.replaceOption(s, 'advanced', form.Flag, 'defaultroute', _('Use default gateway'), _('If unchecked, no default route is configured')); o.default = o.enabled; - if (protoval != 'static') { + if (has_peerdns(protoval)) { o = nettools.replaceOption(s, 'advanced', form.Flag, 'peerdns', _('Use DNS servers advertised by peer'), _('If unchecked, the advertised DNS server addresses are ignored')); o.default = o.enabled; } o = nettools.replaceOption(s, 'advanced', form.DynamicList, 'dns', _('Use custom DNS servers')); - if (protoval != 'static') + if (has_peerdns(protoval)) o.depends('peerdns', '0'); o.datatype = 'ipaddr'; @@ -941,17 +975,6 @@ return view.extend({ o = nettools.replaceOption(s, 'advanced', form.Value, 'metric', _('Use gateway metric')); o.datatype = 'uinteger'; o.placeholder = '0'; - - o = nettools.replaceOption(s,'advanced', form.ListValue, 'multipath', _('Multipath setting'), _('Only one interface must be set as Master.')); - o.value('on',_('Enabled')); - o.value('off',_('Disabled')); - o.value('master',_('Master')); - o.value('backup',_('Backup')); - o.default = 'off'; - - o = nettools.replaceOption(s,'advanced', form.Value, 'addlatency', _('Additional latency')); - o.datatype = 'uinteger'; - o.default = '0'; o = nettools.replaceOption(s, 'advanced', form.Value, 'ip4table', _('Override IPv4 routing table')); o.datatype = 'or(uinteger, string)'; @@ -961,7 +984,12 @@ return view.extend({ o = nettools.replaceOption(s, 'advanced', form.Value, 'ip6table', _('Override IPv6 routing table')); o.datatype = 'or(uinteger, string)'; for (var i = 0; i < rtTables.length; i++) - o.value(rtTables[i][1], '%s (%d)'.format(rtTables[i][0], rtTables[i][1])); + o.value(rtTables[i][1], '%s (%d)'.format(rtTables[i][1], rtTables[i][0])); + + if (protoval == 'dhcpv6') { + o = nettools.replaceOption(s, 'advanced', form.Flag, 'sourcefilter', _('IPv6 source routing'), _('Automatically handle multiple uplink interfaces using source-based policy routing.')); + o.default = o.enabled; + } o = nettools.replaceOption(s, 'advanced', form.Flag, 'delegate', _('Delegate IPv6 prefixes'), _('Enable downstream delegation of IPv6 prefixes available on this interface')); o.default = o.enabled; @@ -1080,7 +1108,7 @@ return view.extend({ proto, name, device; protocols.sort(function(a, b) { - return a.getProtocol() > b.getProtocol(); + return L.naturalCompare(a.getProtocol(), b.getProtocol()); }); s2.render = function() { @@ -1154,6 +1182,9 @@ return view.extend({ protoclass.addDevice(device.formvalue('_new_')); m.children[0].addedSection = section_id; + + ui.hideModal(); + ui.showModal(null, E('p', { 'class': 'spinning' }, [ _('Loading data…') ])); }).then(L.bind(m.children[0].renderMoreOptionsModal, m.children[0], nameval)); }); }) @@ -1183,9 +1214,9 @@ return view.extend({ var node = E('div', { 'class': 'ifacebox' }, [ E('div', { 'class': 'ifacebox-head', - 'style': 'background-color:%s'.format(zone ? zone.getColor() : '#EEEEEE'), + 'style': firewall.getZoneColorStyle(zone), 'title': zone ? _('Part of zone %q').format(zone.getName()) : _('No zone assigned') - }, E('strong', net.getName().toUpperCase())), + }, E('strong', net.getName())), E('div', { 'class': 'ifacebox-body', 'id': '%s-ifc-devices'.format(section_id), @@ -1239,7 +1270,7 @@ return view.extend({ s.cfgsections = function() { var sections = uci.sections('network', 'device'), - section_ids = sections.sort(function(a, b) { return a.name > b.name }).map(function(s) { return s['.name'] }); + section_ids = sections.sort(function(a, b) { return L.naturalCompare(a.name, b.name) }).map(function(s) { return s['.name'] }); for (var i = 0; i < netDevs.length; i++) { if (sections.filter(function(s) { return s.name == netDevs[i].getName() }).length) @@ -1284,7 +1315,7 @@ return view.extend({ var trEl = this.super('renderRowActions', [ section_id, _('Configure…') ]), deleteBtn = trEl.querySelector('button:last-child'); - deleteBtn.firstChild.data = _('Reset'); + deleteBtn.firstChild.data = _('Unconfigure'); deleteBtn.setAttribute('title', _('Remove related device settings from the configuration')); deleteBtn.disabled = section_id.match(/^dev:/) ? true : null; @@ -1317,9 +1348,26 @@ return view.extend({ for (var i = 0; i < map.addedVLANs.length; i++) uci.remove('network', map.addedVLANs[i]); + if (this.addedSection) + uci.remove('network', this.addedSection); + return form.GridSection.prototype.handleModalCancel.apply(this, arguments); }; + s.handleRemove = function(section_id /*, ... */) { + var name = uci.get('network', section_id, 'name'), + type = uci.get('network', section_id, 'type'); + + if (name != null && type == 'bridge') { + uci.sections('network', 'bridge-vlan', function(bvs) { + if (bvs.device == name) + uci.remove('network', bvs['.name']); + }); + } + + return form.GridSection.prototype.handleRemove.apply(this, arguments); + }; + function getDevice(section_id) { var m = section_id.match(/^dev:(.+)$/), name = m ? m[1] : uci.get('network', section_id, 'name'); @@ -1422,7 +1470,7 @@ return view.extend({ mac = dev ? dev.getMAC() : null; return val ? E('strong', { - 'data-tooltip': _('The value is overridden by configuration. Original: %s').format(mac || _('unknown')) + 'data-tooltip': _('The value is overridden by configuration.') }, [ val.toUpperCase() ]) : (mac || '-'); }; @@ -1434,7 +1482,7 @@ return view.extend({ mtu = dev ? dev.getMTU() : null; return val ? E('strong', { - 'data-tooltip': _('The value is overridden by configuration. Original: %s').format(mtu || _('unknown')) + 'data-tooltip': _('The value is overridden by configuration.') }, [ val ]) : (mtu || '-').toString(); }; diff --git a/luci-mod-network/htdocs/luci-static/resources/view/network/routes.js b/luci-mod-network/htdocs/luci-static/resources/view/network/routes.js old mode 100755 new mode 100644 index 7e11a3cb4..da1330aec --- a/luci-mod-network/htdocs/luci-static/resources/view/network/routes.js +++ b/luci-mod-network/htdocs/luci-static/resources/view/network/routes.js @@ -1,22 +1,35 @@ 'use strict'; 'require view'; +'require fs'; +'require uci'; 'require form'; 'require network'; 'require tools.widgets as widgets'; return view.extend({ load: function() { - return network.getDevices(); + return Promise.all([ + network.getDevices(), + fs.lines('/etc/iproute2/rt_tables') + ]); }, - render: function(netdevs) { - var m, s, o; + render: function(data) { + var netDevs = data[0], + m, s, o; - m = new form.Map('network', _('Routes'), _('Routes specify over which interface and gateway a certain host or network can be reached.')); + var rtTables = data[1].map(function(l) { + var m = l.trim().match(/^(\d+)\s+(\S+)$/); + return m ? [ +m[1], m[2] ] : null; + }).filter(function(e) { + return e && e[0] > 0; + }); + + m = new form.Map('network', _('Routing'), _('Routing defines over which interface and gateway a certain host or network can be reached.')); m.tabbed = true; - for (var i = 4; i <= 6; i += 2) { - s = m.section(form.GridSection, (i == 4) ? 'route' : 'route6', (i == 4) ? _('Static IPv4 Routes') : _('Static IPv6 Routes')); + for (var family = 4; family <= 6; family += 2) { + s = m.section(form.GridSection, (family == 6) ? 'route6' : 'route', (family == 6) ? _('Static IPv6 Routes') : _('Static IPv4 Routes')); s.anonymous = true; s.addremove = true; s.sortable = true; @@ -25,44 +38,12 @@ return view.extend({ s.tab('general', _('General Settings')); s.tab('advanced', _('Advanced Settings')); - o = s.taboption('general', widgets.NetworkSelect, 'interface', _('Interface')); - o.rmempty = false; + o = s.taboption('general', widgets.NetworkSelect, 'interface', _('Interface'), _('Specifies the logical interface name of the parent (or master) interface this route belongs to')); + o.loopback = true; o.nocreate = true; - o = s.taboption('general', form.Flag, 'disabled', _('Disable'), _('Disable this route')); - o.rmempty = true; - o.default = o.disabled; - - o = s.taboption('general', form.Value, 'target', _('Target'), (i == 4) ? _('Host-IP or Network') : _('IPv6-Address or Network (CIDR)')); - o.datatype = (i == 4) ? 'ip4addr' : 'ip6addr'; - o.rmempty = false; - - if (i == 4) { - o = s.taboption('general', form.Value, 'netmask', _('IPv4-Netmask'), _('if target is a network')); - o.placeholder = '255.255.255.255'; - o.datatype = 'ip4addr'; - o.rmempty = true; - } - - o = s.taboption('general', form.Value, 'gateway', (i == 4) ? _('IPv4-Gateway') : _('IPv6-Gateway')); - o.datatype = (i == 4) ? 'ip4addr' : 'ip6addr'; - o.rmempty = true; - - o = s.taboption('advanced', form.Value, 'metric', _('Metric')); - o.placeholder = 0; - o.datatype = (i == 4) ? 'range(0,255)' : 'range(0,65535)'; - o.rmempty = true; - o.textvalue = function(section_id) { - return this.cfgvalue(section_id) || 0; - }; - - o = s.taboption('advanced', form.Value, 'mtu', _('MTU')); - o.placeholder = 1500; - o.datatype = 'range(64,9000)'; - o.rmempty = true; + o = s.taboption('general', form.ListValue, 'type', _('Route type'), _('Specifies the route type to be created')); o.modalonly = true; - - o = s.taboption('advanced', form.ListValue, 'type', _('Route type')); o.value('', 'unicast'); o.value('local'); o.value('broadcast'); @@ -71,36 +52,155 @@ return view.extend({ o.value('prohibit'); o.value('blackhole'); o.value('anycast'); - o.default = ''; - o.rmempty = true; - o.modalonly = true; - o = s.taboption('advanced', form.Value, 'table', _('Route table')); - o.value('local', 'local (255)'); - o.value('main', 'main (254)'); - o.value('default', 'default (253)'); - o.rmempty = true; - o.modalonly = true; + o = s.taboption('general', form.Value, 'target', _('Target'), _('Network address')); + o.rmempty = false; + o.datatype = (family == 6) ? 'cidr6' : 'cidr4'; + o.placeholder = (family == 6) ? '::/0' : '0.0.0.0/0'; o.cfgvalue = function(section_id) { - var cfgvalue = this.map.data.get('network', section_id, 'table'); - return cfgvalue || 'main'; + var section_type = uci.get('network', section_id, '.type'), + target = uci.get('network', section_id, 'target'), + mask = uci.get('network', section_id, 'netmask'), + v6 = (section_type == 'route6') ? true : false, + bits = mask ? network.maskToPrefix(mask, v6) : (v6 ? 128 : 32); + if (target) { + return target.split('/')[1] ? target : target + '/' + bits; + } + } + o.write = function(section_id, formvalue) { + uci.set('network', section_id, 'target', formvalue); + uci.unset('network', section_id, 'netmask'); + } + + o = s.taboption('general', form.Value, 'gateway', _('Gateway'), _('Specifies the network gateway. If omitted, the gateway from the parent interface is taken if any, otherwise creates a link scope route. If set to 0.0.0.0 no gateway will be specified for the route')); + o.datatype = (family == 6) ? 'ip6addr("nomask")' : 'ip4addr("nomask")'; + o.placeholder = (family == 6) ? 'fe80::1' : '192.168.0.1'; + + o = s.taboption('advanced', form.Value, 'metric', _('Metric'), _('Specifies the route metric to use')); + o.datatype = 'uinteger'; + o.placeholder = 0; + o.textvalue = function(section_id) { + return this.cfgvalue(section_id) || 0; }; - o = s.taboption('advanced', form.Value, 'source', _('Source Address')); - o.placeholder = E('em', _('automatic')); - for (var j = 0; j < netdevs.length; j++) { - var addrs = netdevs[j].getIPAddrs(); - for (var k = 0; k < addrs.length; k++) - o.value(addrs[k].split('/')[0]); - } - o.datatype = (i == 4) ? 'ip4addr' : 'ip6addr'; - o.default = ''; - o.rmempty = true; + o = s.taboption('advanced', form.Value, 'mtu', _('MTU'), _('Defines a specific MTU for this route')); o.modalonly = true; + o.datatype = 'and(uinteger,range(64,9000))'; + o.placeholder = 1500; - o = s.taboption('advanced', form.Flag, 'onlink', _('On-Link route')); + o = s.taboption('advanced', form.Value, 'table', _('Table'), _('The rule target is a table lookup ID: a numeric table index ranging from 0 to 65535 or symbol alias declared in /etc/iproute2/rt_tables. Special aliases local (255), main (254) and default (253) are also valid')); + o.datatype = 'or(uinteger, string)'; + for (var i = 0; i < rtTables.length; i++) + o.value(rtTables[i][1], '%s (%d)'.format(rtTables[i][1], rtTables[i][0])); + o.textvalue = function(section_id) { + return this.cfgvalue(section_id) || 'main'; + }; + + o = s.taboption('advanced', form.Value, 'source', _('Source'), _('Specifies the preferred source address when sending to destinations covered by the target')); + o.modalonly = true; + o.datatype = (family == 6) ? 'ip6addr' : 'ip4addr'; + o.placeholder = E('em', _('auto')); + for (var i = 0; i < netDevs.length; i++) { + var addrs = (family == 6) ? netDevs[i].getIP6Addrs() : netDevs[i].getIPAddrs(); + for (var j = 0; j < addrs.length; j++) + o.value(addrs[j].split('/')[0]); + } + + o = s.taboption('advanced', form.Flag, 'onlink', _('On-link'), _('When enabled, gateway is on-link even if the gateway does not match any interface prefix')); + o.modalonly = true; + o.default = o.disabled; + + o = s.taboption('advanced', form.Flag, 'disabled', _('Disable')); + o.modalonly = false; + o.editable = true; + o.default = o.disabled; + } + + for (var family = 4; family <= 6; family += 2) { + s = m.section(form.GridSection, (family == 6) ? 'rule6' : 'rule', (family == 6) ? _('IPv6 Rules') : _('IPv4 Rules')); + s.anonymous = true; + s.addremove = true; + s.sortable = true; + s.nodescriptions = true; + + s.tab('general', _('General Settings')); + s.tab('advanced', _('Advanced Settings')); + + o = s.taboption('general', form.Value, 'priority', _('Priority'), _('Specifies the ordering of the IP rules')); + o.datatype = 'uinteger'; + o.placeholder = 30000; + o.textvalue = function(section_id) { + return this.cfgvalue(section_id) || E('em', _('auto')); + }; + + o = s.taboption('general', form.ListValue, 'action', _('Rule type'), _('Specifies the rule target routing action')); + o.modalonly = true; + o.value('', 'unicast'); + o.value('unreachable'); + o.value('prohibit'); + o.value('blackhole'); + o.value('throw'); + + o = s.taboption('general', widgets.NetworkSelect, 'in', _('Incoming interface'), _('Specifies the incoming logical interface name')); + o.loopback = true; + o.nocreate = true; + + o = s.taboption('general', form.Value, 'src', _('Source'), _('Specifies the source subnet to match (CIDR notation)')); + o.datatype = (family == 6) ? 'cidr6' : 'cidr4'; + o.placeholder = (family == 6) ? '::/0' : '0.0.0.0/0'; + o.textvalue = function(section_id) { + return this.cfgvalue(section_id) || E('em', _('any')); + }; + + o = s.taboption('general', widgets.NetworkSelect, 'out', _('Outgoing interface'), _('Specifies the outgoing logical interface name')); + o.loopback = true; + o.nocreate = true; + + o = s.taboption('general', form.Value, 'dest', _('Destination'), _('Specifies the destination subnet to match (CIDR notation)')); + o.datatype = (family == 6) ? 'cidr6' : 'cidr4'; + o.placeholder = (family == 6) ? '::/0' : '0.0.0.0/0'; + o.textvalue = function(section_id) { + return this.cfgvalue(section_id) || E('em', _('any')); + }; + + o = s.taboption('general', form.Value, 'lookup', _('Table'), _('The rule target is a table lookup ID: a numeric table index ranging from 0 to 65535 or symbol alias declared in /etc/iproute2/rt_tables. Special aliases local (255), main (254) and default (253) are also valid')); + o.datatype = 'or(uinteger, string)'; + for (var i = 0; i < rtTables.length; i++) + o.value(rtTables[i][1], '%s (%d)'.format(rtTables[i][1], rtTables[i][0])); + + o = s.taboption('advanced', form.Value, 'goto', _('Jump to rule'), _('The rule target is a jump to another rule specified by its priority value')); + o.modalonly = true; + o.datatype = 'uinteger'; + o.placeholder = 80000; + + o = s.taboption('advanced', form.Value, 'mark', _('Firewall mark'), _('Specifies the fwmark and optionally its mask to match, e.g. 0xFF to match mark 255 or 0x0/0x1 to match any even mark value')); + o.modalonly = true; + o.datatype = 'string'; + o.placeholder = '0x1/0xf'; + + o = s.taboption('advanced', form.Value, 'tos', _('Type of service'), _('Specifies the TOS value to match in IP headers')); + o.modalonly = true; + o.datatype = 'uinteger'; + o.placeholder = 10; + + o = s.taboption('advanced', form.Value, 'uidrange', _('User identifier'), _('Specifies an individual UID or range of UIDs to match, e.g. 1000 to match corresponding UID or 1000-1005 to inclusively match all UIDs within the corresponding range')); + o.modalonly = true; + o.datatype = 'string'; + o.placeholder = '1000-1005'; + + o = s.taboption('advanced', form.Value, 'suppress_prefixlength', _('Prefix suppressor'), _('Reject routing decisions that have a prefix length less than or equal to the specified value')); + o.modalonly = true; + o.datatype = (family == 6) ? 'ip6prefix' : 'ip4prefix'; + o.placeholder = (family == 6) ? 64 : 24; + + o = s.taboption('advanced', form.Flag, 'invert', _('Invert match'), _('If set, the meaning of the match options is inverted')); + o.modalonly = true; + o.default = o.disabled; + + o = s.taboption('advanced', form.Flag, 'disabled', _('Disable')); + o.modalonly = false; + o.editable = true; o.default = o.disabled; - o.rmempty = true; } return m.render(); diff --git a/luci-mod-network/htdocs/luci-static/resources/view/network/switch.js b/luci-mod-network/htdocs/luci-static/resources/view/network/switch.js old mode 100755 new mode 100644 index 3133d2725..535a133e7 --- a/luci-mod-network/htdocs/luci-static/resources/view/network/switch.js +++ b/luci-mod-network/htdocs/luci-static/resources/view/network/switch.js @@ -180,8 +180,10 @@ return view.extend({ s = m.section(form.NamedSection, sid, 'switch', switch_title); s.addremove = false; - if (feat.vlan_option) - s.option(form.Flag, feat.vlan_option, _('Enable VLAN functionality')); + if (feat.vlan_option) { + o = s.option(form.Flag, feat.vlan_option, _('Enable VLAN functionality')); + o.rmempty = false; + } if (feat.learning_option) { o = s.option(form.Flag, feat.learning_option, _('Enable learning and aging')); @@ -222,7 +224,7 @@ return view.extend({ s.filter = function(section_id) { var device = uci.get('network', section_id, 'device'); - return (device == switch_name); + return (device == this.device); }; s.cfgsections = function() { @@ -246,7 +248,7 @@ return view.extend({ max_vid = 0; for (var j = 0; j < sections.length; j++) { - if (sections[j].device != s.device) + if (sections[j].device != this.device) continue; var vlan = +sections[j].vlan, @@ -259,7 +261,7 @@ return view.extend({ max_vid = vid; } - uci.set('network', section_id, 'device', s.device); + uci.set('network', section_id, 'device', this.device); uci.set('network', section_id, 'vlan', max_vlan + 1); if (feat.vid_option) @@ -268,8 +270,6 @@ return view.extend({ return this.map.save(null, true); }; - var port_opts = []; - o = s.option(form.Value, feat.vid_option || 'vlan', 'VLAN ID'); o.rmempty = false; o.forcewrite = true; @@ -297,21 +297,23 @@ return view.extend({ return true; }; + var port_opts = o.port_opts = []; + o.write = function(section_id, value) { var topology = this.section.topology, values = []; - for (var i = 0; i < port_opts.length; i++) { - var tagging = port_opts[i].formvalue(section_id), + for (var i = 0; i < this.port_opts.length; i++) { + var tagging = this.port_opts[i].formvalue(section_id), portspec = Array.isArray(topology.ports) ? topology.ports[i] : null; if (tagging == 't') - values.push(port_opts[i].option + tagging); + values.push(this.port_opts[i].option + tagging); else if (tagging == 'u') - values.push(port_opts[i].option); + values.push(this.port_opts[i].option); if (portspec && portspec.device) { - var old_tag = port_opts[i].cfgvalue(section_id), + var old_tag = this.port_opts[i].cfgvalue(section_id), old_vid = this.cfgvalue(section_id); if (old_tag != tagging || old_vid != value) { diff --git a/luci-mod-network/htdocs/luci-static/resources/view/network/wireless.js b/luci-mod-network/htdocs/luci-static/resources/view/network/wireless.js old mode 100755 new mode 100644 index 5115a69eb..6b1bd262f --- a/luci-mod-network/htdocs/luci-static/resources/view/network/wireless.js +++ b/luci-mod-network/htdocs/luci-static/resources/view/network/wireless.js @@ -314,24 +314,16 @@ var CBIWifiFrequencyValue = form.Value.extend({ this.channels = { '2g': L.hasSystemFeature('hostapd', 'acs') ? [ 'auto', 'auto', true ] : [], '5g': L.hasSystemFeature('hostapd', 'acs') ? [ 'auto', 'auto', true ] : [], - '6g': [], + '6g': L.hasSystemFeature('hostapd', 'acs') ? [ 'auto', 'auto', true ] : [], '60g': [] }; for (var i = 0; i < data[1].length; i++) { - var band; - - if (data[1][i].mhz >= 2412 && data[1][i].mhz <= 2484) - band = '2g'; - else if (data[1][i].mhz >= 5160 && data[1][i].mhz <= 5885) - band = '5g'; - else if (data[1][i].mhz >= 5925 && data[1][i].mhz <= 7125) - band = '6g'; - else if (data[1][i].mhz >= 58329 && data[1][i].mhz <= 69120) - band = '60g'; - else + if (!data[1][i].band) continue; + var band = '%dg'.format(data[1][i].band); + this.channels[band].push( data[1][i].channel, '%d (%d Mhz)'.format(data[1][i].channel, data[1][i].mhz), @@ -343,10 +335,10 @@ var CBIWifiFrequencyValue = form.Value.extend({ .reduce(function(o, v) { o[v] = true; return o }, {}); this.modes = [ - '', 'Legacy', true, + '', 'Legacy', hwmodelist.a || hwmodelist.b || hwmodelist.g, 'n', 'N', hwmodelist.n, - 'ac', 'AC', hwmodelist.ac, - 'ax', 'AX', hwmodelist.ax + 'ac', 'AC', L.hasSystemFeature('hostapd', '11ac') && hwmodelist.ac, + 'ax', 'AX', L.hasSystemFeature('hostapd', '11ax') && hwmodelist.ax ]; var htmodelist = L.toArray(data[0] ? data[0].getHTModes() : null) @@ -375,7 +367,8 @@ var CBIWifiFrequencyValue = form.Value.extend({ this.bands = { '': [ '2g', '2.4 GHz', this.channels['2g'].length > 3, - '5g', '5 GHz', this.channels['5g'].length > 3 + '5g', '5 GHz', this.channels['5g'].length > 3, + '60g', '60 GHz', this.channels['60g'].length > 0 ], 'n': [ '2g', '2.4 GHz', this.channels['2g'].length > 3, @@ -386,7 +379,8 @@ var CBIWifiFrequencyValue = form.Value.extend({ ], 'ax': [ '2g', '2.4 GHz', this.channels['2g'].length > 3, - '5g', '5 GHz', this.channels['5g'].length > 3 + '5g', '5 GHz', this.channels['5g'].length > 3, + '6g', '6 GHz', this.channels['6g'].length > 3 ] }; }, this)); @@ -479,7 +473,7 @@ var CBIWifiFrequencyValue = form.Value.extend({ this.toggleWifiBand(elem); bwdt.value = htval; - chan.value = chval || chan.options[0].value; + chan.value = chval || (chan.options[0] ? chan.options[0].value : 'auto'); return elem; }, @@ -741,7 +735,8 @@ return view.extend({ load: function() { return Promise.all([ uci.changes(), - uci.load('wireless') + uci.load('wireless'), + uci.load('system') ]); }, @@ -941,7 +936,7 @@ return view.extend({ if (hwtype == 'mac80211') { o = ss.taboption('general', form.Flag, 'legacy_rates', _('Allow legacy 802.11b rates'), _('Legacy or badly behaving devices may require legacy 802.11b rates to interoperate. Airtime efficiency may be significantly reduced where these are used. It is recommended to not allow 802.11b rates where possible.')); - o.depends({'_freq': '11g', '!contains': true}); + o.depends({'_freq': '2g', '!contains': true}); o = ss.taboption('general', CBIWifiTxPowerValue, 'txpower', _('Maximum transmit power'), _('Specifies the maximum transmit power the wireless radio may use. Depending on regulatory requirements and wireless usage, the actual transmit power may be reduced by the driver.')); o.wifiNetwork = radioNet; @@ -985,6 +980,7 @@ return view.extend({ ss.tab('encryption', _('Wireless Security')); ss.tab('macfilter', _('MAC-Filter')); ss.tab('advanced', _('Advanced Settings')); + ss.tab('roaming', _('WLAN roaming'), _('Settings for assisting wireless clients in roaming between multiple APs: 802.11r, 802.11k and 802.11v')); o = ss.taboption('general', form.ListValue, 'mode', _('Mode')); o.value('ap', _('Access Point')); @@ -1089,6 +1085,7 @@ return view.extend({ o = ss.taboption('macfilter', form.DynamicList, 'maclist', _('MAC-List')); o.datatype = 'macaddr'; + o.retain = true; o.depends('macfilter', 'allow'); o.depends('macfilter', 'deny'); o.load = function(section_id) { @@ -1144,16 +1141,27 @@ return view.extend({ o.depends('mode', 'ap-wds'); o.default = o.enabled; + /* https://w1.fi/cgit/hostap/commit/?id=34f7c699a6bcb5c45f82ceb6743354ad79296078 */ + /* multicast_to_unicast https://github.com/openwrt/openwrt/commit/7babb978ad9d7fc29acb1ff86afb1eb343af303a */ + o = ss.taboption('advanced', form.Flag, 'multicast_to_unicast', _('Multi To Unicast'), _('ARP, IPv4 and IPv6 (even 802.1Q) with multicast destination MACs are unicast to the STA MAC address. Note: This is not Directed Multicast Service (DMS) in 802.11v. Note: might break receiver STA multicast expectations.')); + o.rmempty = true; + o = ss.taboption('advanced', form.Flag, 'isolate', _('Isolate Clients'), _('Prevents client-to-client communication')); o.depends('mode', 'ap'); o.depends('mode', 'ap-wds'); o = ss.taboption('advanced', form.Value, 'ifname', _('Interface name'), _('Override default interface name')); o.optional = true; + o.datatype = 'netdevname'; o.placeholder = radioNet.getIfname(); if (/^radio\d+\.network/.test(o.placeholder)) o.placeholder = ''; + o = ss.taboption('advanced', form.Value, 'macaddr', _('MAC address'), _('Override default MAC address - the range of usable addresses might be limited by the driver')); + o.optional = true; + o.placeholder = radioNet.getActiveBSSID(); + o.datatype = 'macaddr'; + o = ss.taboption('advanced', form.Flag, 'short_preamble', _('Short Preamble')); o.default = o.enabled; @@ -1171,7 +1179,7 @@ return view.extend({ o.optional = true; o.datatype = 'uinteger'; - o = ss.taboption('advanced', form.Value, 'max_inactivity', _('Station inactivity limit'), _('sec')); + o = ss.taboption('advanced', form.Value, 'max_inactivity', _('Station inactivity limit'), _('802.11v: BSS Max Idle. Units: seconds.')); o.optional = true; o.placeholder = 300; o.datatype = 'uinteger'; @@ -1274,7 +1282,7 @@ return view.extend({ if (has_hostapd || has_supplicant) { crypto_modes.push(['psk2', 'WPA2-PSK', 35]); crypto_modes.push(['psk-mixed', 'WPA-PSK/WPA2-PSK Mixed Mode', 22]); - crypto_modes.push(['psk', 'WPA-PSK', 21]); + crypto_modes.push(['psk', 'WPA-PSK', 12]); } else { encr.description = _('WPA-Encryption requires wpa_supplicant (for client mode) or hostapd (for AP and ad-hoc mode) to be installed.'); @@ -1374,7 +1382,7 @@ return view.extend({ else if (hwtype == 'broadcom') { crypto_modes.push(['psk2', 'WPA2-PSK', 33]); crypto_modes.push(['psk+psk2', 'WPA-PSK/WPA2-PSK Mixed Mode', 22]); - crypto_modes.push(['psk', 'WPA-PSK', 21]); + crypto_modes.push(['psk', 'WPA-PSK', 12]); crypto_modes.push(['wep-open', _('WEP Open System'), 11]); crypto_modes.push(['wep-shared', _('WEP Shared Key'), 10]); } @@ -1392,51 +1400,90 @@ return view.extend({ } - o = ss.taboption('encryption', form.Value, 'auth_server', _('Radius-Authentication-Server')); + o = ss.taboption('encryption', form.Value, 'auth_server', _('RADIUS Authentication Server')); add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] }); o.rmempty = true; o.datatype = 'host(0)'; - o = ss.taboption('encryption', form.Value, 'auth_port', _('Radius-Authentication-Port'), _('Default %d').format(1812)); + o = ss.taboption('encryption', form.Value, 'auth_port', _('RADIUS Authentication Port')); add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] }); o.rmempty = true; o.datatype = 'port'; + o.placeholder = '1812'; - o = ss.taboption('encryption', form.Value, 'auth_secret', _('Radius-Authentication-Secret')); + o = ss.taboption('encryption', form.Value, 'auth_secret', _('RADIUS Authentication Secret')); add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] }); o.rmempty = true; o.password = true; - o = ss.taboption('encryption', form.Value, 'acct_server', _('Radius-Accounting-Server')); + o = ss.taboption('encryption', form.Value, 'acct_server', _('RADIUS Accounting Server')); add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] }); o.rmempty = true; o.datatype = 'host(0)'; - o = ss.taboption('encryption', form.Value, 'acct_port', _('Radius-Accounting-Port'), _('Default %d').format(1813)); + o = ss.taboption('encryption', form.Value, 'acct_port', _('RADIUS Accounting Port')); add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] }); o.rmempty = true; o.datatype = 'port'; + o.placeholder = '1813'; - o = ss.taboption('encryption', form.Value, 'acct_secret', _('Radius-Accounting-Secret')); + o = ss.taboption('encryption', form.Value, 'acct_secret', _('RADIUS Accounting Secret')); add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] }); o.rmempty = true; o.password = true; - o = ss.taboption('encryption', form.Value, 'dae_client', _('DAE-Client')); + /* extra RADIUS settings start */ + o = ss.taboption('encryption', form.ListValue, 'dynamic_vlan', _('RADIUS Dynamic VLAN Assignment'), _('Required: Rejects auth if RADIUS server does not provide appropriate VLAN attributes.')); + add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] }); + o.value('0', _('Disabled')); + o.value('1', _('Optional')); + o.value('2', _('Required')); + o.write = function (section_id, value) { + return this.super('write', [section_id, (value == 0) ? null: value]); + } + + o = ss.taboption('encryption', form.Flag, 'per_sta_vif', _('RADIUS Per STA VLAN'), _('Each STA is assigned its own AP_VLAN interface.')); + add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] }); + + //hostapd internally defaults to vlan_naming=1 even with dynamic VLAN off + o = ss.taboption('encryption', form.Flag, 'vlan_naming', _('RADIUS VLAN Naming'), _('Off: vlanXXX, e.g., vlan1. On: vlan_tagged_interface.XXX, e.g. eth0.1.')); + add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] }); + + o = ss.taboption('encryption', widgets.DeviceSelect, 'vlan_tagged_interface', _('RADIUS VLAN Tagged Interface'), _('E.g. eth0, eth1')); + add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] }); + o.size = 1; + o.rmempty = true; + o.multiple = false; + o.noaliases = true; + o.nobridges = true; + o.nocreate = true; + o.noinactive = true; + + o = ss.taboption('encryption', form.Value, 'vlan_bridge', _('RADIUS VLAN Bridge Naming Scheme'), _('E.g. br-vlan or brvlan.')); + add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] }); + o.rmempty = true; + /* extra RADIUS settings end */ + + o = ss.taboption('encryption', form.Value, 'dae_client', _('DAE-Client'), _('Dynamic Authorization Extension client.')); add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] }); o.rmempty = true; o.datatype = 'host(0)'; - o = ss.taboption('encryption', form.Value, 'dae_port', _('DAE-Port'), _('Default %d').format(3799)); + o = ss.taboption('encryption', form.Value, 'dae_port', _('DAE-Port'), _('Dynamic Authorization Extension port.')); add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] }); o.rmempty = true; o.datatype = 'port'; + o.placeholder = '3799'; - o = ss.taboption('encryption', form.Value, 'dae_secret', _('DAE-Secret')); + o = ss.taboption('encryption', form.Value, 'dae_secret', _('DAE-Secret'), _('Dynamic Authorization Extension secret.')); add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] }); o.rmempty = true; o.password = true; + //WPA(1) has only WPA IE. Only >= WPA2 has RSN IE Preauth frames. + o = ss.taboption('encryption', form.Flag, 'rsn_preauth', _('RSN Preauth'), _('Robust Security Network (RSN): Allow roaming preauth for WPA2-EAP networks (and advertise it in WLAN beacons). Only works if the specified network interface is a bridge. Shortens the time-critical reassociation process.')); + add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['wpa2', 'wpa3', 'wpa3-mixed'] }); + o = ss.taboption('encryption', form.Value, '_wpa_key', _('Key')); o.depends('encryption', 'psk'); @@ -1500,66 +1547,117 @@ return view.extend({ // Probe 802.11r support (and EAP support as a proxy for Openwrt) var has_80211r = L.hasSystemFeature('hostapd', '11r') || L.hasSystemFeature('hostapd', 'eap'); - o = ss.taboption('encryption', form.Flag, 'ieee80211r', _('802.11r Fast Transition'), _('Enables fast roaming among access points that belong to the same Mobility Domain')); + o = ss.taboption('roaming', form.Flag, 'ieee80211r', _('802.11r Fast Transition'), _('Enables fast roaming among access points that belong to the same Mobility Domain')); add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] }); if (has_80211r) add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['psk', 'psk2', 'psk-mixed', 'sae', 'sae-mixed'] }); o.rmempty = true; - o = ss.taboption('encryption', form.Value, 'nasid', _('NAS ID'), _('Used for two different purposes: RADIUS NAS ID and 802.11r R0KH-ID. Not needed with normal WPA(2)-PSK.')); + o = ss.taboption('roaming', form.Value, 'nasid', _('NAS ID'), _('Used for two different purposes: RADIUS NAS ID and 802.11r R0KH-ID. Not needed with normal WPA(2)-PSK.')); add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] }); o.depends({ ieee80211r: '1' }); o.rmempty = true; - o = ss.taboption('encryption', form.Value, 'mobility_domain', _('Mobility Domain'), _('4-character hexadecimal ID')); + o = ss.taboption('roaming', form.Value, 'mobility_domain', _('Mobility Domain'), _('4-character hexadecimal ID')); o.depends({ ieee80211r: '1' }); o.placeholder = '4f57'; o.datatype = 'and(hexstring,length(4))'; o.rmempty = true; - o = ss.taboption('encryption', form.Value, 'reassociation_deadline', _('Reassociation Deadline'), _('time units (TUs / 1.024 ms) [1000-65535]')); + o = ss.taboption('roaming', form.Value, 'reassociation_deadline', _('Reassociation Deadline'), _('time units (TUs / 1.024 ms) [1000-65535]')); o.depends({ ieee80211r: '1' }); o.placeholder = '1000'; o.datatype = 'range(1000,65535)'; o.rmempty = true; - o = ss.taboption('encryption', form.ListValue, 'ft_over_ds', _('FT protocol')); + o = ss.taboption('roaming', form.ListValue, 'ft_over_ds', _('FT protocol')); o.depends({ ieee80211r: '1' }); - o.value('1', _('FT over DS')); o.value('0', _('FT over the Air')); + o.value('1', _('FT over DS')); o.rmempty = true; - o = ss.taboption('encryption', form.Flag, 'ft_psk_generate_local', _('Generate PMK locally'), _('When using a PSK, the PMK can be automatically generated. When enabled, the R0/R1 key options below are not applied. Disable this to use the R0 and R1 key options.')); + o = ss.taboption('roaming', form.Flag, 'ft_psk_generate_local', _('Generate PMK locally'), _('When using a PSK, the PMK can be automatically generated. When enabled, the R0/R1 key options below are not applied. Disable this to use the R0 and R1 key options.')); o.depends({ ieee80211r: '1' }); o.default = o.enabled; o.rmempty = false; - o = ss.taboption('encryption', form.Value, 'r0_key_lifetime', _('R0 Key Lifetime'), _('minutes')); + o = ss.taboption('roaming', form.Value, 'r0_key_lifetime', _('R0 Key Lifetime'), _('minutes')); o.depends({ ieee80211r: '1' }); o.placeholder = '10000'; o.datatype = 'uinteger'; o.rmempty = true; - o = ss.taboption('encryption', form.Value, 'r1_key_holder', _('R1 Key Holder'), _('6-octet identifier as a hex string - no colons')); + o = ss.taboption('roaming', form.Value, 'r1_key_holder', _('R1 Key Holder'), _('6-octet identifier as a hex string - no colons')); o.depends({ ieee80211r: '1' }); o.placeholder = '00004f577274'; o.datatype = 'and(hexstring,length(12))'; o.rmempty = true; - o = ss.taboption('encryption', form.Flag, 'pmk_r1_push', _('PMK R1 Push')); + o = ss.taboption('roaming', form.Flag, 'pmk_r1_push', _('PMK R1 Push')); o.depends({ ieee80211r: '1' }); o.placeholder = '0'; o.rmempty = true; - o = ss.taboption('encryption', form.DynamicList, 'r0kh', _('External R0 Key Holder List'), _('List of R0KHs in the same Mobility Domain.
Format: MAC-address,NAS-Identifier,128-bit key as hex string.
This list is used to map R0KH-ID (NAS Identifier) to a destination MAC address when requesting PMK-R1 key from the R0KH that the STA used during the Initial Mobility Domain Association.')); + o = ss.taboption('roaming', form.DynamicList, 'r0kh', _('External R0 Key Holder List'), _('List of R0KHs in the same Mobility Domain.
Format: MAC-address,NAS-Identifier,128-bit key as hex string.
This list is used to map R0KH-ID (NAS Identifier) to a destination MAC address when requesting PMK-R1 key from the R0KH that the STA used during the Initial Mobility Domain Association.')); o.depends({ ieee80211r: '1' }); o.rmempty = true; - o = ss.taboption('encryption', form.DynamicList, 'r1kh', _('External R1 Key Holder List'), _ ('List of R1KHs in the same Mobility Domain.
Format: MAC-address,R1KH-ID as 6 octets with colons,128-bit key as hex string.
This list is used to map R1KH-ID to a destination MAC address when sending PMK-R1 key from the R0KH. This is also the list of authorized R1KHs in the MD that can request PMK-R1 keys.')); + o = ss.taboption('roaming', form.DynamicList, 'r1kh', _('External R1 Key Holder List'), _ ('List of R1KHs in the same Mobility Domain.
Format: MAC-address,R1KH-ID as 6 octets with colons,128-bit key as hex string.
This list is used to map R1KH-ID to a destination MAC address when sending PMK-R1 key from the R0KH. This is also the list of authorized R1KHs in the MD that can request PMK-R1 keys.')); o.depends({ ieee80211r: '1' }); o.rmempty = true; // End of 802.11r options + // Probe 802.11k and 802.11v support via EAP support (full hostapd has EAP) + if (L.hasSystemFeature('hostapd', 'eap')) { + /* 802.11k settings start */ o = + ss.taboption('roaming', form.Flag, 'ieee80211k', _('802.11k RRM'), _('Radio Resource Measurement - Sends beacons to assist roaming. Not all clients support this.')); + // add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['psk', 'psk2', 'psk-mixed', 'sae', 'sae-mixed'] }); + o.depends('mode', 'ap'); + o.depends('mode', 'ap-wds'); + + o = ss.taboption('roaming', form.Flag, 'rrm_neighbor_report', _('Neighbour Report'), _('802.11k: Enable neighbor report via radio measurements.')); + o.depends({ ieee80211k: '1' }); + o.default = o.enabled; + + o = ss.taboption('roaming', form.Flag, 'rrm_beacon_report', _('Beacon Report'), _('802.11k: Enable beacon report via radio measurements.')); + o.depends({ ieee80211k: '1' }); + o.default = o.enabled; + /* 802.11k settings end */ + + /* 802.11v settings start */ + o = ss.taboption('roaming', form.ListValue, 'time_advertisement', _('Time advertisement'), _('802.11v: Time Advertisement in management frames.')); + o.value('0', _('Disabled')); + o.value('2', _('Enabled')); + o.write = function (section_id, value) { + return this.super('write', [section_id, (value == 2) ? value: null]); + } + + //Pull current System TZ setting + var tz = uci.get('system', '@system[0]', 'timezone'); + o = ss.taboption('roaming', form.Value, 'time_zone', _('Time zone'), _('802.11v: Local Time Zone Advertisement in management frames.')); + o.value(tz); + o.rmempty = true; + + o = ss.taboption('roaming', form.Flag, 'wnm_sleep_mode', _('WNM Sleep Mode'), _('802.11v: Wireless Network Management (WNM) Sleep Mode (extended sleep mode for stations).')); + o.rmempty = true; + + /* wnm_sleep_mode_no_keys: https://git.openwrt.org/?p=openwrt/openwrt.git;a=commitdiff;h=bf98faaac8ed24cf7d3d93dd4fcd7304d109363b */ + o = ss.taboption('roaming', form.Flag, 'wnm_sleep_mode_no_keys', _('WNM Sleep Mode Fixes'), _('802.11v: Wireless Network Management (WNM) Sleep Mode Fixes: Prevents reinstallation attacks.')); + o.rmempty = true; + + o = ss.taboption('roaming', form.Flag, 'bss_transition', _('BSS Transition'), _('802.11v: Basic Service Set (BSS) transition management.')); + o.rmempty = true; + + /* in master, but not 21.02.1: proxy_arp */ + o = ss.taboption('roaming', form.Flag, 'proxy_arp', _('ProxyARP'), _('802.11v: Proxy ARP enables non-AP STA to remain in power-save for longer.')); + o.rmempty = true; + + /* TODO: na_mcast_to_ucast is missing: needs adding to hostapd.sh - nice to have */ + } + /* 802.11v settings end */ + } + + if (hwtype == 'mac80211') { o = ss.taboption('encryption', form.ListValue, 'eap_type', _('EAP-Method')); o.value('tls', 'TLS'); o.value('ttls', 'TTLS'); @@ -1676,7 +1774,7 @@ return view.extend({ if (hwtype == 'mac80211') { // ieee802.11w options o = ss.taboption('encryption', form.ListValue, 'ieee80211w', _('802.11w Management Frame Protection'), _("Note: Some wireless drivers do not fully support 802.11w. E.g. mwlwifi may have problems")); - o.value('', _('Disabled')); + o.value('0', _('Disabled')); o.value('1', _('Optional')); o.value('2', _('Required')); add_dependency_permutations(o, { mode: ['ap', 'ap-wds', 'sta', 'sta-wds'], encryption: ['owe', 'psk2', 'psk-mixed', 'sae', 'sae-mixed', 'wpa2', 'wpa3', 'wpa3-mixed'] }); @@ -1684,7 +1782,14 @@ return view.extend({ o.defaults = { '2': [{ encryption: 'sae' }, { encryption: 'owe' }, { encryption: 'wpa3' }, { encryption: 'wpa3-mixed' }], '1': [{ encryption: 'sae-mixed'}], - '': [] + '0': [] + }; + + o.write = function(section_id, value) { + if (value != this.default) + return form.ListValue.prototype.write.call(this, section_id, value); + else + return form.ListValue.prototype.remove.call(this, section_id); }; o = ss.taboption('encryption', form.Value, 'ieee80211w_max_timeout', _('802.11w maximum timeout'), _('802.11w Association SA Query maximum timeout')); @@ -1956,6 +2061,8 @@ return view.extend({ }); }); }).then(L.bind(function() { + ui.showModal(null, E('p', { 'class': 'spinning' }, [ _('Loading data…') ])); + return this.renderMoreOptionsModal(section_id); }, this)); }; diff --git a/luci-mod-network/root/usr/share/luci/menu.d/luci-mod-network.json b/luci-mod-network/root/usr/share/luci/menu.d/luci-mod-network.json old mode 100755 new mode 100644 index 188c695f3..2fa3cf6ab --- a/luci-mod-network/root/usr/share/luci/menu.d/luci-mod-network.json +++ b/luci-mod-network/root/usr/share/luci/menu.d/luci-mod-network.json @@ -46,35 +46,9 @@ } }, - "admin/network/dhcp": { - "title": "DHCP and DNS", - "order": 30, - "action": { - "type": "view", - "path": "network/dhcp" - }, - "depends": { - "acl": [ "luci-mod-network-dhcp" ], - "uci": { "dhcp": true } - } - }, - - "admin/network/hosts": { - "title": "Hostnames", - "order": 40, - "action": { - "type": "view", - "path": "network/hosts" - }, - "depends": { - "acl": [ "luci-mod-network-dhcp" ], - "uci": { "dhcp": true } - } - }, - "admin/network/routes": { - "title": "Static Routes", - "order": 50, + "title": "Routing", + "order": 30, "action": { "type": "view", "path": "network/routes" @@ -84,9 +58,23 @@ } }, + "admin/network/dhcp": { + "title": "DHCP and DNS", + "order": 40, + "action": { + "type": "view", + "path": "network/dhcp" + }, + "depends": { + "acl": [ "luci-mod-network-dhcp" ], + "fs": { "/usr/sbin/dnsmasq": "executable" }, + "uci": { "dhcp": true } + } + }, + "admin/network/diagnostics": { "title": "Diagnostics", - "order": 60, + "order": 50, "action": { "type": "view", "path": "network/diagnostics" diff --git a/luci-mod-network/root/usr/share/rpcd/acl.d/luci-mod-network.json b/luci-mod-network/root/usr/share/rpcd/acl.d/luci-mod-network.json old mode 100755 new mode 100644 index 6943d9563..b377f395f --- a/luci-mod-network/root/usr/share/rpcd/acl.d/luci-mod-network.json +++ b/luci-mod-network/root/usr/share/rpcd/acl.d/luci-mod-network.json @@ -8,7 +8,9 @@ "/proc/sys/net/ipv6/conf/*/mtu": [ "read" ], "/proc/sys/net/ipv6/conf/*/hop_limit": [ "read" ], "/usr/libexec/luci-peeraddr": [ "exec" ], - "/usr/lib/opkg/info/netifd.control": [ "read" ] + "/usr/lib/opkg/info/netifd.control": [ "read" ], + "/proc/sys/net/ipv[46]/conf/*": [ "read" ], + "/sys/class/net/*/brport/*": [ "read" ] }, "ubus": { "file": [ "exec" ], @@ -58,7 +60,8 @@ "/usr/bin/ping": [ "exec" ], "/usr/bin/ping6": [ "exec", "list" ], "/usr/bin/traceroute": [ "exec" ], - "/usr/bin/traceroute6": [ "exec", "list" ] + "/usr/bin/traceroute6": [ "exec", "list" ], + "/usr/bin/arp-scan": [ "exec", "list" ] }, "ubus": { "file": [ "exec", "stat" ] diff --git a/luci-proto-mbim/Makefile b/luci-proto-mbim/Makefile old mode 100755 new mode 100644 diff --git a/luci-proto-mbim/htdocs/luci-static/resources/protocol/mbim.js b/luci-proto-mbim/htdocs/luci-static/resources/protocol/mbim.js old mode 100755 new mode 100644 index 72bb9f7ba..f6f548cc6 --- a/luci-proto-mbim/htdocs/luci-static/resources/protocol/mbim.js +++ b/luci-proto-mbim/htdocs/luci-static/resources/protocol/mbim.js @@ -51,7 +51,8 @@ return network.registerProtocol('mbim', { renderFormOptions: function(s) { var dev = this.getL3Device() || this.getDevice(), o; - o = s.taboption('general', form.Value, 'device', _('Modem device')); + o = s.taboption('general', form.Value, '_modem_device', _('Modem device')); + o.ucioption = 'device'; o.rmempty = false; o.load = function(section_id) { return callFileList('/dev/').then(L.bind(function(devices) { @@ -61,14 +62,22 @@ return network.registerProtocol('mbim', { }, this)); }; - s.taboption('general', form.Value, 'apn', _('APN')); - s.taboption('general', form.Value, 'pincode', _('PIN')); + o = s.taboption('general', form.Value, 'apn', _('APN')); + o.validate = function(section_id, value) { + if (!/^[a-zA-Z0-9\-.]*[a-zA-Z0-9]$/.test(value)) + return _('Invalid APN provided'); + + return true; + }; + + o = s.taboption('general', form.Value, 'pincode', _('PIN')); + o.datatype = 'and(uinteger,minlength(4),maxlength(8))'; o = s.taboption('general', form.ListValue, 'auth', _('Authentication Type')); - o.value('both', 'PAP/CHAP'); - o.value('pap', 'PAP'); - o.value('chap', 'CHAP'); - o.value('none', 'NONE'); + o.value('both', _('PAP/CHAP')); + o.value('pap', _('PAP')); + o.value('chap', _('CHAP')); + o.value('none', _('None')); o.default = 'none'; o = s.taboption('general', form.Value, 'username', _('PAP/CHAP username')); @@ -82,19 +91,62 @@ return network.registerProtocol('mbim', { o.depends('auth', 'both'); o.password = true; + o = s.taboption('general', form.ListValue, 'pdptype', _('PDP Type')); + o.value('ipv4v6', _('IPv4/IPv6')); + o.value('ipv4', _('IPv4')); + o.value('ipv6', _('IPv6')); + o.default = 'ipv4v6'; + if (L.hasSystemFeature('ipv6')) { - o = s.taboption('advanced', form.Flag, 'ipv6', _('Enable IPv6 negotiation')); - o.default = o.disabled; + o = s.taboption('advanced', form.Flag, 'mbim_ipv6', _('Enable IPv6 negotiation')); + o.ucioption = 'ipv6'; + o.default = o.enabled; + } + + o = s.taboption('advanced', form.ListValue, 'dhcp', _('Use DHCP')); + o.value('', _('Automatic')); + o.value('0', _('Disabled')); + o.value('1', _('Enabled')); + o.depends('pdptype', 'ipv4'); + o.depends('pdptype', 'ipv4v6'); + o.default = ''; + + if (L.hasSystemFeature('ipv6')) { + o = s.taboption('advanced', form.ListValue, 'dhcpv6', _('Use DHCPv6')); + o.value('', _('Automatic')); + o.value('0', _('Disabled')); + o.value('1', _('Enabled')); + o.depends('pdptype', 'ipv6'); + o.depends('pdptype', 'ipv4v6'); + o.default = ''; } o = s.taboption('advanced', form.Value, 'delay', _('Modem init timeout'), _('Maximum amount of seconds to wait for the modem to become ready')); o.placeholder = '10'; o.datatype = 'min(1)'; - o = s.taboption('general', form.ListValue, 'pdptype', _('PDP Type')); - o.value('ipv4v6', 'IPv4/IPv6'); - o.value('ipv4', 'IPv4'); - o.value('ipv6', 'IPv6'); - o.default = 'ipv4v6'; + o = s.taboption('advanced', form.Value, 'mtu', _('Override MTU')); + o.placeholder = dev ? (dev.getMTU() || '1500') : '1500'; + o.datatype = 'max(9200)'; + + o = s.taboption('advanced', form.Flag, 'defaultroute', + _('Use default gateway'), + _('If unchecked, no default route is configured')); + o.default = o.enabled; + + o = s.taboption('advanced', form.Value, 'metric', + _('Use gateway metric')); + o.placeholder = '0'; + o.datatype = 'uinteger'; + o.depends('defaultroute', '1'); + + o = s.taboption('advanced', form.Flag, 'peerdns', + _('Use DNS servers advertised by peer'), + _('If unchecked, the advertised DNS server addresses are ignored')); + o.default = o.enabled; + + o = s.taboption('advanced', form.DynamicList, 'dns', _('Use custom DNS servers')); + o.depends('peerdns', '0'); + o.datatype = 'ipaddr'; } }); diff --git a/luci-theme-ezengreen/Makefile b/luci-theme-ezengreen/Makefile deleted file mode 100755 index ee17e224f..000000000 --- a/luci-theme-ezengreen/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -# -# Copyright (C) 2008-2014 The LuCI Team -# Copyright (C) 2018-2019 Ycarus (Yannick Chabanois) -# -# This is free software, licensed under the Apache License, Version 2.0 . -# - -include $(TOPDIR)/rules.mk - -LUCI_TITLE:=ezengreen Theme (default) -LUCI_DEPENDS:= - -#include ../luci/luci.mk -include $(TOPDIR)/feeds/luci/luci.mk - -# call BuildPackage - OpenWrt buildroot signature diff --git a/luci-theme-ezengreen/htdocs/luci-static/ezengreen/1omr-logo-apple.png b/luci-theme-ezengreen/htdocs/luci-static/ezengreen/1omr-logo-apple.png deleted file mode 100755 index 7ee7779108d5a958e17f305962fef3f5715fbafd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8175 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 - * Based on Bootstrap v1.4.0 - * - * Copyright 2011 Twitter, Inc - * Licensed under the Apache License v2.0 - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Designed and built with all the love in the world @twitter by @mdo and @fat. - */ -/* Reset.less - * Props to Eric Meyer (meyerweb.com) for his CSS reset file. We're using an adapted version here that cuts out some of the reset HTML elements we will never need here (i.e., dfn, samp, etc). - * ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- */ -html { - margin: 0; - padding: 0; -} - -body { - margin: 0; - padding: 5px; -} - -h1, h2, h3, h4, h5, h6, p, pre, a, abbr, acronym, code, del, em, img, ins, q, s, -small, strike, strong, sub, sup, tt, var, dd, dl, dt, li, ol, ul, fieldset, -form, label, legend, button, table, caption, tbody, tfoot, thead, tr, th, td, -.table, .tbody, .tfoot, .thead, .tr, .th, .td { - margin: 0; - padding: 0; - border: 0; - font-weight: normal; - font-style: normal; - font-size: 100%; - line-height: 1; - font-family: inherit; -} - -abbr[title], acronym[title] { - border-bottom: 1px dotted; - font-weight: inherit; - cursor: help; -} - -table { - border-collapse: collapse; - border-spacing: 0; -} - -ol, ul { - list-style: none; -} - -q:before, -q:after, -blockquote:before, -blockquote:after { - content: ""; -} - -html { - overflow-y: scroll; - font-size: 100%; - -webkit-text-size-adjust: 100%; - -ms-text-size-adjust: 100%; -} - -a:focus { - outline: thin dotted; -} - -a:hover, a:active { - outline: 0; -} - -article, -aside, -details, -figcaption, -figure, -footer, -header, -hgroup, -nav, -section { - display: block; -} - -sub, sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; -} - -sup { - top: -0.5em; -} - -sub { - bottom: -0.25em; -} - -img { - border: 0; - -ms-interpolation-mode: bicubic; -} - -button, -input, -select, -option, -textarea { - font-size: 100%; - margin: 0; - box-sizing: border-box; - vertical-align: baseline; - *vertical-align: middle; -} - -button, input { - line-height: normal; - *overflow: visible; -} - -button::-moz-focus-inner, input::-moz-focus-inner { - border: 0; - padding: 0; -} - -button, -input[type="button"], -input[type="reset"], -input[type="submit"] { - cursor: pointer; - -webkit-appearance: button; -} - -button[disabled], -input[type="button"][disabled], -input[type="reset"][disabled], -input[type="submit"][disabled] { - opacity: 0.7; -} - -input[type="search"] { - -webkit-appearance: textfield; - box-sizing: content-box; -} - -input[type="search"]::-webkit-search-decoration { - -webkit-appearance: none; -} - -textarea { - overflow: auto; - vertical-align: top; -} - -/* - * Scaffolding - * Basic and global styles for generating a grid system, structural layout, and page templates - * ------------------------------------------------------------------------------------------- */ -body { - background-color: #fff; - margin: 0; - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 12px; - font-weight: normal; - line-height: 18px; - color: #404040; - padding-top: 75px; -} - -.container { - width: 100%; - max-width: 940px; - margin-left: auto; - margin-right: auto; - zoom: 1; -} - -.container:before, .container:after { - display: table; - content: ""; - zoom: 1; -} - -.container:after { - clear: both; -} - -a { - color: #215e21; - text-decoration: none; - line-height: inherit; - font-weight: inherit; -} - -a:hover { - color: #000000; - text-decoration: none; -} - -.pull-right { - float: right; -} - -.pull-left { - float: left; -} - -/* Typography.less - * Headings, body text, lists, code, and more for a versatile and durable typography system - * ---------------------------------------------------------------------------------------- */ -p, -.cbi-map-descr, -.cbi-section-descr, -.table .tr.cbi-section-table-descr .th { - font-size: 12px; - font-weight: normal; - line-height: 18px; - margin-bottom: 9px; -} - -p small { - font-size: 11px; - color: #bfbfbf; -} - -h1, -h2, -h3, legend, -h4, -h5, -h6 { - font-weight: normal; - color: #404040; -} - -h1 small, -h2 small, -h3 small, -h4 small, -h5 small, -h6 small { - color: #bfbfbf; -} - -h1 { - margin-bottom: 18px; - font-size: 30px; - line-height: 36px; -} - -h1 small { - font-size: 18px; -} - -h2 { - font-size: 24px; - line-height: 58px; - text-transform: uppercase; - font-weight: normal; -} - -h2 small { - font-size: 14px; -} - -h3, legend, -h4, -h5, -h6 { - line-height: 48px; -} - -h3, legend { - font-size: 18px; -} - -h3 small { - font-size: 14px; -} - -h4 { - font-size: 16px; -} - -h4 small { - font-size: 12px; -} - -h5 { - font-size: 14px; -} - -h6 { - font-size: 13px; - color: #bfbfbf; - text-transform: uppercase; -} - -ul, ol { - margin: 0 0 18px 25px; -} - -ul ul, -ul ol, -ol ol, -ol ul { - margin-bottom: 0; -} - -ul { - list-style: disc; -} - -ol { - list-style: decimal; -} - -li { - line-height: 18px; - color: #808080; -} - -ul.unstyled { - list-style: none; - margin-left: 0; -} - -dl { - margin-bottom: 18px; -} - -dl dt, dl dd { - line-height: 18px; -} - -dl dt { - font-weight: bold; -} - -dl dd { - margin-left: 9px; -} - -hr { - margin: 20px 0 19px; - border: 0; - border-bottom: 1px solid #eee; -} - -strong { - font-style: inherit; - font-weight: bold; -} - -em { - font-style: italic; - font-weight: inherit; - line-height: inherit; -} - -small { font-size: 0.9em } - -address { - display: block; - line-height: 18px; - margin-bottom: 18px; -} - -code, pre { - padding: 0 3px 2px; - font-family: Monaco, Andale Mono, Courier New, monospace; - font-size: 12px; - border-radius: 2px; -} - -code { - background-color: #fee9cc; - color: rgba(0, 0, 0, 0.75); - padding: 1px 3px; -} - -pre { - background-color: #f5f5f5; - display: block; - padding: 8.5px; - margin: 0 0 18px; - line-height: 18px; - font-size: 12px; - border: 1px solid #ccc; - border: 1px solid rgba(0, 0, 0, 0.15); - border-radius: 2px; - white-space: pre; - white-space: pre-wrap; - word-wrap: break-word; -} - -/* Forms.less - * Base styles for various input types, form layouts, and states - * ------------------------------------------------------------- */ -form { - margin-bottom: 18px; -} - -fieldset { - margin-bottom: 9px; - padding-top: 9px; -} - -fieldset legend { - display: block; - font-size: 19.5px; - line-height: 1; - color: #404040; - padding-top: 20px; - *padding: 0 0 5px 0px; - /* IE6-7 */ - - *line-height: 1.5; - /* IE6-7 */ - -} -form .cbi-tab-descr { - line-height: 18px; - margin-bottom: 18px; -} - -form .clearfix, -form .cbi-value { - margin-bottom: 15px; - margin-top: 15px; - zoom: 1; -} - -form .clearfix:before, form .clearfix:after, -form .cbi-value:before, form .cbi-value:after { - display: table; - content: ""; - zoom: 1; -} - -form .clearfix:after, -form .cbi-value:after { - clear: both; -} - -label, -input, -select, -textarea { - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 12px; - font-weight: normal; - line-height: normal; -} - -form .input, -form .cbi-value-field { - margin-left: 120px; -} - -form .cbi-value label.cbi-value-title { - padding-top: 6px; - font-size: 12px; - line-height: 18px; - float: left; - width: 111px; - text-align: left; - color: #404040; -} - -input[type=checkbox], input[type=radio] { - cursor: pointer; -} - -input, -textarea, -select, -.cbi-dropdown, -.uneditable-input { - display: inline-block; - width: 200px; - height: 30px; - padding: 4px; - font-size: 12px; - line-height: 18px; - color: #808080; - border: 1px solid #ccc; - border-radius: 2px; - box-sizing: border-box; - margin: 2px 0; -} - -.cbi-dropdown { - min-width: 210px; - max-width: 400px; - width: auto; -} - -select { - padding: initial; - background: #fff; - box-shadow: inset 0 -1px 3px rgba(0, 0, 0, 0.1); -} - -input[type=checkbox], input[type=radio] { - width: auto; - height: auto; - padding: 0; - margin: 3px 0; - *margin-top: 0; - /* IE6-7 */ - - line-height: normal; - border: none; -} - -input[type=file] { - background-color: #fff; - padding: initial; - border: initial; - line-height: initial; - box-shadow: none; - width: auto !important; -} - -input[type=button], input[type=reset], input[type=submit] { - width: auto; - height: auto; -} - -select, input[type=file] { - *height: auto; - *margin-top: 4px; - /* For IE7, add top margin to align select with labels */ -} - -select[multiple] { - height: inherit; - background-color: #fff; -} - -textarea { - height: auto; -} - -.td > input[type=text], -.td > input[type=password], -.td > select, -.td > .cbi-dropdown { - width: 100%; -} - -.uneditable-input { - background-color: #fff; - display: block; - border-color: #eee; - box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); - cursor: not-allowed; -} - -::-moz-placeholder { - color: #bfbfbf; -} - -::-webkit-input-placeholder { - color: #bfbfbf; -} - -.btn, .cbi-button, input, textarea { - transition: border linear 0.2s, box-shadow linear 0.2s; - box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1); - padding: 12px 6px; -} - -.btn:hover, .cbi-button:hover, -input:focus, textarea:focus { - outline: 0; - border-color: rgba(82, 168, 236, 0.8) !important; - box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6); - text-decoration: none; -} - -input[type=file]:focus, input[type=checkbox]:focus, select:focus { - box-shadow: none; - outline: 1px dotted #666; -} - -input[disabled], -select[disabled], -textarea[disabled], -input[readonly], -select[readonly], -textarea[readonly] { - background-color: #194119; - border-color: #ccc; - padding: 5px; - pointer-events: none; - cursor: default; -} - -select[readonly], -textarea[readonly] { - pointer-events: auto; - cursor: auto; -} - -.cbi-optionals, -.cbi-section-create { - padding: 0 0 10px 10px; -} - -.cbi-section-create { - margin: 10px 0 0 -10px; - display: inline-flex; - align-items: center; -} - -.cbi-section-create > * { - margin: 3px; - flex: 1 1 auto; -} - -.cbi-section-create > * > input { - width: 100%; -} - -.actions, -.cbi-page-actions { - background: #f5f5f5; - margin-bottom: 20px; - margin-top: 40px; - padding: 15px 20px 15px 20px; - border-radius: 0 0 2px 2px; - text-align: right; -} - -.actions .secondary-action, -.cbi-page-actions .secondary-action{ - float: right; -} - -.actions .secondary-action a, -.cbi-page-actions .secondary-action a { - line-height: 30px; -} - -.actions .secondary-action a:hover, -.cbi-page-actions .secondary-action a:hover { - text-decoration: none; -} - -.cbi-page-actions > form { - display: inline; - margin: 0; -} - -.help-inline, .help-block { - font-size: 12px; - line-height: 18px; - color: #bfbfbf; -} - -.help-inline { - padding-left: 5px; - *position: relative; - /* IE6-7 */ - - *top: -5px; - /* IE6-7 */ - -} - -.help-block { - display: block; - max-width: 600px; -} - -/* - * Tables.less - * Tables for, you guessed it, tabular data - * ---------------------------------------- */ -.tr { display: table-row; } -.table[width="33%"], .th[width="33%"], .td[width="33%"] { width: 33%; } -.table[width="100%"], .th[width="100%"], .td[width="100%"] { width: 100%; } - -.table { - display: table; - width: 100%; - margin: 12px 0 24px 0; - padding: 0; - font-size: 12px; - border-collapse: collapse; - position: relative; -} - -.table .th, .table .td { - display: table-cell; - vertical-align: middle; /* Fixme */ - padding: 6px 6px 6px 2px; - line-height: 18px; - text-align: left; -} - -.table .tr:first-child .th { - padding-top: 9px; - font-weight: normal; - vertical-align: top; -} - -.table .td, .table .th { - border-top: 1px solid #e7e7e7; -} - -.tr.placeholder { - height: calc(3em + 20px); -} - -.tr.placeholder > .td { - position: absolute; - left: 0; - right: 0; - bottom: 0; - text-align: center; - line-height: 3em; -} - -/* Patterns.less - * Repeatable UI elements outside the base styles provided from the scaffolding - * ---------------------------------------------------------------------------- */ -header { - height: 40px; - position: fixed; - top: 0; - left: 0; - right: 0; - z-index: 10000; - overflow: visible; - color: #BFBFBF; -} - -header a { - color: #c4c4c4; -} - -header h3 a:hover, header .brand:hover, header ul .active > a { - background-color: #333; - background-color: rgba(0, 0, 0, 0.33); - color: #fff; - text-decoration: none; -} - -header h3 { - position: relative; -} - -header h3 a, header .brand { - float: left; - display: block; - padding: 16px 20px 16px; - margin-left: -20px; - color: #fff; - font-size: 24px; - font-weight: 333; - line-height: 1; -} - -header p { - margin: 0; - line-height: 40px; -} - -header .fill { - background-color: #215e21; - background-repeat: repeat-x; - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.33), inset 0 -1px 0 rgba(0, 0, 0, 0.1); - padding: 0 5px; -} - -header div > ul, .nav { - display: block; - float: left; - margin: 0 10px 0 20px; - position: relative; - left: 0; -} - -header div > ul > li, .nav > li { - display: block; - float: left; -} - -header div > ul a, .nav a { - display: block; - float: none; - padding: 22px 12px 14px 12px; - line-height: 19px; - letter-spacing: 0.4px; - text-decoration: none; - text-transform: uppercase; -} - -header div > ul a:hover, .nav a:hover { - color: #fff; - text-decoration: none; -} - -header div > ul .active > a, .nav .active > a { - background-color: #222; - background-color: rgba(0, 0, 0, 0.33); -} - -header div > ul.secondary-nav, .nav.secondary-nav { - float: right; - margin-left: 10px; - margin-right: 0; -} - -header div > ul.secondary-nav .menu-dropdown, -.nav.secondary-nav .menu-dropdown, -header div > ul.secondary-nav .dropdown-menu, -.nav.secondary-nav .dropdown-menu { - right: 0; - border: 0; -} - -header div > ul a.menu:hover, -.nav a.menu:hover, -header div > ul li.open .menu, -.nav li.open .menu, -header div > ul .dropdown-toggle:hover, -.nav .dropdown-toggle:hover, -header div > ul .dropdown.open .dropdown-toggle, -.nav .dropdown.open .dropdown-toggle { - background: #444; - background: rgba(0, 0, 0, 0.3); -} - -header div > ul .menu-dropdown, -.nav .menu-dropdown, -header div > ul .dropdown-menu, -.nav .dropdown-menu { - background-color: #003300; -} - -header div > ul .menu-dropdown a.menu, -.nav .menu-dropdown a.menu, -header div > ul .dropdown-menu a.menu, -.nav .dropdown-menu a.menu, -header div > ul .menu-dropdown .dropdown-toggle, -.nav .menu-dropdown .dropdown-toggle, -header div > ul .dropdown-menu .dropdown-toggle, -.nav .dropdown-menu .dropdown-toggle { - color: #fff; -} - -header div > ul .menu-dropdown a.menu.open, -.nav .menu-dropdown a.menu.open, -header div > ul .dropdown-menu a.menu.open, -.nav .dropdown-menu a.menu.open, -header div > ul .menu-dropdown .dropdown-toggle.open, -.nav .menu-dropdown .dropdown-toggle.open, -header div > ul .dropdown-menu .dropdown-toggle.open, -.nav .dropdown-menu .dropdown-toggle.open { - background: #444; - background: rgba(255, 255, 255, 0.05); -} - -header div > ul .menu-dropdown li a, -.nav .menu-dropdown li a, -header div > ul .dropdown-menu li a, -.nav .dropdown-menu li a { - color: #bfbfbf; -} - -header div > ul .menu-dropdown li a:hover, -.nav .menu-dropdown li a:hover, -header div > ul .dropdown-menu li a:hover, -.nav .dropdown-menu li a:hover { - background-color: #215e21; - background-repeat: repeat-x; - color: #fff; -} - -header div > ul .menu-dropdown .active a, -.nav .menu-dropdown .active a, -header div > ul .dropdown-menu .active a, -.nav .dropdown-menu .active a { - color: #fff; -} - -header div > ul .menu-dropdown .divider, -.nav .menu-dropdown .divider, -header div > ul .dropdown-menu .divider, -.nav .dropdown-menu .divider { - background-color: #222; - border-color: #444; -} - -header ul .menu-dropdown li a, header ul .dropdown-menu li a { - padding: 6px 12px; -} - -li.menu, .dropdown { - position: relative; -} - -.menu-dropdown, .dropdown-menu { - background-color: #fff; - float: left; - position: absolute; - top: 55px; - left: -9999px; - z-index: 900; - min-width: 200px; - max-width: 300px; - _width: 160px; - margin-left: 0; - margin-right: 0; - padding: 6px 0; - zoom: 1; - border-radius: 0 0 2px 2px; - background-clip: padding-box; -} - -.menu-dropdown li, .dropdown-menu li { - float: none; - display: block; - background-color: transparent; -} - -.menu-dropdown .divider, .dropdown-menu .divider { - height: 1px; - margin: 5px 0; - overflow: hidden; - background-color: #eee; - border-bottom: 1px solid #fff; -} - -header .dropdown-menu a, .dropdown-menu a { - display: block; - padding: 4px 15px; - clear: both; - font-weight: normal; - line-height: 18px; - text-transform: capitalize; - letter-spacing: 0.2px; - color: #808080; - zoom: 1.1; -} - -header .dropdown-menu a:hover, -.dropdown-menu a:hover, -header .dropdown-menu a.hover, -.dropdown-menu a.hover { - background-color: #ddd; - background-repeat: repeat-x; - color: #404040; - text-decoration: none; - box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.025), inset 0 -1px rgba(0, 0, 0, 0.025); -} - -.open .menu, -.dropdown.open .menu, -.open .dropdown-toggle, -.dropdown.open .dropdown-toggle { - color: #fff; - background: #ccc; - background: rgba(0, 0, 0, 0.3); -} - -.open .menu-dropdown, -.dropdown.open .menu-dropdown, -.open .dropdown-menu, -.dropdown.open .dropdown-menu { - left: 0; -} - -.dropdown:hover ul.dropdown-menu { - left: 0; -} - -.dropdown-menu .dropdown-menu { - position: absolute; - left: 159px; -} - -.dropdown-menu li { - position: relative; -} - -.tabs, .cbi-tabmenu { - margin: 0 0 18px; - padding: 0; - list-style: none; - zoom: 1; -} - -.tabs:before, -.cbi-tabmenu:before, -.tabs:after, -.cbi-tabmenu:after { - display: table; - content: ""; - zoom: 1; -} - -.tabs:after, .cbi-tabmenu:after { - clear: both; -} - -.tabs > li, .cbi-tabmenu > li { - float: left; -} - -.tabs > li > a, .cbi-tabmenu > li > a { - display: block; -} - -.tabs, -.cbi-tabmenu { - border-color: #ddd; - border-style: solid; - border-width: 0 0 1px; -} - -.tabs > li, -.cbi-tabmenu > li { - position: relative; - margin-bottom: -1px; -} - -.cbi-tabmenu.map { - margin: 0; -} - -.cbi-tabmenu.map > li { - font-size: 16.5px; - font-weight: bold; -} - -.cbi-tabcontainer > fieldset.cbi-section[id] > legend { - display: none; -} - -.tabs > li > a, -.cbi-tabmenu > li > a { - padding: 0 15px; - margin-right: 2px; - line-height: 34px; - border: 1px solid transparent; - border-radius: 2px 2px 0 0; -} - -.tabs > li > a:hover, -.cbi-tabmenu > li > a:hover { - text-decoration: none; - background-color: #eee; - border-color: #eee #eee #ddd; -} - -.tabs .active > a, .tabs .active > a:hover, -.cbi-tabmenu .active > a, .cbi-tabmenu .active > a:hover, -.cbi-tab > a:link, .cbi-tab > a:hover { - color: #000000; - background-color: #fff; - border: 1px solid #ddd; - border-bottom-color: transparent; - cursor: default; -} - -.tabs .menu-dropdown, .tabs .dropdown-menu, -.cbi-tabmenu .menu-dropdown, .cbi-tabmenu .dropdown-menu { - top: 35px; - border-width: 1px; - border-radius: 0 2px 2px 2px; -} - -.tabs a.menu:after, .tabs .dropdown-toggle:after, -.cbi-tabmenu a.menu:after, .cbi-tabmenu .dropdown-toggle:after { - border-top-color: #999; - margin-top: 15px; - margin-left: 5px; -} - -.tabs li.open.menu .menu, .tabs .open.dropdown .dropdown-toggle, -.cbi-tabmenu li.open.menu .menu, .cbi-tabmenu .open.dropdown .dropdown-toggle { - border-color: #999; -} - -.tabs li.open a.menu:after, .tabs .dropdown.open .dropdown-toggle:after, -.cbi-tabmenu li.open a.menu:after, .cbi-tabmenu .dropdown.open .dropdown-toggle:after { - border-top-color: #555; -} - -.tab-content > .tab-pane, -.tab-content > div { - display: none; -} - -.tab-content > .active { - display: block; -} - -.breadcrumb { - padding: 7px 14px; - margin: 0 0 18px; - background-color: #f5f5f5; - background-repeat: repeat-x; - border: 1px solid #ddd; - border-radius: 2px; - box-shadow: inset 0 1px 0 #fff; -} - -.breadcrumb li { - display: inline; -} - -.breadcrumb .divider { - padding: 0 5px; - color: #bfbfbf; -} - -.breadcrumb .active a { - color: #404040; -} - -footer { - margin-top: 30px; - padding-top: 20px; - padding-bottom: 20px; - border-top: 1px solid #404040; -} - -.btn.danger, -.alert-message.danger, -.btn.danger:hover, -.alert-message.danger:hover, -.btn.error, -.alert-message.error, -.btn.error:hover, -.alert-message.error:hover, -.btn.success, -.alert-message.success, -.btn.success:hover, -.alert-message.success:hover, -.btn.info, -.alert-message.info, -.btn.info:hover, -.alert-message.info:hover { - color: #fff; -} - -.btn .close, .alert-message .close { - font-family: Arial, sans-serif; - line-height: 18px; -} - -.btn.danger, -.alert-message.danger, -.btn.error, -.alert-message.error { - background: linear-gradient(to bottom, #ee5f5b, #c43c35) repeat-x; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); -} - -.btn.success, .alert-message.success { - background: linear-gradient(to bottom, #62c462, #57a957) repeat-x; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); -} - -.btn.info, .alert-message.info { - background: linear-gradient(to bottom, #5bc0de, #339bb9) repeat-x; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); -} - -.alert-message.notice { - background: linear-gradient(to bottom, #efefef, #fefefe) repeat-x; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); -} - -.btn, -.cbi-button { - cursor: pointer; - display: inline-block; - background: linear-gradient(#fff, #fff 25%, #e6e6e6) no-repeat; - padding: 5px 14px 6px; - color: #333; - font-size: 12px; - line-height: normal; - border: 1px solid #ccc; - border-bottom-color: #bbb; - border-radius: 2px; - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); -} - -.btn:focus, -.cbi-button:focus { - outline: 1px dotted #666; -} - -.cbi-input-invalid, -.cbi-value-error input { - color: #f00; - border-color: #f00; -} - -.cbi-button-positive, -.cbi-button-fieldadd, -.cbi-button-add, -.cbi-button-save { - border-color: #4a4; - color: #4a4; -} - -.cbi-button-neutral, -.cbi-button-download, -.cbi-button-find, -.cbi-button-link, -.cbi-button-up, -.cbi-button-down { - color: #444; -} - -.btn.primary, -.cbi-button-action, -.cbi-button-apply, -.cbi-button-reload, -.cbi-button-edit { - border-color: #4aa44b; - color: #4aa44b; -} - -.cbi-button-negative, -.cbi-section-remove .cbi-button, -.cbi-button-reset, -.cbi-button-remove { - border-color: #c44; - color: #c44; -} - -.cbi-page-actions::after { - display: table; - content: ""; - clear: both; -} - -.cbi-page-actions > :not([method="post"]):not(.cbi-button-apply):not(.cbi-button-save):not(.cbi-button-reset) { - float: left; - margin-right: .4em; -} - -.btn.primary, -.cbi-button-action.important, -.cbi-page-actions .cbi-button-apply, -.cbi-section-actions .cbi-button-edit { - color: #fff; - background: #4aa44b; -} - -.cbi-button-positive.important, -.cbi-page-actions .cbi-button-save { - color: #fff; - background: linear-gradient(to bottom, #4a4, #484) no-repeat; -} - -.cbi-button-negative.important { - color: #fff; - background: linear-gradient(to bottom, #c44, #c00) no-repeat; -} - -.cbi-page-actions .cbi-button-apply + .cbi-button-save { - background: linear-gradient(#fff, #fff 25%, #e6e6e6); - color: #4a4; -} - -.cbi-dropdown { - border: 1px solid #ccc; - border-radius: 2px; - display: inline-flex; - padding: 0; - cursor: pointer; - height: auto; - background: linear-gradient(#fff 0%, #e9e8e6 100%); - position: relative; - color: #404040; -} - -.cbi-dropdown:focus { - outline: 2px solid #4b6e9b; -} - -.cbi-dropdown > ul { - margin: 0 !important; - padding: 0; - list-style: none; - overflow-x: hidden; - overflow-y: auto; - display: flex; - width: 100%; -} - -.cbi-dropdown > ul.preview { - display: none; -} - -.cbi-dropdown > .open, -.cbi-dropdown > .more { - flex-grow: 0; - flex-shrink: 0; - display: flex; - flex-direction: column; - justify-content: center; - text-align: center; - line-height: 2em; - padding: 0 .25em; -} - -.cbi-dropdown > .more, -.cbi-dropdown > ul > li[placeholder] { - color: #777; - font-weight: bold; - display: none; -} - -.cbi-dropdown > ul > li { - display: none; - padding: .25em; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - flex-shrink: 1; - flex-grow: 1; - align-items: center; - align-self: center; - color: #404040; - min-height: 20px; -} - -.cbi-dropdown > ul > li .hide-open { display: block; display: initial; } -.cbi-dropdown > ul > li .hide-close { display: none; } - -.cbi-dropdown > ul > li[display]:not([display="0"]) { - border-left: 1px solid #ccc; -} - -.cbi-dropdown[empty] > ul { - max-width: 1px; -} - -.cbi-dropdown > ul > li > form { - display: none; - margin: 0; - padding: 0; - pointer-events: none; -} - -.cbi-dropdown > ul > li img { - vertical-align: middle; - margin-right: .25em; -} - -.cbi-dropdown > ul > li > form > input[type="checkbox"] { - margin: 0; -} - -.cbi-dropdown > ul > li input[type="text"] { - height: 20px; -} - -.cbi-dropdown[open] { - position: relative; -} - -.cbi-dropdown[open] > ul.dropdown { - display: block; - background: #f6f6f5; - border: 1px solid #918e8c; - box-shadow: 0 0 4px #918e8c; - position: absolute; - z-index: 1000; - max-width: none; - min-width: 100%; - width: auto; -} - -.cbi-dropdown > ul > li[display], -.cbi-dropdown[open] > ul.preview, -.cbi-dropdown[open] > ul.dropdown > li, -.cbi-dropdown[multiple] > ul > li > label, -.cbi-dropdown[multiple][open] > ul.dropdown > li, -.cbi-dropdown[multiple][more] > .more, -.cbi-dropdown[multiple][empty] > .more { - flex-grow: 1; - display: flex; -} - -.cbi-dropdown[empty] > ul > li, -.cbi-dropdown[optional][open] > ul.dropdown > li[placeholder], -.cbi-dropdown[multiple][open] > ul.dropdown > li > form { - display: block; -} - -.cbi-dropdown[open] > ul.dropdown > li .hide-open { display: none; } -.cbi-dropdown[open] > ul.dropdown > li .hide-close { display: block; display: initial; } - -.cbi-dropdown[open] > ul.dropdown > li { - border-bottom: 1px solid #ccc; -} - -.cbi-dropdown[open] > ul.dropdown > li[selected] { - background: #b0d0f0; -} - -.cbi-dropdown[open] > ul.dropdown > li.focus { - background: linear-gradient(90deg, #a3c2e8 0%, #84aad9 100%); -} - -.cbi-dropdown[open] > ul.dropdown > li:last-child { - margin-bottom: 0; - border-bottom: none; -} - -.cbi-dropdown[disabled] { - pointer-events: none; - opacity: .6; -} - -input[type="text"] + .cbi-button, -input[type="password"] + .cbi-button, -select + .cbi-button { - border-radius: 2px; - border-color: #ccc; - margin: 2px 0 2px 3px; - padding: 0 12px; - vertical-align: top; - height: 28px; - font-size: 13px; - font-weight: normal; - line-height: 28px; -} - -select + .cbi-button { - #border-left-color: transparent; -} - -.cbi-title-ref { - color: #f39800; -} - -.cbi-title-ref::after { - content: " ➙ "; -} - -.cbi-tooltip-container { - cursor: help; - padding: 5px 3px 5px 3px; -} - -.cbi-tooltip { - position: absolute; - z-index: 1000; - left: -1000px; - opacity: 0; - transition: opacity .25s ease-out; -} - -.cbi-tooltip-container:hover .cbi-tooltip:not(:empty) { - left: auto; - opacity: 1; - transition: opacity .25s ease-in; -} - -.zonebadge .cbi-tooltip { - padding: 1px; - background: inherit; - margin: -1.6em 0 0 -5px; - border-radius: 2px; - pointer-events: none; - box-shadow: 0 0 3px #444; -} - -.zonebadge .cbi-tooltip > * { - margin: 1px; -} - -.zone-forwards { - display: flex; - flex-wrap: wrap; -} - -.zone-forwards > * { - flex: 1 1 40%; - padding: 1px; -} - -.zone-forwards > span { - flex-basis: 10%; - text-align: center; -} - -.zone-forwards .zone-src, -.zone-forwards .zone-dest { - display: flex; - flex-direction: column; -} - -.btn.active, .btn:active { - box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05); -} - -.btn.disabled { - cursor: default; - background-image: none; - opacity: 0.65; - box-shadow: none; -} - -.btn[disabled] { - cursor: default; - background-image: none; - opacity: 0.65; - box-shadow: none; -} - -.btn.large { - font-size: 15px; - line-height: normal; - padding: 9px 14px 9px; - border-radius: 2px; -} - -.btn.small { - padding: 7px 9px 7px; - font-size: 11px; -} - -button.btn::-moz-focus-inner, input[type=submit].btn::-moz-focus-inner { - padding: 0; - border: 0; -} - -.close { - float: right; - color: #000; - font-size: 20px; - font-weight: bold; - line-height: 13.5px; - opacity: 0.25; -} - -.close:hover { - color: #000; - text-decoration: none; - opacity: 0.4; -} - -.alert-message { - position: relative; - padding: 30px; - margin-top: 25px; - margin-bottom: 25px; - color: #404040; - background: #f0e68c; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - border-width: 1px; - border-style: solid; - border-radius: 2px; - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25); -} - -.alert-message .close { - margin-top: 1px; - *margin-top: 0; -} - -.alert-message a { - font-weight: bold; - color: #404040; -} - -.alert-message.danger p a, -.alert-message.error p a, -.alert-message.success p a, -.alert-message.info p a { - color: #fff; -} - -.alert-message h5 { - line-height: 18px; -} - -.alert-message p { - margin-bottom: 0; -} - -.alert-message div { - margin-top: 15px; - margin-bottom: 10px; - line-height: 28px; -} - -.label { - padding: 3px 3px 3px 3px; - font-size: 8px; - font-weight: normal; - color: #fff !important; - text-transform: uppercase; - white-space: nowrap; - background-color: #bfbfbf; - border-radius: 2px; - text-shadow: none; -} - -a.label:link, -a.label:visited { - color: #fff; -} - -a.label:hover { - text-decoration: none; -} - -.label.important { - background-color: #c43c35; -} - -.label.warning { - background-color: #f89406; -} - -.label.success { - background-color: #46a546; -} - -.label.notice { - background-color: #62cffc; -} - -/* LuCI specific items */ -.hidden { display: none } - -#memtotal > div, -#memfree > div, -#memcache > div, -#membuff > div, -#conns > div { - border: 1px solid #ccc; - border-radius: 2px 2px 2px 2px; - color: #808080; - display: inline-block; - font-size: 12px; - line-height: 18px; -} - -#xhr_poll_status { - cursor: pointer; -} - -form.inline { display: inline; margin-bottom: 0; } - -header .pull-right { padding-top: 21px; } - -#modemenu li:last-child span.divider { display: none } - -#syslog { width: 100%; } - -.cbi-section-table .tr:hover .td, -.cbi-section-table .tr:hover .th, -.cbi-section-table .tr:hover::before { - background-color: #f5f5f5; -} - -.cbi-section-table .tr.cbi-section-table-descr .th { - font-weight: normal; -} - -.cbi-section-table-titles.named::before, -.cbi-section-table-descr.named::before, -.cbi-section-table-row[data-title]::before { - content: attr(data-title) " "; - display: table-cell; - padding: 10px 10px 9px; - line-height: 18px; - font-weight: bold; - vertical-align: middle; -} - -.cbi-section-table-titles.named::before, -.cbi-section-table-descr.named::before, -.cbi-section-table-row[data-title]::before { - border-top: 1px solid #ddd; -} - -.left { text-align: left !important; } -.right { text-align: right !important; } -.center { text-align: center !important; } -.top { vertical-align: top !important; } -.middle { vertical-align: middle !important; } -.bottom { vertical-align: bottom !important; } - -.cbi-value-field { line-height: 1.5em; } - -.cbi-value-field input[type=checkbox], -.cbi-value-field input[type=radio] { - margin-top: 8px; - margin-right: 6px; -} - -table table td, -.cbi-value-field table td { - border: none; -} - -.table.cbi-section-table input[type="password"], -.table.cbi-section-table input[type="text"], -.table.cbi-section-table textarea, -.table.cbi-section-table select { - width: 100%; -} - -.table.cbi-section-table .td.cbi-section-table-cell { - white-space: nowrap; - text-align: right; -} - -.table.cbi-section-table .td.cbi-section-table-cell select { - width: inherit; -} - -.td.cbi-section-actions { - text-align: right; - vertical-align: middle; -} - -.td.cbi-section-actions > * { - display: flex; -} - -.td.cbi-section-actions > * > *, -.td.cbi-section-actions > * > form > * { - flex: 1 1 4em; - margin: 0 1px; -} - -.td.cbi-section-actions > * > form { - display: inline-flex; - margin: 0; -} - -.table.valign-middle .td { - vertical-align: middle; -} - -.cbi-rowstyle-2, -.tr.table-titles, -.tr.cbi-section-table-titles { - background: #f9f9f9; -} - -.cbi-value-description { - background-image: url(/luci-static/resources/cbi/help.gif); - background-position: .25em .2em; - background-repeat: no-repeat; - margin: 10px 0 10px -5px; - padding: 0 0 0 26px; -} - -.cbi-section-error { - border: 1px solid #f00; - border-radius: 2px; - background-color: #fce6e6; - padding: 5px; - margin-bottom: 18px; -} - -.cbi-section-error ul { margin: 0 0 0 20px; } - -.cbi-section-error ul li { - color: #f00; - font-weight: bold; -} - -.ifacebox { - background-color: #fff; - border: 1px solid #ccc; - margin: 6px 4px; - text-align: center; - white-space: nowrap; - background-image: linear-gradient(#fff, #fff 25%, #f9f9f9); - border-radius: 2px; - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); - display: inline-flex; - flex-direction: column; - line-height: 1.2em; - min-width: 100px; -} - -.ifacebox .ifacebox-head { - border-bottom: 1px solid #ccc; - padding: 10px; - line-height: 1.2em; - background: #eee; -} - -.ifacebox .ifacebox-head.active { - background: #f0e68c; -} - -.ifacebox .ifacebox-body { - padding: .25em; -} - -.ifacebadge { - display: inline-block; - flex-direction: row; - white-space: nowrap; - background-color: #fff; - border: 1px solid #ccc; - padding: 5px 5px 3px 5px; - background-image: linear-gradient(#fff, #fff 25%, #f9f9f9); - border-radius: 2px; - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); - cursor: default; - line-height: 1.2em; -} - -.ifacebadge img { - width: 16px; - height: 16px; - vertical-align: middle; -} - -.ifacebadge-active { - border-color: #000; - font-weight: bold; -} - -.network-status-table { - display: flex; - flex-wrap: wrap; -} - -.network-status-table .ifacebox { - margin: 10px 10px 15px 2px; - flex-grow: 1; -} - -.network-status-table .ifacebox-body { - display: flex; - flex-direction: column; - height: 100%; - text-align: left; - padding: 8px; -} - -.network-status-table .ifacebox-body > * { - margin: .25em; -} - -.network-status-table .ifacebox-body > span { - flex: 10 10 auto; - height: 100%; -} - -.network-status-table .ifacebox-body > div { - display: flex; - flex-wrap: wrap; - margin: -.125em; -} - -#dsl_status_table .ifacebox-body > span > strong { - display: inline-block; - min-width: 35%; -} - -.ifacebadge.large, -.network-status-table .ifacebox-body .ifacebadge { - display: inline-flex; - flex: 1; - padding: 10px 4px 10px 4px; - min-width: 220px; - margin: 10px 6px 4px 4px; -} - -.ifacebadge > *, -.ifacebadge.large > * { - margin: 0 .125em; -} - -.zonebadge { - padding: 2px; - border-radius: 2px; - display: inline-block; - white-space: nowrap; - color: #666; -} - -.zonebadge > em, -.zonebadge > strong { - margin: 0 2px; - display: inline-block; -} - -.zonebadge input { - width: 6em; -} - -.zonebadge > .ifacebadge { - margin-left: 2px; -} - -.zonebadge-empty { - border: 1px dashed #aaa; - color: #aaa; - font-style: italic; - font-size: smaller; -} - -div.cbi-value var, -.td.cbi-value-field var { - font-style: italic; - color: #215e21; -} - -.uci-change-list { - line-height: 170%; - white-space: pre; -} - -.uci-change-list del, -.uci-change-list ins, -.uci-change-list var, -.uci-change-legend-label del, -.uci-change-legend-label ins, -.uci-change-legend-label var { - text-decoration: none; - font-family: monospace; - font-style: normal; - border: 1px solid #ccc; - background: #eee; - padding: 2px; - display: block; - line-height: 15px; - margin-bottom: 1px; -} - -.uci-change-list ins, -.uci-change-legend-label ins { - border-color: #0f0; - background: #cfc; -} - -.uci-change-list del, -.uci-change-legend-label del { - border-color: #f00; - background: #fcc; -} - -.uci-change-list var, -.uci-change-legend-label var { - border-color: #ccc; - background: #eee; -} - -.uci-change-list var ins, -.uci-change-list var del { - display: inline-block; - border: none; - width: 100%; - padding: 0; -} - -.uci-change-legend { - padding: 5px; -} - -.uci-change-legend-label { - width: 150px; - float: left; -} - -.uci-change-legend-label > ins, -.uci-change-legend-label > del, -.uci-change-legend-label > var { - float: left; - margin-right: 4px; - width: 10px; - height: 10px; - display: block; - position: relative; -} - -.uci-change-legend-label var ins, -.uci-change-legend-label var del { - border: none; - position: absolute; - top: 2px; - left: 2px; - right: 2px; - bottom: 2px; -} - -html body.apply-overlay-active { - height: calc(100vh - 63px); -} - -#applyreboot-section { - line-height: 300%; -} - -.login{ - text-align: center; - background-color: #fff; - border-radius: 20px; - width: 300px; - height: 350px; - position: absolute; - left: 50%; - top: 50%; - transform: translate(-50%,-50%); -} diff --git a/luci-theme-ezengreen/htdocs/luci-static/ezengreen/favicon.png b/luci-theme-ezengreen/htdocs/luci-static/ezengreen/favicon.png deleted file mode 100755 index 7ee7779108d5a958e17f305962fef3f5715fbafd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8175 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.createElement("font"),c.setAttribute("data-html5shiv",a.nodeName.toLowerCase())):c=b.createElement("shiv:"+a.nodeName);while(a.firstChild)c.appendChild(a.childNodes[0]);for(d=a.attributes,e=d.length,f=0;f7?e[g][e[g].length-1]=e[g][e[g].length-1].replace(d,'$1font[data-html5shiv="$2"]'):e[g][e[g].length-1]=e[g][e[g].length-1].replace(d,"$1shiv\\:$2"),e[g]=e[g].join("}");return e.join("{")}var c=function(a){return a.innerHTML="",a.childNodes.length===1}(b.createElement("a")),d=function(a,b,c){return b.appendChild(a),(c=(c?c(a):a.currentStyle).display)&&b.removeChild(a)&&c==="block"}(b.createElement("nav"),b.documentElement,a.getComputedStyle),e={elements:"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video".split(" "),shivDocument:function(a){a=a||b;if(a.documentShived)return;a.documentShived=!0;var f=a.createElement,g=a.createDocumentFragment,h=a.getElementsByTagName("head")[0],i=function(a){f(a)};c||(e.elements.join(" ").replace(/\w+/g,i),a.createElement=function(a){var b=f(a);return b.canHaveChildren&&e.shivDocument(b.document),b},a.createDocumentFragment=function(){return e.shivDocument(g())});if(!d&&h){var j=f("div");j.innerHTML=["x"].join(""),h.insertBefore(j.lastChild,h.firstChild)}return a}};e.shivDocument(b),a.html5=e;if(c||!a.attachEvent)return;a.attachEvent("onbeforeprint",function(){if(a.html5.supportsXElement||!b.namespaces)return;b.namespaces.shiv||b.namespaces.add("shiv");var c=-1,d=new RegExp("^("+a.html5.elements.join("|")+")$","i"),e=b.getElementsByTagName("*"),g=e.length,j,k=i(h(function(a,b){var c=[],d=a.length;while(d)c.unshift(a[--d]);d=b.length;while(d)c.unshift(b[--d]);c.sort(function(a,b){return a.sourceIndex-b.sourceIndex}),d=c.length;while(d)c[--d]=c[d].styleSheet;return c}(b.getElementsByTagName("style"),b.getElementsByTagName("link"))));while(++c ul, .nav { - display: block; - float: left; - margin: 7px 8px 0 8px; - position: relative; - left: 0; -} - -header div > ul a, .nav a { - display: block; - float: left; - padding: 12px 6px 12px 6px; - line-height: 14px; - letter-spacing: 0.2px; -} - -.menu-dropdown, .dropdown-menu { - top: 38px; - min-width: 180px; - max-width: 260px; -} - -@media screen and (max-device-width: 660px) { - #maincontent.container { - width: 98%; - margin: 30px 0 0 6px; - } -} - -@media screen and (max-device-width: 360px) { - #maincontent.container { - width: 96%; - margin: 30px 0 0 6px; - } -} - -@media screen and (max-device-width: 200px) { - #maincontent.container { - width: 94%; - margin: 40px 0 0 2px; - } -} diff --git a/luci-theme-ezengreen/htdocs/luci-static/resources/ezengreen/images/cascade.css b/luci-theme-ezengreen/htdocs/luci-static/resources/ezengreen/images/cascade.css deleted file mode 100755 index 740adc320..000000000 --- a/luci-theme-ezengreen/htdocs/luci-static/resources/ezengreen/images/cascade.css +++ /dev/null @@ -1,2027 +0,0 @@ -/*! - * LuCI Bootstrap Theme - * Copyright 2012 Nut & Bolt - * By David Menting - * Based on Bootstrap v1.4.0 - * - * Copyright 2011 Twitter, Inc - * Licensed under the Apache License v2.0 - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Designed and built with all the love in the world @twitter by @mdo and @fat. - */ -/* Reset.less - * Props to Eric Meyer (meyerweb.com) for his CSS reset file. We're using an adapted version here that cuts out some of the reset HTML elements we will never need here (i.e., dfn, samp, etc). - * ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- */ -html { - margin: 0; - padding: 0; -} - -body { - margin: 0; - padding: 5px; -} - -h1, h2, h3, h4, h5, h6, p, pre, a, abbr, acronym, code, del, em, img, ins, q, s, -small, strike, strong, sub, sup, tt, var, dd, dl, dt, li, ol, ul, fieldset, -form, label, legend, button, table, caption, tbody, tfoot, thead, tr, th, td, -.table, .tbody, .tfoot, .thead, .tr, .th, .td { - margin: 0; - padding: 0; - border: 0; - font-weight: normal; - font-style: normal; - font-size: 100%; - line-height: 1; - font-family: inherit; -} - -abbr[title], acronym[title] { - border-bottom: 1px dotted; - font-weight: inherit; - cursor: help; -} - -table { - border-collapse: collapse; - border-spacing: 0; -} - -ol, ul { - list-style: none; -} - -q:before, -q:after, -blockquote:before, -blockquote:after { - content: ""; -} - -html { - overflow-y: scroll; - font-size: 100%; - -webkit-text-size-adjust: 100%; - -ms-text-size-adjust: 100%; -} - -a:focus { - outline: thin dotted; -} - -a:hover, a:active { - outline: 0; -} - -article, -aside, -details, -figcaption, -figure, -footer, -header, -hgroup, -nav, -section { - display: block; -} - -sub, sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; -} - -sup { - top: -0.5em; -} - -sub { - bottom: -0.25em; -} - -img { - border: 0; - -ms-interpolation-mode: bicubic; -} - -button, -input, -select, -option, -textarea { - font-size: 100%; - margin: 0; - box-sizing: border-box; - vertical-align: baseline; - *vertical-align: middle; -} - -button, input { - line-height: normal; - *overflow: visible; -} - -button::-moz-focus-inner, input::-moz-focus-inner { - border: 0; - padding: 0; -} - -button, -input[type="button"], -input[type="reset"], -input[type="submit"] { - cursor: pointer; - -webkit-appearance: button; -} - -button[disabled], -input[type="button"][disabled], -input[type="reset"][disabled], -input[type="submit"][disabled] { - opacity: 0.7; -} - -input[type="search"] { - -webkit-appearance: textfield; - box-sizing: content-box; -} - -input[type="search"]::-webkit-search-decoration { - -webkit-appearance: none; -} - -textarea { - overflow: auto; - vertical-align: top; -} - -/* - * Scaffolding - * Basic and global styles for generating a grid system, structural layout, and page templates - * ------------------------------------------------------------------------------------------- */ -body { - background-color: #fff; - margin: 0; - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 12px; - font-weight: normal; - line-height: 18px; - color: #404040; - padding-top: 75px; -} - -.container { - width: 100%; - max-width: 940px; - margin-left: auto; - margin-right: auto; - zoom: 1; -} - -.container:before, .container:after { - display: table; - content: ""; - zoom: 1; -} - -.container:after { - clear: both; -} - -a { - color: #215e21; - text-decoration: none; - line-height: inherit; - font-weight: inherit; -} - -a:hover { - color: #000000; - text-decoration: none; -} - -.pull-right { - float: right; -} - -.pull-left { - float: left; -} - -/* Typography.less - * Headings, body text, lists, code, and more for a versatile and durable typography system - * ---------------------------------------------------------------------------------------- */ -p, -.cbi-map-descr, -.cbi-section-descr, -.table .tr.cbi-section-table-descr .th { - font-size: 12px; - font-weight: normal; - line-height: 18px; - margin-bottom: 9px; -} - -p small { - font-size: 11px; - color: #bfbfbf; -} - -h1, -h2, -h3, legend, -h4, -h5, -h6 { - font-weight: normal; - color: #404040; -} - -h1 small, -h2 small, -h3 small, -h4 small, -h5 small, -h6 small { - color: #bfbfbf; -} - -h1 { - margin-bottom: 18px; - font-size: 30px; - line-height: 36px; -} - -h1 small { - font-size: 18px; -} - -h2 { - font-size: 24px; - line-height: 58px; - text-transform: uppercase; - font-weight: normal; -} - -h2 small { - font-size: 14px; -} - -h3, legend, -h4, -h5, -h6 { - line-height: 48px; -} - -h3, legend { - font-size: 18px; -} - -h3 small { - font-size: 14px; -} - -h4 { - font-size: 16px; -} - -h4 small { - font-size: 12px; -} - -h5 { - font-size: 14px; -} - -h6 { - font-size: 13px; - color: #bfbfbf; - text-transform: uppercase; -} - -ul, ol { - margin: 0 0 18px 25px; -} - -ul ul, -ul ol, -ol ol, -ol ul { - margin-bottom: 0; -} - -ul { - list-style: disc; -} - -ol { - list-style: decimal; -} - -li { - line-height: 18px; - color: #808080; -} - -ul.unstyled { - list-style: none; - margin-left: 0; -} - -dl { - margin-bottom: 18px; -} - -dl dt, dl dd { - line-height: 18px; -} - -dl dt { - font-weight: bold; -} - -dl dd { - margin-left: 9px; -} - -hr { - margin: 20px 0 19px; - border: 0; - border-bottom: 1px solid #eee; -} - -strong { - font-style: inherit; - font-weight: bold; -} - -em { - font-style: italic; - font-weight: inherit; - line-height: inherit; -} - -small { font-size: 0.9em } - -address { - display: block; - line-height: 18px; - margin-bottom: 18px; -} - -code, pre { - padding: 0 3px 2px; - font-family: Monaco, Andale Mono, Courier New, monospace; - font-size: 12px; - border-radius: 2px; -} - -code { - background-color: #fee9cc; - color: rgba(0, 0, 0, 0.75); - padding: 1px 3px; -} - -pre { - background-color: #f5f5f5; - display: block; - padding: 8.5px; - margin: 0 0 18px; - line-height: 18px; - font-size: 12px; - border: 1px solid #ccc; - border: 1px solid rgba(0, 0, 0, 0.15); - border-radius: 2px; - white-space: pre; - white-space: pre-wrap; - word-wrap: break-word; -} - -/* Forms.less - * Base styles for various input types, form layouts, and states - * ------------------------------------------------------------- */ -form { - margin-bottom: 18px; -} - -fieldset { - margin-bottom: 9px; - padding-top: 9px; -} - -fieldset legend { - display: block; - font-size: 19.5px; - line-height: 1; - color: #404040; - padding-top: 20px; - *padding: 0 0 5px 0px; - /* IE6-7 */ - - *line-height: 1.5; - /* IE6-7 */ - -} -form .cbi-tab-descr { - line-height: 18px; - margin-bottom: 18px; -} - -form .clearfix, -form .cbi-value { - margin-bottom: 15px; - margin-top: 15px; - zoom: 1; -} - -form .clearfix:before, form .clearfix:after, -form .cbi-value:before, form .cbi-value:after { - display: table; - content: ""; - zoom: 1; -} - -form .clearfix:after, -form .cbi-value:after { - clear: both; -} - -label, -input, -select, -textarea { - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 12px; - font-weight: normal; - line-height: normal; -} - -form .input, -form .cbi-value-field { - margin-left: 120px; -} - -form .cbi-value label.cbi-value-title { - padding-top: 6px; - font-size: 12px; - line-height: 18px; - float: left; - width: 111px; - text-align: left; - color: #404040; -} - -input[type=checkbox], input[type=radio] { - cursor: pointer; -} - -input, -textarea, -select, -.cbi-dropdown, -.uneditable-input { - display: inline-block; - width: 200px; - height: 30px; - padding: 4px; - font-size: 12px; - line-height: 18px; - color: #808080; - border: 1px solid #ccc; - border-radius: 2px; - box-sizing: border-box; - margin: 2px 0; -} - -.cbi-dropdown { - min-width: 210px; - max-width: 400px; - width: auto; -} - -select { - padding: initial; - background: #fff; - box-shadow: inset 0 -1px 3px rgba(0, 0, 0, 0.1); -} - -input[type=checkbox], input[type=radio] { - width: auto; - height: auto; - padding: 0; - margin: 3px 0; - *margin-top: 0; - /* IE6-7 */ - - line-height: normal; - border: none; -} - -input[type=file] { - background-color: #fff; - padding: initial; - border: initial; - line-height: initial; - box-shadow: none; - width: auto !important; -} - -input[type=button], input[type=reset], input[type=submit] { - width: auto; - height: auto; -} - -select, input[type=file] { - *height: auto; - *margin-top: 4px; - /* For IE7, add top margin to align select with labels */ -} - -select[multiple] { - height: inherit; - background-color: #fff; -} - -textarea { - height: auto; -} - -.td > input[type=text], -.td > input[type=password], -.td > select, -.td > .cbi-dropdown { - width: 100%; -} - -.uneditable-input { - background-color: #fff; - display: block; - border-color: #eee; - box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); - cursor: not-allowed; -} - -::-moz-placeholder { - color: #bfbfbf; -} - -::-webkit-input-placeholder { - color: #bfbfbf; -} - -.btn, .cbi-button, input, textarea { - transition: border linear 0.2s, box-shadow linear 0.2s; - box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1); - padding: 12px 6px; -} - -.btn:hover, .cbi-button:hover, -input:focus, textarea:focus { - outline: 0; - border-color: rgba(82, 168, 236, 0.8) !important; - box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6); - text-decoration: none; -} - -input[type=file]:focus, input[type=checkbox]:focus, select:focus { - box-shadow: none; - outline: 1px dotted #666; -} - -input[disabled], -select[disabled], -textarea[disabled], -input[readonly], -select[readonly], -textarea[readonly] { - background-color: #194119; - border-color: #ccc; - padding: 5px; - pointer-events: none; - cursor: default; -} - -select[readonly], -textarea[readonly] { - pointer-events: auto; - cursor: auto; -} - -.cbi-optionals, -.cbi-section-create { - padding: 0 0 10px 10px; -} - -.cbi-section-create { - margin: 10px 0 0 -10px; - display: inline-flex; - align-items: center; -} - -.cbi-section-create > * { - margin: 3px; - flex: 1 1 auto; -} - -.cbi-section-create > * > input { - width: 100%; -} - -.actions, -.cbi-page-actions { - background: #f5f5f5; - margin-bottom: 20px; - margin-top: 40px; - padding: 15px 20px 15px 20px; - border-radius: 0 0 2px 2px; - text-align: right; -} - -.actions .secondary-action, -.cbi-page-actions .secondary-action{ - float: right; -} - -.actions .secondary-action a, -.cbi-page-actions .secondary-action a { - line-height: 30px; -} - -.actions .secondary-action a:hover, -.cbi-page-actions .secondary-action a:hover { - text-decoration: none; -} - -.cbi-page-actions > form { - display: inline; - margin: 0; -} - -.help-inline, .help-block { - font-size: 12px; - line-height: 18px; - color: #bfbfbf; -} - -.help-inline { - padding-left: 5px; - *position: relative; - /* IE6-7 */ - - *top: -5px; - /* IE6-7 */ - -} - -.help-block { - display: block; - max-width: 600px; -} - -/* - * Tables.less - * Tables for, you guessed it, tabular data - * ---------------------------------------- */ -.tr { display: table-row; } -.table[width="33%"], .th[width="33%"], .td[width="33%"] { width: 33%; } -.table[width="100%"], .th[width="100%"], .td[width="100%"] { width: 100%; } - -.table { - display: table; - width: 100%; - margin: 12px 0 24px 0; - padding: 0; - font-size: 12px; - border-collapse: collapse; - position: relative; -} - -.table .th, .table .td { - display: table-cell; - vertical-align: middle; /* Fixme */ - padding: 6px 6px 6px 2px; - line-height: 18px; - text-align: left; -} - -.table .tr:first-child .th { - padding-top: 9px; - font-weight: normal; - vertical-align: top; -} - -.table .td, .table .th { - border-top: 1px solid #e7e7e7; -} - -.tr.placeholder { - height: calc(3em + 20px); -} - -.tr.placeholder > .td { - position: absolute; - left: 0; - right: 0; - bottom: 0; - text-align: center; - line-height: 3em; -} - -/* Patterns.less - * Repeatable UI elements outside the base styles provided from the scaffolding - * ---------------------------------------------------------------------------- */ -header { - height: 40px; - position: fixed; - top: 0; - left: 0; - right: 0; - z-index: 10000; - overflow: visible; - color: #BFBFBF; -} - -header a { - color: #c4c4c4; -} - -header h3 a:hover, header .brand:hover, header ul .active > a { - background-color: #333; - background-color: rgba(0, 0, 0, 0.33); - color: #fff; - text-decoration: none; -} - -header h3 { - position: relative; -} - -header h3 a, header .brand { - float: left; - display: block; - padding: 16px 20px 16px; - margin-left: -20px; - color: #fff; - font-size: 24px; - font-weight: 333; - line-height: 1; -} - -header p { - margin: 0; - line-height: 40px; -} - -header .fill { - background-color: #215e21; - background-repeat: repeat-x; - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.33), inset 0 -1px 0 rgba(0, 0, 0, 0.1); - padding: 0 5px; -} - -header div > ul, .nav { - display: block; - float: left; - margin: 0 10px 0 20px; - position: relative; - left: 0; -} - -header div > ul > li, .nav > li { - display: block; - float: left; -} - -header div > ul a, .nav a { - display: block; - float: none; - padding: 22px 12px 14px 12px; - line-height: 19px; - letter-spacing: 0.4px; - text-decoration: none; - text-transform: uppercase; -} - -header div > ul a:hover, .nav a:hover { - color: #fff; - text-decoration: none; -} - -header div > ul .active > a, .nav .active > a { - background-color: #222; - background-color: rgba(0, 0, 0, 0.33); -} - -header div > ul.secondary-nav, .nav.secondary-nav { - float: right; - margin-left: 10px; - margin-right: 0; -} - -header div > ul.secondary-nav .menu-dropdown, -.nav.secondary-nav .menu-dropdown, -header div > ul.secondary-nav .dropdown-menu, -.nav.secondary-nav .dropdown-menu { - right: 0; - border: 0; -} - -header div > ul a.menu:hover, -.nav a.menu:hover, -header div > ul li.open .menu, -.nav li.open .menu, -header div > ul .dropdown-toggle:hover, -.nav .dropdown-toggle:hover, -header div > ul .dropdown.open .dropdown-toggle, -.nav .dropdown.open .dropdown-toggle { - background: #444; - background: rgba(0, 0, 0, 0.3); -} - -header div > ul .menu-dropdown, -.nav .menu-dropdown, -header div > ul .dropdown-menu, -.nav .dropdown-menu { - background-color: #003300; -} - -header div > ul .menu-dropdown a.menu, -.nav .menu-dropdown a.menu, -header div > ul .dropdown-menu a.menu, -.nav .dropdown-menu a.menu, -header div > ul .menu-dropdown .dropdown-toggle, -.nav .menu-dropdown .dropdown-toggle, -header div > ul .dropdown-menu .dropdown-toggle, -.nav .dropdown-menu .dropdown-toggle { - color: #fff; -} - -header div > ul .menu-dropdown a.menu.open, -.nav .menu-dropdown a.menu.open, -header div > ul .dropdown-menu a.menu.open, -.nav .dropdown-menu a.menu.open, -header div > ul .menu-dropdown .dropdown-toggle.open, -.nav .menu-dropdown .dropdown-toggle.open, -header div > ul .dropdown-menu .dropdown-toggle.open, -.nav .dropdown-menu .dropdown-toggle.open { - background: #444; - background: rgba(255, 255, 255, 0.05); -} - -header div > ul .menu-dropdown li a, -.nav .menu-dropdown li a, -header div > ul .dropdown-menu li a, -.nav .dropdown-menu li a { - color: #bfbfbf; -} - -header div > ul .menu-dropdown li a:hover, -.nav .menu-dropdown li a:hover, -header div > ul .dropdown-menu li a:hover, -.nav .dropdown-menu li a:hover { - background-color: #215e21; - background-repeat: repeat-x; - color: #fff; -} - -header div > ul .menu-dropdown .active a, -.nav .menu-dropdown .active a, -header div > ul .dropdown-menu .active a, -.nav .dropdown-menu .active a { - color: #fff; -} - -header div > ul .menu-dropdown .divider, -.nav .menu-dropdown .divider, -header div > ul .dropdown-menu .divider, -.nav .dropdown-menu .divider { - background-color: #222; - border-color: #444; -} - -header ul .menu-dropdown li a, header ul .dropdown-menu li a { - padding: 6px 12px; -} - -li.menu, .dropdown { - position: relative; -} - -.menu-dropdown, .dropdown-menu { - background-color: #fff; - float: left; - position: absolute; - top: 55px; - left: -9999px; - z-index: 900; - min-width: 200px; - max-width: 300px; - _width: 160px; - margin-left: 0; - margin-right: 0; - padding: 6px 0; - zoom: 1; - border-radius: 0 0 2px 2px; - background-clip: padding-box; -} - -.menu-dropdown li, .dropdown-menu li { - float: none; - display: block; - background-color: transparent; -} - -.menu-dropdown .divider, .dropdown-menu .divider { - height: 1px; - margin: 5px 0; - overflow: hidden; - background-color: #eee; - border-bottom: 1px solid #fff; -} - -header .dropdown-menu a, .dropdown-menu a { - display: block; - padding: 4px 15px; - clear: both; - font-weight: normal; - line-height: 18px; - text-transform: capitalize; - letter-spacing: 0.2px; - color: #808080; - zoom: 1.1; -} - -header .dropdown-menu a:hover, -.dropdown-menu a:hover, -header .dropdown-menu a.hover, -.dropdown-menu a.hover { - background-color: #ddd; - background-repeat: repeat-x; - color: #404040; - text-decoration: none; - box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.025), inset 0 -1px rgba(0, 0, 0, 0.025); -} - -.open .menu, -.dropdown.open .menu, -.open .dropdown-toggle, -.dropdown.open .dropdown-toggle { - color: #fff; - background: #ccc; - background: rgba(0, 0, 0, 0.3); -} - -.open .menu-dropdown, -.dropdown.open .menu-dropdown, -.open .dropdown-menu, -.dropdown.open .dropdown-menu { - left: 0; -} - -.dropdown:hover ul.dropdown-menu { - left: 0; -} - -.dropdown-menu .dropdown-menu { - position: absolute; - left: 159px; -} - -.dropdown-menu li { - position: relative; -} - -.tabs, .cbi-tabmenu { - margin: 0 0 18px; - padding: 0; - list-style: none; - zoom: 1; -} - -.tabs:before, -.cbi-tabmenu:before, -.tabs:after, -.cbi-tabmenu:after { - display: table; - content: ""; - zoom: 1; -} - -.tabs:after, .cbi-tabmenu:after { - clear: both; -} - -.tabs > li, .cbi-tabmenu > li { - float: left; -} - -.tabs > li > a, .cbi-tabmenu > li > a { - display: block; -} - -.tabs, -.cbi-tabmenu { - border-color: #ddd; - border-style: solid; - border-width: 0 0 1px; -} - -.tabs > li, -.cbi-tabmenu > li { - position: relative; - margin-bottom: -1px; -} - -.cbi-tabmenu.map { - margin: 0; -} - -.cbi-tabmenu.map > li { - font-size: 16.5px; - font-weight: bold; -} - -.cbi-tabcontainer > fieldset.cbi-section[id] > legend { - display: none; -} - -.tabs > li > a, -.cbi-tabmenu > li > a { - padding: 0 15px; - margin-right: 2px; - line-height: 34px; - border: 1px solid transparent; - border-radius: 2px 2px 0 0; -} - -.tabs > li > a:hover, -.cbi-tabmenu > li > a:hover { - text-decoration: none; - background-color: #eee; - border-color: #eee #eee #ddd; -} - -.tabs .active > a, .tabs .active > a:hover, -.cbi-tabmenu .active > a, .cbi-tabmenu .active > a:hover, -.cbi-tab > a:link, .cbi-tab > a:hover { - color: #000000; - background-color: #fff; - border: 1px solid #ddd; - border-bottom-color: transparent; - cursor: default; -} - -.tabs .menu-dropdown, .tabs .dropdown-menu, -.cbi-tabmenu .menu-dropdown, .cbi-tabmenu .dropdown-menu { - top: 35px; - border-width: 1px; - border-radius: 0 2px 2px 2px; -} - -.tabs a.menu:after, .tabs .dropdown-toggle:after, -.cbi-tabmenu a.menu:after, .cbi-tabmenu .dropdown-toggle:after { - border-top-color: #999; - margin-top: 15px; - margin-left: 5px; -} - -.tabs li.open.menu .menu, .tabs .open.dropdown .dropdown-toggle, -.cbi-tabmenu li.open.menu .menu, .cbi-tabmenu .open.dropdown .dropdown-toggle { - border-color: #999; -} - -.tabs li.open a.menu:after, .tabs .dropdown.open .dropdown-toggle:after, -.cbi-tabmenu li.open a.menu:after, .cbi-tabmenu .dropdown.open .dropdown-toggle:after { - border-top-color: #555; -} - -.tab-content > .tab-pane, -.tab-content > div { - display: none; -} - -.tab-content > .active { - display: block; -} - -.breadcrumb { - padding: 7px 14px; - margin: 0 0 18px; - background-color: #f5f5f5; - background-repeat: repeat-x; - border: 1px solid #ddd; - border-radius: 2px; - box-shadow: inset 0 1px 0 #fff; -} - -.breadcrumb li { - display: inline; -} - -.breadcrumb .divider { - padding: 0 5px; - color: #bfbfbf; -} - -.breadcrumb .active a { - color: #404040; -} - -footer { - margin-top: 30px; - padding-top: 20px; - padding-bottom: 20px; - border-top: 1px solid #404040; -} - -.btn.danger, -.alert-message.danger, -.btn.danger:hover, -.alert-message.danger:hover, -.btn.error, -.alert-message.error, -.btn.error:hover, -.alert-message.error:hover, -.btn.success, -.alert-message.success, -.btn.success:hover, -.alert-message.success:hover, -.btn.info, -.alert-message.info, -.btn.info:hover, -.alert-message.info:hover { - color: #fff; -} - -.btn .close, .alert-message .close { - font-family: Arial, sans-serif; - line-height: 18px; -} - -.btn.danger, -.alert-message.danger, -.btn.error, -.alert-message.error { - background: linear-gradient(to bottom, #ee5f5b, #c43c35) repeat-x; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); -} - -.btn.success, .alert-message.success { - background: linear-gradient(to bottom, #62c462, #57a957) repeat-x; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); -} - -.btn.info, .alert-message.info { - background: linear-gradient(to bottom, #5bc0de, #339bb9) repeat-x; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); -} - -.alert-message.notice { - background: linear-gradient(to bottom, #efefef, #fefefe) repeat-x; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); -} - -.btn, -.cbi-button { - cursor: pointer; - display: inline-block; - background: linear-gradient(#fff, #fff 25%, #e6e6e6) no-repeat; - padding: 5px 14px 6px; - color: #333; - font-size: 12px; - line-height: normal; - border: 1px solid #ccc; - border-bottom-color: #bbb; - border-radius: 2px; - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); -} - -.btn:focus, -.cbi-button:focus { - outline: 1px dotted #666; -} - -.cbi-input-invalid, -.cbi-value-error input { - color: #f00; - border-color: #f00; -} - -.cbi-button-positive, -.cbi-button-fieldadd, -.cbi-button-add, -.cbi-button-save { - border-color: #4a4; - color: #4a4; -} - -.cbi-button-neutral, -.cbi-button-download, -.cbi-button-find, -.cbi-button-link, -.cbi-button-up, -.cbi-button-down { - color: #444; -} - -.btn.primary, -.cbi-button-action, -.cbi-button-apply, -.cbi-button-reload, -.cbi-button-edit { - border-color: #4aa44b; - color: #4aa44b; -} - -.cbi-button-negative, -.cbi-section-remove .cbi-button, -.cbi-button-reset, -.cbi-button-remove { - border-color: #c44; - color: #c44; -} - -.cbi-page-actions::after { - display: table; - content: ""; - clear: both; -} - -.cbi-page-actions > :not([method="post"]):not(.cbi-button-apply):not(.cbi-button-save):not(.cbi-button-reset) { - float: left; - margin-right: .4em; -} - -.btn.primary, -.cbi-button-action.important, -.cbi-page-actions .cbi-button-apply, -.cbi-section-actions .cbi-button-edit { - color: #fff; - background: #4aa44b; -} - -.cbi-button-positive.important, -.cbi-page-actions .cbi-button-save { - color: #fff; - background: linear-gradient(to bottom, #4a4, #484) no-repeat; -} - -.cbi-button-negative.important { - color: #fff; - background: linear-gradient(to bottom, #c44, #c00) no-repeat; -} - -.cbi-page-actions .cbi-button-apply + .cbi-button-save { - background: linear-gradient(#fff, #fff 25%, #e6e6e6); - color: #4a4; -} - -.cbi-dropdown { - border: 1px solid #ccc; - border-radius: 2px; - display: inline-flex; - padding: 0; - cursor: pointer; - height: auto; - background: linear-gradient(#fff 0%, #e9e8e6 100%); - position: relative; - color: #404040; -} - -.cbi-dropdown:focus { - outline: 2px solid #4b6e9b; -} - -.cbi-dropdown > ul { - margin: 0 !important; - padding: 0; - list-style: none; - overflow-x: hidden; - overflow-y: auto; - display: flex; - width: 100%; -} - -.cbi-dropdown > ul.preview { - display: none; -} - -.cbi-dropdown > .open, -.cbi-dropdown > .more { - flex-grow: 0; - flex-shrink: 0; - display: flex; - flex-direction: column; - justify-content: center; - text-align: center; - line-height: 2em; - padding: 0 .25em; -} - -.cbi-dropdown > .more, -.cbi-dropdown > ul > li[placeholder] { - color: #777; - font-weight: bold; - display: none; -} - -.cbi-dropdown > ul > li { - display: none; - padding: .25em; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - flex-shrink: 1; - flex-grow: 1; - align-items: center; - align-self: center; - color: #404040; - min-height: 20px; -} - -.cbi-dropdown > ul > li .hide-open { display: block; display: initial; } -.cbi-dropdown > ul > li .hide-close { display: none; } - -.cbi-dropdown > ul > li[display]:not([display="0"]) { - border-left: 1px solid #ccc; -} - -.cbi-dropdown[empty] > ul { - max-width: 1px; -} - -.cbi-dropdown > ul > li > form { - display: none; - margin: 0; - padding: 0; - pointer-events: none; -} - -.cbi-dropdown > ul > li img { - vertical-align: middle; - margin-right: .25em; -} - -.cbi-dropdown > ul > li > form > input[type="checkbox"] { - margin: 0; -} - -.cbi-dropdown > ul > li input[type="text"] { - height: 20px; -} - -.cbi-dropdown[open] { - position: relative; -} - -.cbi-dropdown[open] > ul.dropdown { - display: block; - background: #f6f6f5; - border: 1px solid #918e8c; - box-shadow: 0 0 4px #918e8c; - position: absolute; - z-index: 1000; - max-width: none; - min-width: 100%; - width: auto; -} - -.cbi-dropdown > ul > li[display], -.cbi-dropdown[open] > ul.preview, -.cbi-dropdown[open] > ul.dropdown > li, -.cbi-dropdown[multiple] > ul > li > label, -.cbi-dropdown[multiple][open] > ul.dropdown > li, -.cbi-dropdown[multiple][more] > .more, -.cbi-dropdown[multiple][empty] > .more { - flex-grow: 1; - display: flex; -} - -.cbi-dropdown[empty] > ul > li, -.cbi-dropdown[optional][open] > ul.dropdown > li[placeholder], -.cbi-dropdown[multiple][open] > ul.dropdown > li > form { - display: block; -} - -.cbi-dropdown[open] > ul.dropdown > li .hide-open { display: none; } -.cbi-dropdown[open] > ul.dropdown > li .hide-close { display: block; display: initial; } - -.cbi-dropdown[open] > ul.dropdown > li { - border-bottom: 1px solid #ccc; -} - -.cbi-dropdown[open] > ul.dropdown > li[selected] { - background: #b0d0f0; -} - -.cbi-dropdown[open] > ul.dropdown > li.focus { - background: linear-gradient(90deg, #a3c2e8 0%, #84aad9 100%); -} - -.cbi-dropdown[open] > ul.dropdown > li:last-child { - margin-bottom: 0; - border-bottom: none; -} - -.cbi-dropdown[disabled] { - pointer-events: none; - opacity: .6; -} - -input[type="text"] + .cbi-button, -input[type="password"] + .cbi-button, -select + .cbi-button { - border-radius: 2px; - border-color: #ccc; - margin: 2px 0 2px 3px; - padding: 0 12px; - vertical-align: top; - height: 28px; - font-size: 13px; - font-weight: normal; - line-height: 28px; -} - -select + .cbi-button { - #border-left-color: transparent; -} - -.cbi-title-ref { - color: #f39800; -} - -.cbi-title-ref::after { - content: " ➙ "; -} - -.cbi-tooltip-container { - cursor: help; - padding: 5px 3px 5px 3px; -} - -.cbi-tooltip { - position: absolute; - z-index: 1000; - left: -1000px; - opacity: 0; - transition: opacity .25s ease-out; -} - -.cbi-tooltip-container:hover .cbi-tooltip:not(:empty) { - left: auto; - opacity: 1; - transition: opacity .25s ease-in; -} - -.zonebadge .cbi-tooltip { - padding: 1px; - background: inherit; - margin: -1.6em 0 0 -5px; - border-radius: 2px; - pointer-events: none; - box-shadow: 0 0 3px #444; -} - -.zonebadge .cbi-tooltip > * { - margin: 1px; -} - -.zone-forwards { - display: flex; - flex-wrap: wrap; -} - -.zone-forwards > * { - flex: 1 1 40%; - padding: 1px; -} - -.zone-forwards > span { - flex-basis: 10%; - text-align: center; -} - -.zone-forwards .zone-src, -.zone-forwards .zone-dest { - display: flex; - flex-direction: column; -} - -.btn.active, .btn:active { - box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05); -} - -.btn.disabled { - cursor: default; - background-image: none; - opacity: 0.65; - box-shadow: none; -} - -.btn[disabled] { - cursor: default; - background-image: none; - opacity: 0.65; - box-shadow: none; -} - -.btn.large { - font-size: 15px; - line-height: normal; - padding: 9px 14px 9px; - border-radius: 2px; -} - -.btn.small { - padding: 7px 9px 7px; - font-size: 11px; -} - -button.btn::-moz-focus-inner, input[type=submit].btn::-moz-focus-inner { - padding: 0; - border: 0; -} - -.close { - float: right; - color: #000; - font-size: 20px; - font-weight: bold; - line-height: 13.5px; - opacity: 0.25; -} - -.close:hover { - color: #000; - text-decoration: none; - opacity: 0.4; -} - -.alert-message { - position: relative; - padding: 30px; - margin-top: 25px; - margin-bottom: 25px; - color: #404040; - background: #f0e68c; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - border-width: 1px; - border-style: solid; - border-radius: 2px; - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25); -} - -.alert-message .close { - margin-top: 1px; - *margin-top: 0; -} - -.alert-message a { - font-weight: bold; - color: #404040; -} - -.alert-message.danger p a, -.alert-message.error p a, -.alert-message.success p a, -.alert-message.info p a { - color: #fff; -} - -.alert-message h5 { - line-height: 18px; -} - -.alert-message p { - margin-bottom: 0; -} - -.alert-message div { - margin-top: 15px; - margin-bottom: 10px; - line-height: 28px; -} - -.label { - padding: 3px 3px 3px 3px; - font-size: 8px; - font-weight: normal; - color: #fff !important; - text-transform: uppercase; - white-space: nowrap; - background-color: #bfbfbf; - border-radius: 2px; - text-shadow: none; -} - -a.label:link, -a.label:visited { - color: #fff; -} - -a.label:hover { - text-decoration: none; -} - -.label.important { - background-color: #c43c35; -} - -.label.warning { - background-color: #f89406; -} - -.label.success { - background-color: #46a546; -} - -.label.notice { - background-color: #62cffc; -} - -/* LuCI specific items */ -.hidden { display: none } - -#memtotal > div, -#memfree > div, -#memcache > div, -#membuff > div, -#conns > div { - border: 1px solid #ccc; - border-radius: 2px 2px 2px 2px; - color: #808080; - display: inline-block; - font-size: 12px; - line-height: 18px; -} - -#xhr_poll_status { - cursor: pointer; -} - -form.inline { display: inline; margin-bottom: 0; } - -header .pull-right { padding-top: 21px; } - -#modemenu li:last-child span.divider { display: none } - -#syslog { width: 100%; } - -.cbi-section-table .tr:hover .td, -.cbi-section-table .tr:hover .th, -.cbi-section-table .tr:hover::before { - background-color: #f5f5f5; -} - -.cbi-section-table .tr.cbi-section-table-descr .th { - font-weight: normal; -} - -.cbi-section-table-titles.named::before, -.cbi-section-table-descr.named::before, -.cbi-section-table-row[data-title]::before { - content: attr(data-title) " "; - display: table-cell; - padding: 10px 10px 9px; - line-height: 18px; - font-weight: bold; - vertical-align: middle; -} - -.cbi-section-table-titles.named::before, -.cbi-section-table-descr.named::before, -.cbi-section-table-row[data-title]::before { - border-top: 1px solid #ddd; -} - -.left { text-align: left !important; } -.right { text-align: right !important; } -.center { text-align: center !important; } -.top { vertical-align: top !important; } -.middle { vertical-align: middle !important; } -.bottom { vertical-align: bottom !important; } - -.cbi-value-field { line-height: 1.5em; } - -.cbi-value-field input[type=checkbox], -.cbi-value-field input[type=radio] { - margin-top: 8px; - margin-right: 6px; -} - -table table td, -.cbi-value-field table td { - border: none; -} - -.table.cbi-section-table input[type="password"], -.table.cbi-section-table input[type="text"], -.table.cbi-section-table textarea, -.table.cbi-section-table select { - width: 100%; -} - -.table.cbi-section-table .td.cbi-section-table-cell { - white-space: nowrap; - text-align: right; -} - -.table.cbi-section-table .td.cbi-section-table-cell select { - width: inherit; -} - -.td.cbi-section-actions { - text-align: right; - vertical-align: middle; -} - -.td.cbi-section-actions > * { - display: flex; -} - -.td.cbi-section-actions > * > *, -.td.cbi-section-actions > * > form > * { - flex: 1 1 4em; - margin: 0 1px; -} - -.td.cbi-section-actions > * > form { - display: inline-flex; - margin: 0; -} - -.table.valign-middle .td { - vertical-align: middle; -} - -.cbi-rowstyle-2, -.tr.table-titles, -.tr.cbi-section-table-titles { - background: #f9f9f9; -} - -.cbi-value-description { - background-image: url(/luci-static/resources/cbi/help.gif); - background-position: .25em .2em; - background-repeat: no-repeat; - margin: 10px 0 10px -5px; - padding: 0 0 0 26px; -} - -.cbi-section-error { - border: 1px solid #f00; - border-radius: 2px; - background-color: #fce6e6; - padding: 5px; - margin-bottom: 18px; -} - -.cbi-section-error ul { margin: 0 0 0 20px; } - -.cbi-section-error ul li { - color: #f00; - font-weight: bold; -} - -.ifacebox { - background-color: #fff; - border: 1px solid #ccc; - margin: 6px 4px; - text-align: center; - white-space: nowrap; - background-image: linear-gradient(#fff, #fff 25%, #f9f9f9); - border-radius: 2px; - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); - display: inline-flex; - flex-direction: column; - line-height: 1.2em; - min-width: 100px; -} - -.ifacebox .ifacebox-head { - border-bottom: 1px solid #ccc; - padding: 10px; - line-height: 1.2em; - background: #eee; -} - -.ifacebox .ifacebox-head.active { - background: #f0e68c; -} - -.ifacebox .ifacebox-body { - padding: .25em; -} - -.ifacebadge { - display: inline-block; - flex-direction: row; - white-space: nowrap; - background-color: #fff; - border: 1px solid #ccc; - padding: 5px 5px 3px 5px; - background-image: linear-gradient(#fff, #fff 25%, #f9f9f9); - border-radius: 2px; - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); - cursor: default; - line-height: 1.2em; -} - -.ifacebadge img { - width: 16px; - height: 16px; - vertical-align: middle; -} - -.ifacebadge-active { - border-color: #000; - font-weight: bold; -} - -.network-status-table { - display: flex; - flex-wrap: wrap; -} - -.network-status-table .ifacebox { - margin: 10px 10px 15px 2px; - flex-grow: 1; -} - -.network-status-table .ifacebox-body { - display: flex; - flex-direction: column; - height: 100%; - text-align: left; - padding: 8px; -} - -.network-status-table .ifacebox-body > * { - margin: .25em; -} - -.network-status-table .ifacebox-body > span { - flex: 10 10 auto; - height: 100%; -} - -.network-status-table .ifacebox-body > div { - display: flex; - flex-wrap: wrap; - margin: -.125em; -} - -#dsl_status_table .ifacebox-body > span > strong { - display: inline-block; - min-width: 35%; -} - -.ifacebadge.large, -.network-status-table .ifacebox-body .ifacebadge { - display: inline-flex; - flex: 1; - padding: 10px 4px 10px 4px; - min-width: 220px; - margin: 10px 6px 4px 4px; -} - -.ifacebadge > *, -.ifacebadge.large > * { - margin: 0 .125em; -} - -.zonebadge { - padding: 2px; - border-radius: 2px; - display: inline-block; - white-space: nowrap; - color: #666; -} - -.zonebadge > em, -.zonebadge > strong { - margin: 0 2px; - display: inline-block; -} - -.zonebadge input { - width: 6em; -} - -.zonebadge > .ifacebadge { - margin-left: 2px; -} - -.zonebadge-empty { - border: 1px dashed #aaa; - color: #aaa; - font-style: italic; - font-size: smaller; -} - -div.cbi-value var, -.td.cbi-value-field var { - font-style: italic; - color: #215e21; -} - -.uci-change-list { - line-height: 170%; - white-space: pre; -} - -.uci-change-list del, -.uci-change-list ins, -.uci-change-list var, -.uci-change-legend-label del, -.uci-change-legend-label ins, -.uci-change-legend-label var { - text-decoration: none; - font-family: monospace; - font-style: normal; - border: 1px solid #ccc; - background: #eee; - padding: 2px; - display: block; - line-height: 15px; - margin-bottom: 1px; -} - -.uci-change-list ins, -.uci-change-legend-label ins { - border-color: #0f0; - background: #cfc; -} - -.uci-change-list del, -.uci-change-legend-label del { - border-color: #f00; - background: #fcc; -} - -.uci-change-list var, -.uci-change-legend-label var { - border-color: #ccc; - background: #eee; -} - -.uci-change-list var ins, -.uci-change-list var del { - display: inline-block; - border: none; - width: 100%; - padding: 0; -} - -.uci-change-legend { - padding: 5px; -} - -.uci-change-legend-label { - width: 150px; - float: left; -} - -.uci-change-legend-label > ins, -.uci-change-legend-label > del, -.uci-change-legend-label > var { - float: left; - margin-right: 4px; - width: 10px; - height: 10px; - display: block; - position: relative; -} - -.uci-change-legend-label var ins, -.uci-change-legend-label var del { - border: none; - position: absolute; - top: 2px; - left: 2px; - right: 2px; - bottom: 2px; -} - -html body.apply-overlay-active { - height: calc(100vh - 63px); -} - -#applyreboot-section { - line-height: 300%; -} - -.login{ - text-align: center; - background-color: #fff; - border-radius: 20px; - width: 300px; - height: 350px; - position: absolute; - left: 50%; - top: 50%; - transform: translate(-50%,-50%); -} diff --git a/luci-theme-ezengreen/htdocs/luci-static/resources/ezengreen/images/ezenlink.png b/luci-theme-ezengreen/htdocs/luci-static/resources/ezengreen/images/ezenlink.png deleted file mode 100755 index 070a12b7da56ad334a98ffb87ca1a382af985ca4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 553 zcmV+^0@nSBP)5Rm*L{Kop!rxswj!voA{raViK6tZ*v8R6tTepaO_o zK%jz<3ScijlMX@!jz*fb7UN%5LM!a|X5Y-td%h{l5<`};@jZaZ<;8JG{Ov%{2>=2f zjE$E=aylzEHXZ{Y&?A5!fj0+a};rI%Z*jv2iL{ zMgq8CqI=*$2EfYY1rNJ&#m0k@fwA!kz*?8~dk$t1{z70E8s|4@}f?f1JGsh-A*IZ+iaOa7=K r8C)FHmOJQUD(bA18eYuZ#s%OHNQeZcR0cH!00000NkvXXu0mjf(L3<` diff --git a/luci-theme-ezengreen/htdocs/luci-static/resources/ezengreen/images/favicon.ico b/luci-theme-ezengreen/htdocs/luci-static/resources/ezengreen/images/favicon.ico deleted file mode 100755 index dd14062c9b9520f0de40f938a7cfa0ecc0edc154..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4286 zcmeHHJ5Iwu5M3%tvJDcVz;u*8f+a4HirPo;4cI_I3Zw{$CRJKGAHg+Mj$mq<$Q=ce zdC!`0R+i(~2|^TJ^jObl=gqveW6TNug23>Zj8AB;4%?Ff3*-B*Qmg#!2eR< z;`K8IBJHZhPFmtq&A*#phCl?=U%1$Tms7_P3xJq0)&)x95L~^=?%Qz7N%1V5ct3Q9IyS=|P{_Q}6eY=TUFv z)zsRt#1<0E#nyMRvgz~JA@iet?(uVey@%NISKq6b>wI2)K7?P->JAQS?mX@lW1f$9 zQ~y@zIqu+}01k-7?z|7?uoe&rsJE|&a)v-au18Vx?>;EajH$xWNFbst{M z>B*mJZR~uGfl6QO2~cyZU+eGN!5;uQkTJK}&#v>}nF1N0daQ?Xx7BXrM_t~%6L5Z= zSGgDPwZ3m{99_O0{7pXPU4b{~sy8$SetsV*Q2n;@JUDpA8NfNILo~GRm_I5oDljVW z*9w#!Yq@-Wx7N(JnB)1wyx5s7>;v$1U08QpTK81i*=cFN&&tAG0rzF`*im^K`T>j! BrMdtB diff --git a/luci-theme-ezengreen/htdocs/luci-static/resources/ezengreen/images/footer.png b/luci-theme-ezengreen/htdocs/luci-static/resources/ezengreen/images/footer.png deleted file mode 100755 index c7e2e393ac0c035c9a41f7e9d095bd11c4099971..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 836 zcmV-K1H1f*P)s+)P~w1iKdod zscmgBclR0#Sg?&vEJUVn^1i)(IdXxJpLs9u?q+vpXJ@`|cJpR99AZ)8d^j>!S(>!f zrSoAMz#c#E;xkK=yLpygSn$q=&j5D$d6lKfCG{HsS^(BcOm6|)WNGqe)-~VG74f)y zkS~3I0MMIaw*}zP`EcfZ*qLR)cXI^$BFWO^5kS-Vu*vyWi7Ej5u8NNeH(}K~&(fs3 zl;E8Yw&+fT#tS!*V_p2%Mz#sJ3f1Pj<$Sn!4oWj)o`Ihb!<|S@=R*@fjnnS4G--*= zdx26vOOq!say}f8)XI&kX$g8w=0C~;bpY*W=9@GXBF={aE07a4OOv0@hYo;-%-wZ9 zJlfbKr;8-)L}8^i3S(;pqHc2oJ$9yhnY$myR~|fxcWMw|P(>md)*H@;V}q9woRHIb zU&)U#nF}X{HEv>5Rc_!`#t-nn z1F1gmJfq;vf%Bm~>)qld!tT+|(!_}WjTs)$)L?ncLkvplLYDQU9S>ek%)^+8WeACC zfi$EQRtj0}ObAr3&hZq_gV!T@ebI4SMeX>Hm6cW)E1(s>k@roR-xYsVtcb8pc9MNo zHvVC;fUY@hO$e%oQ$^nOoLOIb@XS!Hpsov+HPF$;t#D~m2>&hmUv}opAQ&?`%c=cj zZVY}P&pzM#1$`9FK(|CcdgmQpZNV$?r2npJA8pDYG#0#FoGjSWST;U$eKg3@#0X{W z&K&2b9q--NDeR7~EzfLYpSI_j*jVQ=KR*f^I;Z}-=**|->`%%a0Q>{Ia7QjydhGlF O0000 ul, .nav { - display: block; - float: left; - margin: 7px 8px 0 8px; - position: relative; - left: 0; -} - -header div > ul a, .nav a { - display: block; - float: left; - padding: 12px 6px 12px 6px; - line-height: 14px; - letter-spacing: 0.2px; -} - -.menu-dropdown, .dropdown-menu { - top: 38px; - min-width: 180px; - max-width: 260px; -} - -@media screen and (max-device-width: 660px) { - #maincontent.container { - width: 98%; - margin: 30px 0 0 6px; - } -} - -@media screen and (max-device-width: 360px) { - #maincontent.container { - width: 96%; - margin: 30px 0 0 6px; - } -} - -@media screen and (max-device-width: 200px) { - #maincontent.container { - width: 94%; - margin: 40px 0 0 2px; - } -} diff --git a/luci-theme-ezengreen/htdocs/luci-static/resources/ezengreen/images/omr-logo.png b/luci-theme-ezengreen/htdocs/luci-static/resources/ezengreen/images/omr-logo.png deleted file mode 100755 index 3d532aec038b0c7bf504b1583606b1139a43a037..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19149 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

bVaUL}!q88y{QQ?r(PMb$$ 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 GOZW$!hAhAU diff --git a/luci-theme-ezengreen/htdocs/luci-static/resources/menu-ezengreen.js b/luci-theme-ezengreen/htdocs/luci-static/resources/menu-ezengreen.js deleted file mode 100755 index 5400276b0..000000000 --- a/luci-theme-ezengreen/htdocs/luci-static/resources/menu-ezengreen.js +++ /dev/null @@ -1,118 +0,0 @@ -'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 = ''; - - this.renderModeMenu(tree); - - 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.addEventListener('poll-start', this.handleBodyMargin); - document.addEventListener('poll-stop', this.handleBodyMargin); - document.addEventListener('uci-new-changes', this.handleBodyMargin); - document.addEventListener('uci-clear-changes', this.handleBodyMargin); - window.addEventListener('resize', this.handleBodyMargin); - - this.handleBodyMargin(); - }, - - renderTabMenu: function(tree, url, level) { - var container = document.querySelector('#tabmenu'), - ul = E('ul', { 'class': 'tabs' }), - children = ui.menu.getChildren(tree), - activeNode = null; - - for (var i = 0; i < children.length; i++) { - var isActive = (L.env.dispatchpath[3 + (level || 0)] == 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]; - } - - if (ul.children.length == 0) - return E([]); - - container.appendChild(ul); - container.style.display = ''; - - if (activeNode) - this.renderTabMenu(activeNode, url + '/' + activeNode.name, (level || 0) + 1); - - return ul; - }, - - renderMainMenu: function(tree, url, level) { - var ul = level ? E('ul', { 'class': 'dropdown-menu' }) : document.querySelector('#topmenu'), - children = ui.menu.getChildren(tree); - - if (children.length == 0 || level > 1) - return E([]); - - for (var i = 0; i < children.length; i++) { - var submenu = this.renderMainMenu(children[i], url + '/' + children[i].name, (level || 0) + 1), - subclass = (!level && submenu.firstElementChild) ? 'dropdown' : null, - linkclass = (!level && submenu.firstElementChild) ? 'menu' : null, - linkurl = submenu.firstElementChild ? '#' : L.url(url, children[i].name); - - var li = E('li', { 'class': subclass }, [ - E('a', { 'class': linkclass, 'href': linkurl }, [ _(children[i].title) ]), - submenu - ]); - - ul.appendChild(li); - } - - ul.style.display = ''; - - return ul; - }, - - renderModeMenu: function(tree) { - var ul = document.querySelector('#modemenu'), - 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); - - ul.appendChild(E('li', { 'class': isActive ? 'active' : null }, [ - E('a', { 'href': L.url(children[i].name) }, [ _(children[i].title) ]), - ' ', - E('span', { 'class': 'divider' }, [ '|' ]) - ])); - - if (isActive) - this.renderMainMenu(children[i], children[i].name); - } - - if (ul.children.length > 1) - ul.style.display = ''; - }, - - handleBodyMargin: function(ev) { - var body = document.querySelector('body'), - head = document.querySelector('header'); - - body.style.marginTop = head.offsetHeight + 'px'; - } -}); diff --git a/luci-theme-ezengreen/luasrc/view/themes/ezengreen/footer.htm b/luci-theme-ezengreen/luasrc/view/themes/ezengreen/footer.htm deleted file mode 100755 index 0fdd0e4d3..000000000 --- a/luci-theme-ezengreen/luasrc/view/themes/ezengreen/footer.htm +++ /dev/null @@ -1,19 +0,0 @@ -<%# - Copyright 2008 Steven Barth - Copyright 2008 Jo-Philipp Wich - Copyright 2012 David Menting - Licensed to the public under the Apache License 2.0. --%> - -<% local ver = require "luci.version" %> - -

-
- - - - diff --git a/luci-theme-ezengreen/luasrc/view/themes/ezengreen/header.htm b/luci-theme-ezengreen/luasrc/view/themes/ezengreen/header.htm deleted file mode 100755 index f4a63ebaf..000000000 --- a/luci-theme-ezengreen/luasrc/view/themes/ezengreen/header.htm +++ /dev/null @@ -1,90 +0,0 @@ -<%# - Copyright 2008 Steven Barth - Copyright 2008-2016 Jo-Philipp Wich - Copyright 2012 David Menting - 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 boardinfo = util.ubus("system", "board") - - local node = disp.context.dispatched - - -- send as HTML5 - http.prepare_content("text/html") - - -- Get current and latest OMR version - local current_omr_version = luci.model.uci.cursor():get("openmptcprouter","settings","version") or "" - local latest_omr_version = luci.model.uci.cursor():get("openmptcprouter","latest_versions","omr") or "" - --%> - - - - - <%=striptags( (boardinfo.hostname or "?") .. ( (node and node.title) and ' - ' .. translate(node.title) or '')) %> - system - - - - - - - - - <% if node and node.css then %> - - <% end -%> - <% if css then %> - - <% end -%> - - - - - "> -
-
- -
-
- -
- <%- if luci.sys.process.info("uid") == 0 and luci.sys.user.getuser("root") and not luci.sys.user.getpasswd("root") then -%> -
-

<%:No password set!%>

-

<%:There is no password set on this router. Please configure a root password to protect the web interface.%>

- <% if disp.lookup("admin/system/admin") then %> - - <% end %> -
- <%- end -%> - <%- if current_omr_version ~= "" and latest_omr_version ~= "" and current_omr_version < latest_omr_version then -%> -
-

<%=translatef("你的蚂蚁聚合openmptcprouter of china商业版 版本号 %s 最新 版本号 %s 现在可以升级",current_omr_version,latest_omr_version)%>

- -
- <%- end -%> -
- - -
- - - - diff --git a/luci-theme-ezengreen/root/etc/uci-defaults/luci-theme-ezengreen b/luci-theme-ezengreen/root/etc/uci-defaults/luci-theme-ezengreen deleted file mode 100755 index e1c8313d2..000000000 --- a/luci-theme-ezengreen/root/etc/uci-defaults/luci-theme-ezengreen +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -if [ "$(uci -q get luci.themes.ezengreen)" = "" ]; then - uci batch <<-EOF - set luci.themes.ezengreen=/luci-static/ezengreen - set luci.main.mediaurlbase=/luci-static/ezengreen - commit luci - EOF -fi -exit 0 diff --git a/luci-theme-openwrt-2020/Makefile b/luci-theme-openwrt-2020/Makefile old mode 100755 new mode 100644 index e5ef95832..0e18a5f43 --- a/luci-theme-openwrt-2020/Makefile +++ b/luci-theme-openwrt-2020/Makefile @@ -9,6 +9,14 @@ include $(TOPDIR)/rules.mk LUCI_TITLE:=LuCI modern OpenWrt theme LUCI_DEPENDS:= +define Package/luci-theme-openwrt-2020/postrm +#!/bin/sh +[ -n "$${IPKG_INSTROOT}" ] || { + uci -q delete luci.themes.OpenWrt2020 + uci commit luci +} +endef + include $(TOPDIR)/feeds/luci/luci.mk # call BuildPackage - OpenWrt buildroot signature diff --git a/luci-theme-openwrt-2020/htdocs/luci-static/openwrt2020/GalanoGrotesqueW00-Regular.woff2 b/luci-theme-openwrt-2020/htdocs/luci-static/openwrt2020/GalanoGrotesqueW00-Regular.woff2 old mode 100755 new mode 100644 diff --git a/luci-theme-openwrt-2020/htdocs/luci-static/openwrt2020/cascade.css b/luci-theme-openwrt-2020/htdocs/luci-static/openwrt2020/cascade.css old mode 100755 new mode 100644 index b412764d4..ff3b90917 --- a/luci-theme-openwrt-2020/htdocs/luci-static/openwrt2020/cascade.css +++ b/luci-theme-openwrt-2020/htdocs/luci-static/openwrt2020/cascade.css @@ -5,6 +5,7 @@ --secondary-dark-color: #212322; --danger-color: #CC1111; --warning-color: #CC8800; + --success-color: #5CB85C; --regular-font: "GalanoGrotesqueW00-Regular"; --base-font-size: 16px; } @@ -14,6 +15,10 @@ src: url("GalanoGrotesqueW00-Regular.woff2") format("woff2"); } +:root[lang="bg"], :root[lang="ru"], :root[lang="uk"], :root[lang="el"], :root[lang="he"] { + --regular-font: "Helvetica"; +} + /* * resets and base style */ @@ -53,13 +58,17 @@ body { min-width: 100%; } +abbr[title], acronym[title] { + text-decoration: dotted underline; +} + /* * scaffholding */ #menubar { background-color: var(--main-bright-color); - background-image: url("omr-logo.png"); + background-image: url("logo.svg"); background-position: 10px center; background-size: 50px 50px; background-repeat: no-repeat; @@ -147,7 +156,8 @@ body { } #mainmenu { - flex: 1 1 200px; + flex: 1 1 100px; + max-width: 250px; background: var(--main-dark-color); color: var(--main-bright-color); padding: 1em; @@ -166,7 +176,7 @@ body { #mainmenu ul { padding: 0; - margin: 0 0 .5em .5em; + margin: 0 0 0 .5em; line-height: 1.5em; } @@ -188,6 +198,7 @@ body { #mainmenu li.active > ul { max-height: 3000px; transition: max-height 1s ease-in-out; + margin: 0 0 .5em .5em; } #mainmenu .l1 > li > a { @@ -269,74 +280,69 @@ body.modal-overlay-active #modal_overlay { * table layout */ -.table { - display: table; +table { width: 100%; margin: 0 0 1rem 0; position: relative; + border-collapse: collapse; } -.tr { - display: table-row; -} - -.tr.cbi-section-table-titles[data-title]::before { +tr.cbi-section-table-titles[data-title]::before { font-weight: bold; border-top: none; } -.tr[data-title]::before { +tr[data-title]::before { content: attr(data-title); display: table-cell; border-top: 1px solid var(--main-dark-color); padding: .5em; } -.th { +th { + text-align: left; font-weight: bold; - display: table-cell; padding: .5em; /* word-break: break-word; */ } -.cbi-section-table-descr .th { +.cbi-section-table-descr th { opacity: .8; font-size: 90%; font-weight: normal; } -.td { - display: table-cell; +td { border-top: 1px solid var(--main-dark-color); padding: .5em; vertical-align: middle; } -.td input:not([type]), -.td input[type="text"], -.td input[type="password"], -.td select, -.td .cbi-dropdown:not(.btn):not(.cbi-button), -.td .cbi-dynlist, -.td .control-group { +td input:not([type]), +td input[type="text"], +td input[type="password"], +td select, +td .cbi-dropdown:not(.btn):not(.cbi-button), +td .cbi-dynlist, +td .control-group { min-width: auto; width: 100%; } -.tr.drag-over-above { +tr.drag-over-above { box-shadow: 0 -6px 6px var(--main-bright-color); } -.tr.drag-over-below { +tr.drag-over-below { box-shadow: 0 6px 6px var(--main-bright-color); } -.tr.placeholder { +tr.placeholder { height: 4em; position: relative; } -.tr.placeholder > .td { +tr.placeholder > td { position: absolute; left: 0; right: 0; @@ -356,51 +362,51 @@ body.modal-overlay-active #modal_overlay { justify-content: space-around; } -.assoclist .td, -[data-page="admin-status-overview"] .td { +.assoclist td, +[data-page="admin-status-overview"] td { font-size: .9rem; vertical-align: middle; } -.assoclist .td:nth-of-type(3) > span { +.assoclist td:nth-of-type(3) > span { display: block; max-width: 270px; font-size: .8rem; } -.assoclist .td:nth-of-type(5) > span { +.assoclist td:nth-of-type(5) > span { font-size: .8rem; } -.assoclist .td > .ifacebadge { +.assoclist td > .ifacebadge { flex-wrap: wrap; justify-content: space-around; max-width: 120px; padding: .2em; } -.assoclist .td > .ifacebadge::after { +.assoclist td > .ifacebadge::after { overflow: hidden; text-overflow: ellipsis; } -.assoclist .td > .ifacebadge > img { +.assoclist td > .ifacebadge > img { margin: 0 25px; } -.assoclist .td > .ifacebadge[data-ssid][data-ifname] > span { +.assoclist td > .ifacebadge[data-ssid][data-ifname] > span { display: none; } -.assoclist .td > .ifacebadge[data-ssid][data-ifname]::after { +.assoclist td > .ifacebadge[data-ssid][data-ifname]::after { content: attr(data-ssid) " (" attr(data-ifname) ")"; } -[data-page="admin-status-overview"] .td:nth-of-type(3) { +[data-page="admin-status-overview"] td:nth-of-type(3) { min-width: 100px; } -[data-page="admin-network-firewall"] .table > .tr > *:nth-child(1) { +[data-page="admin-network-firewall"] table > tr > *:nth-child(1) { flex: 1 1 30%; } @@ -412,8 +418,8 @@ body.modal-overlay-active #modal_overlay { flex: 1; } -[data-page="admin-status-processes"] .table .td:nth-of-type(3), -[data-tab="leases"] .table .td[data-name="duid"] { +[data-page="admin-status-processes"] table td:nth-of-type(3), +[data-tab="leases"] table td[data-name="duid"] { word-break: break-word; } @@ -630,6 +636,10 @@ ul > li { list-style: disc; } +p > a { + text-decoration: underline; +} + /* * widgets */ @@ -666,7 +676,7 @@ ul > li { padding: 0; text-align: center; width: 100%; - max-width: 100px; + max-width: 150px; } .ifacebox-head { @@ -853,8 +863,11 @@ ul > li { background: var(--danger-color); } +.alert-message.success { + background: var(--success-color); +} + .alert-message .btn { - background: inherit; box-shadow: 0 0 2px var(--secondary-bright-color); } @@ -885,7 +898,7 @@ ul > li { * forms */ -.cbi-button, button, .btn { +button, .btn { background: var(--main-bright-color); color: var(--secondary-bright-color); line-height: 1.5em; @@ -896,7 +909,7 @@ ul > li { display: inline-block; } -.cbi-button:hover, button:hover, .btn:hover { +button:hover, .btn:hover { box-shadow: 0 0 6px var(--main-bright-color); } @@ -1517,11 +1530,12 @@ div[id$=".editlist"] { top: 0; bottom: 0; left: .4em; - width: 1.3em; - height: 1.3em; + width: 1.4em; + height: 1.4em; animation: spin 1s linear infinite; content: url("spinner.svg"); margin: auto; + line-height: 0; } button.spinning, .btn.spinning { @@ -1555,6 +1569,10 @@ button.spinning::before, .btn.spinning::before { background: var(--danger-color); } +.label.success { + background: var(--success-color); +} + ul.deps { margin: 0; padding: 0; @@ -1660,25 +1678,25 @@ ul.errors { display: none !important; } - .table { + table { display: flex; flex-direction: column; } - .tr { + tr { display: block; border-bottom: 1px solid var(--main-dark-color); margin-bottom: .5em; padding-bottom: .5em; } - .tr.cbi-section-table-titles[data-title]::before, - .tr.cbi-section-table-titles, - .tr.cbi-section-table-descr { + tr.cbi-section-table-titles[data-title]::before, + tr.cbi-section-table-titles, + tr.cbi-section-table-descr { display: none; } - .tr[data-title]::before { + tr[data-title]::before { display: block; font-weight: bold; border-top: none; @@ -1686,23 +1704,23 @@ ul.errors { font-size: 110%; } - .td { + td { display: block; border-top: none; text-align: left !important; padding: .2em 0; } - .th, .table-titles { + th, table-titles { display: none; } - .td[data-title] { + td[data-title] { position: relative; padding: .2em 0 .2em 40%; } - .td[data-title]::before { + td[data-title]::before { content: attr(data-title) ": "; white-space: nowrap; font-weight: bold; @@ -1719,7 +1737,7 @@ ul.errors { align-items: center; } - .td[data-title]::after { + td[data-title]::after { content: ""; width: 2em; position: absolute; @@ -1730,93 +1748,93 @@ ul.errors { background: linear-gradient(90deg, rgba(255, 255, 255, 0), var(--secondary-bright-color) 90%); } - [data-page="admin-status-overview"] .cbi-section:nth-of-type(1) .td:first-of-type, - [data-page="admin-status-overview"] .cbi-section:nth-of-type(2) .td:first-of-type { + [data-page="admin-status-overview"] .cbi-section:nth-of-type(1) td:first-of-type, + [data-page="admin-status-overview"] .cbi-section:nth-of-type(2) td:first-of-type { font-weight: bold; max-width: none; width: 100%; } - [data-page="admin-status-overview"] .td > span > span { font-size: .9rem; } + [data-page="admin-status-overview"] td > span > span { font-size: .9rem; } - [data-page="admin-status-routes"] .table:nth-of-type(3) .td:nth-of-type(1) { word-break: break-all; } + [data-page="admin-status-routes"] table:nth-of-type(3) td:nth-of-type(1) { word-break: break-all; } - [data-page="admin-network-firewall-zones"] .td[data-name="_info"] { + [data-page="admin-network-firewall-zones"] td[data-name="_info"] { padding: .2em 0; line-height: 2.2rem; } - [data-page="admin-network-firewall-zones"] .td[data-name="_info"]::before, - [data-page="admin-network-firewall-zones"] .td[data-name="_info"]::after { + [data-page="admin-network-firewall-zones"] td[data-name="_info"]::before, + [data-page="admin-network-firewall-zones"] td[data-name="_info"]::after { display: none; } - [data-page="admin-network-firewall-zones"] .td[data-name="_info"] label { + [data-page="admin-network-firewall-zones"] td[data-name="_info"] label { font-size: 1rem; } - #cbi-wireless-wifi-device .tr { display: flex; flex-wrap: wrap; } - #cbi-wireless-wifi-device .tr > *:nth-child(1) { flex: 1 1 20%; align-self: center; } - #cbi-wireless-wifi-device .tr > *:nth-child(2) { flex: 2 2 75%; } - #cbi-wireless-wifi-device .tr > *:nth-child(3) { flex: 3 3 100%; } + #cbi-wireless-wifi-device tr { display: flex; flex-wrap: wrap; } + #cbi-wireless-wifi-device tr > *:nth-child(1) { flex: 1 1 20%; align-self: center; } + #cbi-wireless-wifi-device tr > *:nth-child(2) { flex: 2 2 75%; } + #cbi-wireless-wifi-device tr > *:nth-child(3) { flex: 3 3 100%; } - #cbi-network-interface .tr { display: flex; flex-wrap: wrap; } - #cbi-network-interface .tr > *:nth-child(1) { flex: 1 1 33%; align-self: center; } - #cbi-network-interface .tr > *:nth-child(2) { flex: 2 2 60%; align-self: center; font-size: .9rem; overflow: hidden; } - #cbi-network-interface .tr > *:nth-child(3) { flex: 3 3 100%; } - #cbi-network-interface .tr > *:nth-child(2) > div { overflow: hidden; text-overflow: ellipsis; } + #cbi-network-interface tr { display: flex; flex-wrap: wrap; } + #cbi-network-interface tr > *:nth-child(1) { flex: 1 1 33%; align-self: center; } + #cbi-network-interface tr > *:nth-child(2) { flex: 2 2 60%; align-self: center; font-size: .9rem; overflow: hidden; } + #cbi-network-interface tr > *:nth-child(3) { flex: 3 3 100%; } + #cbi-network-interface tr > *:nth-child(2) > div { overflow: hidden; text-overflow: ellipsis; } - .assoclist .tr { + .assoclist tr { display: flex; flex-wrap: wrap; } - .assoclist .td > .ifacebadge { + .assoclist td > .ifacebadge { max-width: 90px; } - .assoclist .td > .ifacebadge > img { + .assoclist td > .ifacebadge > img { margin: 0 35px; } - .assoclist .td > .ifacebadge > span { + .assoclist td > .ifacebadge > span { display: none; } - .assoclist .td > .ifacebadge[data-ifname]::after { + .assoclist td > .ifacebadge[data-ifname]::after { content: attr(data-ifname); } - .assoclist .td > .ifacebadge[data-signal]::after { + .assoclist td > .ifacebadge[data-signal]::after { content: attr(data-signal) " dBm"; } - .assoclist .td:nth-of-type(3) { + .assoclist td:nth-of-type(3) { font-weight: bold; font-size: 1rem; } - .assoclist .td:nth-of-type(1), .assoclist .td:nth-of-type(4) { + .assoclist td:nth-of-type(1), .assoclist td:nth-of-type(4) { flex: 1 1 100px; margin-right: .5em; } - .assoclist .td:nth-of-type(3), .assoclist .td:nth-of-type(5) { + .assoclist td:nth-of-type(3), .assoclist td:nth-of-type(5) { flex: 2 2 calc(100% - 110px); overflow: hidden; text-overflow: ellipsis; align-self: center; } - .assoclist .td:nth-of-type(6) { flex: 1; text-align: right !important; } - .assoclist .td[data-title] { padding: .2em 0; } - .assoclist .td[data-title]::before, - .assoclist .td[data-title]::after { display: none; } + .assoclist td:nth-of-type(6) { flex: 1; text-align: right !important; } + .assoclist td[data-title] { padding: .2em 0; } + .assoclist td[data-title]::before, + .assoclist td[data-title]::after { display: none; } - .leases6 .td:nth-of-type(3) { word-wrap: break-word; } + .leases6 td:nth-of-type(3) { word-wrap: break-word; } - .td.cbi-section-actions > div { display: flex; } - .td.cbi-section-actions > div > * { flex: 1; } + td.cbi-section-actions > div { display: flex; } + td.cbi-section-actions > div > * { flex: 1; } body.modal-overlay-active #modal_overlay > .modal { width: 95%; @@ -1919,7 +1937,7 @@ ul.errors { } @media only screen and (min-width: 800px) and (max-width: 1200px) { - .assoclist .tr > *:nth-of-type(2) { + .assoclist tr > *:nth-of-type(2) { display: none; } } diff --git a/luci-theme-openwrt-2020/htdocs/luci-static/openwrt2020/favicon.png b/luci-theme-openwrt-2020/htdocs/luci-static/openwrt2020/favicon.png deleted file mode 100755 index 7c3f3acb1f0c7c142d0dbd3f42a4926b07f8eb38..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 535 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 + + + + + + diff --git a/luci-theme-openwrt-2020/htdocs/luci-static/openwrt2020/omr-logo.png b/luci-theme-openwrt-2020/htdocs/luci-static/openwrt2020/omr-logo.png deleted file mode 100755 index f8584ac11a5020cc2dfe049b6b87025ab7c35782..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 50790 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 diff --git a/luci-theme-openwrt-2020/htdocs/luci-static/openwrt2020/spinner.svg b/luci-theme-openwrt-2020/htdocs/luci-static/openwrt2020/spinner.svg old mode 100755 new mode 100644 diff --git a/luci-theme-openwrt-2020/htdocs/luci-static/resources/menu-openwrt2020.js b/luci-theme-openwrt-2020/htdocs/luci-static/resources/menu-openwrt2020.js old mode 100755 new mode 100644 diff --git a/luci-theme-openwrt-2020/luasrc/view/themes/openwrt2020/header.htm b/luci-theme-openwrt-2020/luasrc/view/themes/openwrt2020/header.htm deleted file mode 100755 index fb0842df0..000000000 --- a/luci-theme-openwrt-2020/luasrc/view/themes/openwrt2020/header.htm +++ /dev/null @@ -1,63 +0,0 @@ -<%# - Copyright 2020 Jo-Philipp Wich - 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") or { } - - local node = disp.context.dispatched - local path = table.concat(disp.context.path, "-") - - http.prepare_content("text/html; charset=UTF-8") --%> - - - - - - - - - - -<%=striptags( (boardinfo.hostname or "?") .. ( (node and node.title) and ' - ' .. translate(node.title) or '')) %> - LuCI - - - - - - - - - -
- - -
- <%- if luci.sys.process.info("uid") == 0 and luci.sys.user.getuser("root") and not luci.sys.user.getpasswd("root") and category ~= "failsafe" and path ~= "admin-system-admin-password" then -%> -
-

<%:No password set!%>

-

<%:There is no password set on this router. Please configure a root password to protect the web interface.%>

- <% if disp.lookup("admin/system/admin") then %> - - <% end %> -
- <%- end -%> - - diff --git a/luci-theme-openwrt-2020/root/etc/uci-defaults/30_luci-theme-openwrt-2020 b/luci-theme-openwrt-2020/root/etc/uci-defaults/30_luci-theme-openwrt-2020 index cd41631de..7c49acfda 100755 --- a/luci-theme-openwrt-2020/root/etc/uci-defaults/30_luci-theme-openwrt-2020 +++ b/luci-theme-openwrt-2020/root/etc/uci-defaults/30_luci-theme-openwrt-2020 @@ -4,6 +4,7 @@ if [ "$PKG_UPGRADE" != 1 ]; then uci get luci.themes.OpenWrt2020 >/dev/null 2>&1 || \ uci batch <<-EOF set luci.themes.OpenWrt2020=/luci-static/openwrt2020 + set luci.main.mediaurlbase=/luci-static/openwrt2020 commit luci EOF fi diff --git a/luci-theme-openwrt-2020/luasrc/view/themes/openwrt2020/footer.htm b/luci-theme-openwrt-2020/ucode/template/themes/openwrt2020/footer.ut old mode 100755 new mode 100644 similarity index 67% rename from luci-theme-openwrt-2020/luasrc/view/themes/openwrt2020/footer.htm rename to luci-theme-openwrt-2020/ucode/template/themes/openwrt2020/footer.ut index e9122f0b5..5899f2a9d --- a/luci-theme-openwrt-2020/luasrc/view/themes/openwrt2020/footer.htm +++ b/luci-theme-openwrt-2020/ucode/template/themes/openwrt2020/footer.ut @@ -1,14 +1,13 @@ -<%# +{# Copyright 2020 Jo-Philipp Wich Licensed to the public under the Apache License 2.0. --%> +-#}

- <% local ver = require "luci.version" -%> - Powered by <%= ver.luciname %> (<%= ver.luciversion %>) + Powered by {{ version.luciname }} ({{ version.luciversion }})

diff --git a/luci-theme-openwrt-2020/ucode/template/themes/openwrt2020/header.ut b/luci-theme-openwrt-2020/ucode/template/themes/openwrt2020/header.ut new file mode 100644 index 000000000..2b7c58138 --- /dev/null +++ b/luci-theme-openwrt-2020/ucode/template/themes/openwrt2020/header.ut @@ -0,0 +1,72 @@ +{# + Copyright 2020 Jo-Philipp Wich + Licensed to the public under the Apache License 2.0. +-#} + +{% + import { getuid, getspnam } from 'luci.core'; + + const boardinfo = ubus.call('system', 'board'); + + http.prepare_content('text/html; charset=UTF-8'); +-%} + + + + + + + + + + + + + +{{ striptags(`${boardinfo.hostname ?? '?'}${node ? ` - ${node.title}` : ''}`) }} - LuCI +{% if (css): %} + +{% endif %} + + + + + + + + + +
+ + +
+ {% if (getuid() == 0 && getspnam('root')?.pwdp === '' && join('-', ctx.request_path) != 'admin-system-admin'): %} +
+

{{ _('No password set!') }}

+

{{ _('There is no password set on this router. Please configure a root password to protect the web interface.') }}

+ {% if (dispatcher.lookup("admin/system/admin")): %} + + {% endif %} +
+ {% endif %} + + {% if (boardinfo.rootfs_type == "initramfs"): %} +
+

{{ _('System running in recovery (initramfs) mode.') }}

+

{{ _('No changes to settings will be stored and are lost after rebooting. This mode should only be used to install a firmware upgrade') }}

+ {% if (dispatcher.lookup("admin/system/flash")): %} + + {% endif %} +
+ {% endif %} + + diff --git a/msmtp/Makefile b/msmtp/Makefile old mode 100755 new mode 100644 index d4588bbcf..e953eb4e5 --- a/msmtp/Makefile +++ b/msmtp/Makefile @@ -1,7 +1,6 @@ # # Copyright (C) 2009 David Cooper # Copyright (C) 2009-2016 OpenWrt.org -# Copyright (C) 2021 Ycarus (Yannick Chabanois) for OpenMPTCProuter # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. @@ -10,12 +9,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=msmtp -PKG_VERSION:=1.8.14 -PKG_RELEASE:=2 +PKG_VERSION:=1.8.19 +PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz PKG_SOURCE_URL:=https://marlam.de/msmtp/releases -PKG_HASH:=d56f065d711486e9c234618515a02a48a48dab4051b34f3e108fbecb6fb773b4 +PKG_HASH:=34a1e1981176874dbe4ee66ee0d9103c90989aa4dcdc4861e4de05ce7e44526b PKG_MAINTAINER:= PKG_LICENSE:=GPL-3.0-or-later @@ -109,7 +108,7 @@ CONFIGURE_ARGS += \ --without-msmtpd ifeq ($(BUILD_VARIANT),ssl) - CONFIGURE_ARGS += --with-tls=openssl + CONFIGURE_ARGS += --with-tls=gnutls else CONFIGURE_ARGS += --without-tls endif diff --git a/net-tools/Makefile b/net-tools/Makefile old mode 100755 new mode 100644 index 6336c57e5..e620d4e2a --- a/net-tools/Makefile +++ b/net-tools/Makefile @@ -1,7 +1,6 @@ # # Copyright (C) 2006-2010 OpenWrt.org # Copyright (C) 2016 Stijn Segers -# Copyright (C) 2020 Ycarus (Yannick Chabanois) for OpenMPTCProuter # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. @@ -10,15 +9,14 @@ include $(TOPDIR)/rules.mk PKG_NAME:=net-tools -PKG_SOURCE_DATE:=2018-11-03 -PKG_SOURCE_VERSION:=0eebece8c964e3cfa8a018f42b2e7e751a7009a0 -PKG_RELEASE:=2 +PKG_VERSION:=2.10 +PKG_RELEASE:=1 -PKG_SOURCE_PROTO:=git -PKG_SOURCE_URL:=https://git.code.sf.net/p/net-tools/code -PKG_MIRROR_HASH:=9d978b9f8ccae4af623a299155c62d9b3d31213182c785f925bf8704d48a04c9 +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz +PKG_SOURCE_URL:=https://sourceforge.net/projects/net-tools/files/ +PKG_HASH:=b262435a5241e89bfa51c3cabd5133753952f7a7b7b93f32e08cb9d96f580d69 -PKG_MAINTAINER:=Yannick Chabanois +PKG_MAINTAINER:=Stijn Segers PKG_LICENSE:=GPL-2.0-or-later PKG_LICENSE_FILES:=COPYING diff --git a/net-tools/patches/mptcp-support.patch b/net-tools/patches/mptcp-support.patch deleted file mode 100755 index b9f69d0f8..000000000 --- a/net-tools/patches/mptcp-support.patch +++ /dev/null @@ -1,338 +0,0 @@ -diff -aurN net-tools-code-0eebece8c964e3cfa8a018f42b2e7e751a7009a0/lib/pathnames.h net-tools-mptcp_v0.95/lib/pathnames.h ---- net-tools-code-0eebece8c964e3cfa8a018f42b2e7e751a7009a0/lib/pathnames.h 2018-11-03 14:23:32.000000000 +0100 -+++ net-tools-mptcp_v0.95/lib/pathnames.h 2019-06-22 22:52:42.000000000 +0200 -@@ -14,6 +14,7 @@ - #define _PATH_PROCNET_IGMP6 "/proc/net/igmp6" - #define _PATH_PROCNET_TCP "/proc/net/tcp" - #define _PATH_PROCNET_TCP6 "/proc/net/tcp6" -+#define _PATH_PROCNET_MPTCP "/proc/net/mptcp_net/mptcp" - #define _PATH_PROCNET_UDP "/proc/net/udp" - #define _PATH_PROCNET_UDP6 "/proc/net/udp6" - #define _PATH_PROCNET_UDPLITE "/proc/net/udplite" -diff -aurN net-tools-code-0eebece8c964e3cfa8a018f42b2e7e751a7009a0/netstat.c net-tools-mptcp_v0.95/netstat.c ---- net-tools-code-0eebece8c964e3cfa8a018f42b2e7e751a7009a0/netstat.c 2018-11-03 14:23:32.000000000 +0100 -+++ net-tools-mptcp_v0.95/netstat.c 2019-06-22 22:52:42.000000000 +0200 -@@ -115,7 +115,7 @@ - #endif - - /* prototypes for statistics.c */ --void parsesnmp(int, int, int, int); -+void parsesnmp(int, int, int, int, int); - void parsesnmp6(int, int, int); - - typedef enum { -@@ -155,6 +155,7 @@ - int flag_opt = 0; - int flag_raw = 0; - int flag_tcp = 0; -+int flag_mptcp = 0; - int flag_sctp= 0; - int flag_udp = 0; - int flag_udplite = 0; -@@ -1206,6 +1207,83 @@ - tcp_do_one, "tcp", "tcp6"); - } - -+static void mptcp_do_one(int lnr, const char *line, const char *prot) -+{ -+ int d, ipv6, num, local_port, rem_port, state, nsub; -+ unsigned long txq, rxq, local_token, remote_token, inode; -+ char rem_addr[128], local_addr[128]; -+ struct sockaddr_storage localsas, remsas; -+ struct sockaddr_in *localaddr = (struct sockaddr_in *)&localsas; -+ struct sockaddr_in *remaddr = (struct sockaddr_in *)&remsas; -+ const struct aftype *ap; -+#if HAVE_AFINET6 -+ char addr6[INET6_ADDRSTRLEN]; -+ struct in6_addr in6; -+ extern struct aftype inet6_aftype; -+#endif -+ -+ if (lnr == 0) -+ return; -+ -+ num = sscanf(line, "%d: %lX %lX %d %64[0-9A-Fa-f]:%X %64[0-9A-Fa-f]:%X " -+ "%X %X %lX:%lX %lu\n", &d, &local_token, &remote_token, -+ &ipv6, local_addr, &local_port, rem_addr, &rem_port, -+ &state, &nsub, &txq, &rxq, &inode); -+ -+ if (strlen(local_addr) > 8) { -+#if HAVE_AFINET6 -+ /* Demangle what the kernel gives us */ -+ sscanf(local_addr, "%08X%08X%08X%08X", -+ &in6.s6_addr32[0], &in6.s6_addr32[1], -+ &in6.s6_addr32[2], &in6.s6_addr32[3]); -+ inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6)); -+ inet6_aftype.input(1, addr6, &localsas); -+ sscanf(rem_addr, "%08X%08X%08X%08X", -+ &in6.s6_addr32[0], &in6.s6_addr32[1], -+ &in6.s6_addr32[2], &in6.s6_addr32[3]); -+ inet_ntop(AF_INET6, &in6, addr6, sizeof(addr6)); -+ inet6_aftype.input(1, addr6, &remsas); -+ localsas.ss_family = AF_INET6; -+ remsas.ss_family = AF_INET6; -+#endif -+ } else { -+ sscanf(local_addr, "%X", -+ &((struct sockaddr_in *) &localaddr)->sin_addr.s_addr); -+ sscanf(rem_addr, "%X", -+ &((struct sockaddr_in *) &remaddr)->sin_addr.s_addr); -+ localsas.ss_family = AF_INET; -+ remsas.ss_family = AF_INET; -+ } -+ -+ if (num < 12) { -+ fprintf(stderr, _("warning, got bogus mptcp line.\n")); -+ return; -+ } -+ -+ if ((ap = get_afntype(localsas.ss_family)) == NULL) { -+ fprintf(stderr, _("netstat: unsupported address family %d !\n"), -+ localsas.ss_family); -+ return; -+ } -+ -+ addr_do_one(local_addr, sizeof(local_addr), 22, ap, &localsas, local_port, "tcp"); -+ addr_do_one(rem_addr, sizeof(rem_addr), 22, ap, &remsas, rem_port, "tcp"); -+ -+ printf("%-4s %6ld %6ld %-*s %-*s %-11s", -+ prot, rxq, txq, (int)netmax(23,strlen(local_addr)), local_addr, -+ (int)netmax(23,strlen(rem_addr)), rem_addr, _(tcp_state[state])); -+ -+ if (flag_mptcp) -+ printf(" %-11lu %-12lu", local_token, remote_token); -+ -+ finish_this_one(0, inode, NULL); -+} -+ -+static int mptcp_info(void) -+{ -+ INFO_GUTS(_PATH_PROCNET_MPTCP, "AF INET (mptcp)", mptcp_do_one, "mptcp"); -+} -+ - static int notnull(const struct sockaddr_storage *sas) - { - const struct sockaddr_in *sin = (const struct sockaddr_in *)sas; -@@ -1994,7 +2072,7 @@ - fprintf(fp, _(" -Z, --context display SELinux security context for sockets\n")); - #endif - -- fprintf(fp, _("\n ={-t|--tcp} {-u|--udp} {-U|--udplite} {-S|--sctp} {-w|--raw}\n")); -+ fprintf(fp, _("\n ={-t|--tcp} {-m|--mptcp} {-u|--udp} {-U|--udplite} {-S|--sctp} {-w|--raw}\n")); - fprintf(fp, _(" {-x|--unix} --ax25 --ipx --netrom\n")); - fprintf(fp, _(" =Use '-6|-4' or '-A ' or '--'; default: %s\n"), DFLT_AF); - fprintf(fp, _(" List of possible address families (which support routing):\n")); -@@ -2019,6 +2097,7 @@ - #endif - {"protocol", 1, 0, 'A'}, - {"tcp", 0, 0, 't'}, -+ {"mptcp", 0, 0, 'm'}, - {"sctp", 0, 0, 'S'}, - {"udp", 0, 0, 'u'}, - {"udplite", 0, 0, 'U'}, -@@ -2055,7 +2134,7 @@ - getroute_init(); /* Set up AF routing support */ - - afname[0] = '\0'; -- while ((i = getopt_long(argc, argv, "A:CFMacdeghilnNoprsStuUvVWw2fx64?Z", longopts, &lop)) != EOF) -+ while ((i = getopt_long(argc, argv, "A:CFMacdeghilnNoprsStmuUvVWw2fx64?Z", longopts, &lop)) != EOF) - switch (i) { - case -1: - break; -@@ -2146,6 +2225,9 @@ - case 't': - flag_tcp++; - break; -+ case 'm': -+ flag_mptcp++; -+ break; - case 'S': - flag_sctp++; - break; -@@ -2194,17 +2276,17 @@ - usage(E_OPTERR); - - if ((flag_inet || flag_inet6 || flag_sta) && -- !(flag_tcp || flag_sctp || flag_udp || flag_udplite || flag_raw)) -- flag_noprot = flag_tcp = flag_sctp = flag_udp = flag_udplite = flag_raw = 1; -+ !(flag_tcp || flag_sctp || flag_mptcp || flag_udp || flag_udplite || flag_raw)) -+ flag_noprot = flag_tcp = flag_mptcp = flag_sctp = flag_udp = flag_udplite = flag_raw = 1; - -- if ((flag_tcp || flag_sctp || flag_udp || flag_udplite || flag_raw || flag_igmp) && -+ if ((flag_tcp || flag_sctp || flag_mptcp || flag_udp || flag_udplite || flag_raw || flag_igmp) && - !(flag_inet || flag_inet6)) - flag_inet = flag_inet6 = 1; - - if (flag_bluetooth && !(flag_l2cap || flag_rfcomm)) - flag_l2cap = flag_rfcomm = 1; - -- flag_arg = flag_tcp + flag_sctp + flag_udplite + flag_udp + flag_raw + flag_unx -+ flag_arg = flag_tcp + flag_mptcp +flag_sctp + flag_udplite + flag_udp + flag_raw + flag_unx - + flag_ipx + flag_ax25 + flag_netrom + flag_igmp + flag_x25 + flag_rose - + flag_l2cap + flag_rfcomm; - -@@ -2234,7 +2316,7 @@ - - if (!strcmp(afname, "inet")) { - #if HAVE_AFINET -- parsesnmp(flag_raw, flag_tcp, flag_udp, flag_sctp); -+ parsesnmp(flag_raw, flag_tcp, flag_udp, flag_sctp, flag_mptcp); - #else - ENOSUPP("netstat", "AF INET"); - #endif -@@ -2284,7 +2366,7 @@ - return (i); - } - for (;;) { -- if (!flag_arg || flag_tcp || flag_sctp || flag_udp || flag_udplite || flag_raw) { -+ if (!flag_arg || flag_tcp || flag_mptcp || flag_sctp || flag_udp || flag_udplite || flag_raw) { - #if HAVE_AFINET - prg_cache_load(); - printf(_("Active Internet connections ")); /* xxx */ -@@ -2298,6 +2380,8 @@ - printf(_("(w/o servers)")); - } - printf(_("\nProto Recv-Q Send-Q Local Address Foreign Address State ")); /* xxx */ -+ if (flag_mptcp) -+ printf(_(" Local Token Remote Token ")); - if (flag_exp > 1) - printf(_(" User Inode ")); - print_progname_banner(); -@@ -2318,6 +2402,12 @@ - if (i) - return (i); - } -+ -+ if (!flag_arg || flag_mptcp) { -+ i = mptcp_info(); -+ if (i) -+ return (i); -+ } - - if (!flag_arg || flag_sctp) { - i = sctp_info(); -diff -aurN net-tools-code-0eebece8c964e3cfa8a018f42b2e7e751a7009a0/statistics.c net-tools-mptcp_v0.95/statistics.c ---- net-tools-code-0eebece8c964e3cfa8a018f42b2e7e751a7009a0/statistics.c 2018-11-03 14:23:32.000000000 +0100 -+++ net-tools-mptcp_v0.95/statistics.c 2019-06-22 22:52:42.000000000 +0200 -@@ -13,7 +13,7 @@ - #include "intl.h" - #include "proc.h" - --static int print_static,f_raw,f_tcp,f_udp,f_sctp,f_unknown = 1; -+static int print_static,f_raw,f_tcp,f_udp,f_sctp,f_mptcp,f_unknown = 1; - - enum State { - number = 0, opt_number, i_forward, i_inp_icmp, i_outp_icmp, i_rto_alg, -@@ -295,6 +295,51 @@ - {"SctpShutdowns", N_("%llu Number of Graceful Terminations"), number}, - }; - -+static const struct entry Mptcptab[] = -+{ /* Keep the entries sorted! */ -+ {"AddAddrRx", N_("%llu Number of ADD_ADDRs received"), number}, -+ {"AddAddrTx", N_("%llu Number of ADD_ADDRs sent"), number}, -+ {"DSSNoMatchTCP", N_("%llu Number of DSS-mapping/TCP sequence number mismatches"), number}, -+ {"DSSNotMatching", N_("%llu Number of new mismatched mappings"), number}, -+ {"DSSPurgeOldSubSegs", N_("%llu Number of skbs removed from the rcv-queue due to missing DSS-mapping"), number}, -+ {"DSSSplitTail", N_("%llu Number of trimmed segments at the tail"), number}, -+ {"DSSTrimHead", N_("%llu Number of trimmed segments at the head"), number}, -+ {"InfiniteMapRx", N_("%llu Number of infinite mappings received"), number}, -+ {"MPCapableACKRX", N_("%llu Number of received third ACKs with MP_CAPABLE"), number}, -+ {"MPCapableFallbackACK", N_("%llu Number of server-side fallbacks during the 3-way handshake"), number}, -+ {"MPCapableFallbackSYNACK", N_("%llu Number of client-side fallbacks during the 3-way handshake"), number}, -+ {"MPCapableRetransFallback", N_("%llu Number of times the client-side stopped sending MP_CAPABLE after too many SYN-retransmissions"), -+ number}, -+ {"MPCapableSYNACKRX", N_("%llu Number of received SYN/ACKs with MP_CAPABLE"), number}, -+ {"MPCapableSYNRX", N_("%llu Number of received SYNs with MP_CAPABLE"), number}, -+ {"MPCapableSYNTX", N_("%llu Number of sent SYNs with MP_CAPABLE"), number}, -+ {"MPCsumFail", N_("%llu Number of received segments with an invalid checksum"), number}, -+ {"MPFailRX", N_("%llu Number of MP_FAILs received"), number}, -+ {"MPFallbackAckInit", N_("%llu Number of fallbacks upon ack without data-ack on initial subflow"), number}, -+ {"MPFallbackAckSub", N_("%llu Number of fallbacks upon ack without data-ack on new subflow"), number}, -+ {"MPFallbackDataInit", N_("%llu Number of fallbacks upon data without DSS at the beginning on initial subflow"), number}, -+ {"MPFallbackDataSub", N_("%llu Number of fallbacks upon data without DSS at the beginning on new subflow"), number}, -+ {"MPFastcloseRX", N_("%llu Number of FAST_CLOSEs received"), number}, -+ {"MPFastcloseTX", N_("%llu Number of FAST_CLOSEs sent"), number}, -+ {"MPJoinAckHMacFailure", N_("%llu Number of HMAC mismatches on ACK + MP_JOIN"), number}, -+ {"MPJoinAckMissing", N_("%llu Number of third ACKs on a new subflow not containing a MP_JOIN"), number}, -+ {"MPJoinAckRTO", N_("%llu Number of retransmission timeouts for third ACK + MP_JOIN"), number}, -+ {"MPJoinAckRexmit", N_("%llu Number of retransmitted ACK + MP_JOINs"), number}, -+ {"MPJoinAckRx", N_("%llu Number of ACK + MP_JOINs received"), number}, -+ {"MPJoinAlreadyFallenback", N_("%llu Number of received MP_JOINs on a session that has fallen back to reg. TCP"), number}, -+ {"MPJoinNoTokenFound", N_("%llu Number of received MP_JOINs without a token"), number}, -+ {"MPJoinSynAckHMacFailure", N_("%llu Number of received SYN/ACK + MP_JOINs with a HMAC mismatch"), number}, -+ {"MPJoinSynAckRx", N_("%llu Number of SYN/ACK + MP_JOINs received"), number}, -+ {"MPJoinSynRx", N_("%llu Number of SYN + MP_JOINs received"), number}, -+ {"MPJoinSynTx", N_("%llu Number of SYN + MP_JOINs sent"), number}, -+ {"MPRemoveAddrSubDelete", N_("%llu Number of subflows removed due to REMOVE_ADDR"), number}, -+ {"MPTCPCsumEnabled", N_("%llu Number of MPTCP connections created with DSS-checksum enabled"), number}, -+ {"MPTCPRetrans", N_("%llu Number of segments retransmitted at the MPTCP level"), number}, -+ {"NoDSSInWindow", N_("%llu Number of too many packets received without a DSS option errors"), number}, -+ {"RemAddrRx", N_("%llu Number of REMOVE_ADDRs received"), number}, -+ {"RemAddrTx", N_("%llu Number of REMOVE_ADDRs sent"), number}, -+}; -+ - struct tabtab { - const char *title; - const struct entry *tab; -@@ -310,6 +355,7 @@ - {"Udp", Udptab, sizeof(Udptab), &f_udp}, - {"Sctp", Sctptab, sizeof(Sctptab), &f_sctp}, - {"TcpExt", Tcpexttab, sizeof(Tcpexttab), &f_tcp}, -+ {"Mptcp", Mptcptab, sizeof(Mptcptab), &f_mptcp}, - {NULL} - }; - -@@ -503,13 +549,13 @@ - } - - /* Process a file with name-value lines (like /proc/net/sctp/snmp) */ --static void process_fd2(FILE *f, const char *filename) -+static void process_fd2(FILE *f, const char *filename, const char *tablename) - { - char buf1[1024]; - char *sp; - const struct tabtab *tab; - -- tab = newtable(snmptabs, "Sctp"); -+ tab = newtable(snmptabs, tablename); - - while (fgets(buf1, sizeof buf1, f)) { - sp = buf1 + strcspn(buf1, " \t\n"); -@@ -527,11 +573,11 @@ - } - } - --void parsesnmp(int flag_raw, int flag_tcp, int flag_udp, int flag_sctp) -+void parsesnmp(int flag_raw, int flag_tcp, int flag_udp, int flag_sctp, int flag_mptcp) - { - FILE *f; - -- f_raw = flag_raw; f_tcp = flag_tcp; f_udp = flag_udp; f_sctp = flag_sctp; -+ f_raw = flag_raw; f_tcp = flag_tcp; f_udp = flag_udp; f_sctp = flag_sctp; f_mptcp = flag_mptcp; - - f = proc_fopen("/proc/net/snmp"); - if (!f) { -@@ -561,12 +607,21 @@ - - f = proc_fopen("/proc/net/sctp/snmp"); - if (f) { -- process_fd2(f,"/proc/net/sctp/snmp"); -+ process_fd2(f,"/proc/net/sctp/snmp", "Sctp"); - if (ferror(f)) { - perror("/proc/net/sctp/snmp"); - fclose(f); - } - } -+ -+ f = proc_fopen("/proc/net/mptcp_net/snmp"); -+ if (f) { -+ process_fd2(f,"/proc/net/mptcp_net/snmp", "Mptcp"); -+ if (ferror(f)) { -+ perror("/proc/net/mptcp_net/snmp"); -+ fclose(f); -+ } -+ } - } - - void parsesnmp6(int flag_raw, int flag_tcp, int flag_udp) diff --git a/netifd/Makefile b/netifd/Makefile old mode 100755 new mode 100644 index 4b5f110da..31fd0838a --- a/netifd/Makefile +++ b/netifd/Makefile @@ -5,15 +5,15 @@ PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/project/netifd.git -PKG_SOURCE_DATE:=2021-07-26 -PKG_SOURCE_VERSION:=440eb0647708274cc8d7d9e7c2bb0cfdfba90023 -PKG_MIRROR_HASH:=eed957036ab608fdc49bdf801fc5b4405fcd2a3a5e5d3343ec39898e156c10e9 +PKG_SOURCE_DATE:=2023-06-04 +PKG_SOURCE_VERSION:=ec9dba72124597b7224bbfe75960386dc320f4bd +PKG_MIRROR_HASH:=baee39a3882a2b03fc83a3a6a8963c340fa8d884c7a8c9e80e7d2dddc50e24bd PKG_MAINTAINER:=Felix Fietkau PKG_LICENSE:=GPL-2.0 PKG_LICENSE_FILES:= -PKG_BUILD_PARALLEL:=1 +PKG_BUILD_FLAGS:=lto include $(INCLUDE_DIR)/package.mk include $(INCLUDE_DIR)/cmake.mk @@ -32,10 +32,7 @@ endef TARGET_CFLAGS += \ -I$(STAGING_DIR)/usr/include/libnl-tiny \ - -I$(STAGING_DIR)/usr/include \ - -flto - -TARGET_LDFLAGS += -flto -fuse-linker-plugin + -I$(STAGING_DIR)/usr/include CMAKE_OPTIONS += \ -DLIBNL_LIBS=-lnl-tiny \ diff --git a/netifd/files/etc/hotplug.d/iface/00-netstate b/netifd/files/etc/hotplug.d/iface/00-netstate old mode 100755 new mode 100644 diff --git a/netifd/files/etc/init.d/packet_steering b/netifd/files/etc/init.d/packet_steering new file mode 100755 index 000000000..9d8f791e2 --- /dev/null +++ b/netifd/files/etc/init.d/packet_steering @@ -0,0 +1,18 @@ +#!/bin/sh /etc/rc.common + +START=25 +USE_PROCD=1 + +start_service() { + reload_service +} + +service_triggers() { + procd_add_reload_trigger "network" + procd_add_reload_trigger "firewall" + procd_add_raw_trigger "interface.*" 1000 /etc/init.d/packet_steering reload +} + +reload_service() { + /usr/libexec/network/packet-steering.sh +} diff --git a/netifd/files/etc/uci-defaults/14_migrate-dhcp-release b/netifd/files/etc/uci-defaults/14_migrate-dhcp-release old mode 100755 new mode 100644 diff --git a/netifd/files/etc/udhcpc.user b/netifd/files/etc/udhcpc.user old mode 100755 new mode 100644 diff --git a/netifd/files/lib/netifd/dhcp.script b/netifd/files/lib/netifd/dhcp.script index c857c9fc0..6fcf139be 100755 --- a/netifd/files/lib/netifd/dhcp.script +++ b/netifd/files/lib/netifd/dhcp.script @@ -13,7 +13,7 @@ set_classless_routes() { done } -setup_interface() { +setup_interface () { proto_init_update "*" 1 proto_add_ipv4_address "$ip" "${subnet:-255.255.255.0}" # TODO: apply $broadcast @@ -27,7 +27,6 @@ setup_interface() { eval "$(ipcalc.sh "$i/$mask")";gw_net="$NETWORK" [ "$ip_net" != "$gw_net" ] && proto_add_ipv4_route "$i" 32 "" "$ip" - #[ "$DEFAULTROUTE" = 0 ] || proto_add_ipv4_route 0.0.0.0 0 "$i" "$ip" proto_add_ipv4_route 0.0.0.0 0 "$i" "$ip" local r @@ -61,6 +60,7 @@ setup_interface() { [ -n "$message" ] && json_add_string message "$message" [ -n "$timezone" ] && json_add_int timezone "$timezone" [ -n "$lease" ] && json_add_int leasetime "$lease" + [ -n "$serverid" ] && json_add_string dhcpserver "$serverid" proto_close_data proto_send_update "$INTERFACE" diff --git a/netifd/files/lib/netifd/proto/dhcp.sh b/netifd/files/lib/netifd/proto/dhcp.sh index 8db848260..636b4654f 100755 --- a/netifd/files/lib/netifd/proto/dhcp.sh +++ b/netifd/files/lib/netifd/proto/dhcp.sh @@ -1,6 +1,6 @@ #!/bin/sh -[ -L /sbin/udhcpc ] || exit 0 +[ -x /sbin/udhcpc ] || exit 0 . /lib/functions.sh . ../netifd-proto.sh @@ -35,8 +35,8 @@ proto_dhcp_setup() { local config="$1" local iface="$2" - local ipaddr hostname clientid vendorid broadcast norelease reqopts defaultreqopts iface6rd sendopts delegate zone6rd zone mtu6rd customroutes classlessroute defaultroute - json_get_vars ipaddr hostname clientid vendorid broadcast norelease reqopts defaultreqopts iface6rd delegate zone6rd zone mtu6rd customroutes classlessroute defaultroute + local ipaddr hostname clientid vendorid broadcast norelease reqopts defaultreqopts iface6rd sendopts delegate zone6rd zone mtu6rd customroutes classlessroute + json_get_vars ipaddr hostname clientid vendorid broadcast norelease reqopts defaultreqopts iface6rd delegate zone6rd zone mtu6rd customroutes classlessroute local opt dhcpopts for opt in $reqopts; do @@ -58,7 +58,6 @@ proto_dhcp_setup() { [ -n "$zone" ] && proto_export "ZONE=$zone" [ -n "$mtu6rd" ] && proto_export "MTU6RD=$mtu6rd" [ -n "$customroutes" ] && proto_export "CUSTOMROUTES=$customroutes" - [ -n "$defaultroute" ] && proto_export "DEFAULTROUTE=$defaultroute" [ "$delegate" = "0" ] && proto_export "IFACE6RD_DELEGATE=0" # Request classless route option (see RFC 3442) by default [ "$classlessroute" = "0" ] || append dhcpopts "-O 121" @@ -68,7 +67,7 @@ proto_dhcp_setup() { -p /var/run/udhcpc-$iface.pid \ -s /lib/netifd/dhcp.script \ -f -t 0 -i "$iface" \ - ${ipaddr:+-r $ipaddr} \ + ${ipaddr:+-r ${ipaddr/\/*/}} \ ${hostname:+-x "hostname:$hostname"} \ ${vendorid:+-V "$vendorid"} \ $clientid $defaultreqopts $broadcast $norelease $dhcpopts diff --git a/netifd/files/etc/hotplug.d/net/20-smp-packet-steering b/netifd/files/usr/libexec/network/packet-steering.sh similarity index 92% rename from netifd/files/etc/hotplug.d/net/20-smp-packet-steering rename to netifd/files/usr/libexec/network/packet-steering.sh index 8a86bf75f..799c08080 100755 --- a/netifd/files/etc/hotplug.d/net/20-smp-packet-steering +++ b/netifd/files/usr/libexec/network/packet-steering.sh @@ -1,6 +1,4 @@ #!/bin/sh -[ "$ACTION" = add ] || exit - NPROCS="$(grep -c "^processor.*:" /proc/cpuinfo)" [ "$NPROCS" -gt 1 ] || exit @@ -40,6 +38,11 @@ packet_steering="$(uci get "network.@globals[0].packet_steering")" exec 512>/var/lock/smp_tune.lock flock 512 || exit 1 +[ -e "/usr/libexec/platform/packet-steering.sh" ] && { + /usr/libexec/platform/packet-steering.sh + exit 0 +} + for dev in /sys/class/net/*; do [ -d "$dev" ] || continue diff --git a/netmaker-openwrt/LICENSE b/netmaker-openwrt/LICENSE deleted file mode 100755 index 472ac2361..000000000 --- a/netmaker-openwrt/LICENSE +++ /dev/null @@ -1,8 +0,0 @@ -MIT License -Copyright (c) - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/netmaker-openwrt/README.md b/netmaker-openwrt/README.md deleted file mode 100755 index 60b189cce..000000000 --- a/netmaker-openwrt/README.md +++ /dev/null @@ -1,111 +0,0 @@ -# Netmaker-OpenWRT - -[Netmaker](https://github.com/gravitl/netmaker) is a platform for creating and managing fast, secure, and dynamic virtual overlay networks using WireGuard. This project offers OpenWRT packages for Netmaker. - -## Installing package - -Download the prebuild package and copy it onto your OpenWRT installation, preferably into the `/tmp` folder. - -Then install the ipk package file: - -```bash -opkg install netmaker_*.ipk -``` - -Now start `netclient` of Netmaker: - -```bash -/etc/init.d/netclient start -``` - -## Compiling from Sources - -To include Netmaker into your OpenWRT image or to create an `.ipk` package (equivalent to Debians .deb files), you have to build an OpenWRT image. - -Now prepare OpenWRT: - -```bash -git clone https://github.com/openwrt/openwrt -cd openwrt - -./scripts/feeds update -a -./scripts/feeds install -a -``` - -To build Netmaker for OpenWRT, you need to have Golang with OpenWRT build envirment. Then, you can insert the Netmaker package using a package feed or add the package manually. - -### Add package by feed - -A feed is the standard way packages are made available to the OpenWRT build system. - -Put this line in your feeds list file (e.g. feeds.conf.default) - -```bash -src-git netmaker http://github.com/sbilly/netmaker-openwrt.git -``` - -Update and install the new feed - -```bash -./scripts/feeds update netmaker -./scripts/feeds install netmaker -``` - -Now continue with the building packages section. - -## Building Packages - -Configure packages: - -```bash -make menuconfig -``` - -Now select the appropiate "Target System" and "Target Profile" depending on what target chipset/router you want to build for. Also mark the Netmaker package under `Network ---> VPN ---> <*> netmaker`. - -Now compile/build everything: - -```bash -make -``` - -The images and all *.ipk packages are now inside the bin/ folder, including the netmaker package. You can install the Netmaker .ipk on the target device using opkg install . - -For details please check the OpenWRT documentation. - -## Build bulk packages - -For a release, it is useful the build packages at a bulk for multiple targets: - -```shell -#!/bin/sh - -# dump-target-info.pl is used to get all targets configurations: -# https://git.openwrt.org/?p=openwrt/openwrt.git;a=blob;f=scripts/dump-target-info.pl - -./scripts/dump-target-info.pl architectures | while read pkgarch target1 rest; do - echo "CONFIG_TARGET_${target1%/*}=y" > .config - echo "CONFIG_TARGET_${target1%/*}_${target1#*/}=y" >> .config - echo "CONFIG_PACKAGE_example1=y" >> .config - - # Debug output - echo "pkgarch: $pkgarch, target1: $target1" - - make defconfig - make -j4 tools/install - make -j4 toolchain/install - - # Build package - make package/netmaker/{clean,compile} - - # Free space (optional) - rm -rf build_dir/target-* - rm -rf build_dir/toolchain-* -done -``` - -## Thanks - -- [netmaker](https://github.com/gravitl/netmaker) -- [zerotier-openwrt](https://github.com/mwarning/zerotier-openwrt) -- [openwrt-golang-package-test-feed](https://github.com/jefferyto/openwrt-golang-package-test-feed) diff --git a/netmaker-openwrt/netmaker/Makefile b/netmaker-openwrt/netmaker/Makefile deleted file mode 100755 index 903dd2beb..000000000 --- a/netmaker-openwrt/netmaker/Makefile +++ /dev/null @@ -1,93 +0,0 @@ -# -# Copyright (C) 2019 sbilly -# -# This is free software, licensed under the MIT License. -# See /LICENSE for more information. -# - -include $(TOPDIR)/rules.mk - -PKG_NAME:=netmaker -PKG_VERSION:=0.9.4 -PKG_RELEASE:=1 - -PKG_SOURCE_PROTO:=git -PKG_SOURCE_URL:=https://github.com/gravitl/netmaker.git -PKG_SOURCE_VERSION:=e9bce264719f88c30e252ecc754d08f422f4c080 -PKG_SOURCE_DATE:=20220117 -PKG_MIRROR_HASH:=skip - -PKG_LICENSE:=MIT -PKG_LICENSE_FILES:=LICENSE -PKG_MAINTAINER:=sbilly - -PKG_BUILD_DEPENDS:=golang/host -PKG_BUILD_PARALLEL:=1 -PKG_USE_MIPS16:=0 - -GO_PKG:=github.com/gravitl/netmaker -GO_PKG_INSTALL_EXTRA:=extra/file extra/dir -GO_PKG_EXCLUDES:=excluded -GO_PKG_LDFLAGS:=-s -w - -include $(INCLUDE_DIR)/package.mk -include $(TOPDIR)/feeds/packages/lang/golang/golang-package.mk - -define Package/netmaker -$(call Package/netmaker/Default) -$(call GoPackage/GoSubMenu) - SECTION:=net - CATEGORY:=Network - SUBMENU:=VPN -endef - -define Package/netmaker/Default - TITLE:=Netmaker for OpenWRT - URL:=https://github.com/gravitl/netmaker - DEPENDS:=$(GO_ARCH_DEPENDS) - MAINTAINER:=sbilly -endef - -define Package/netmaker/Default/description -Netmaker is a platform for creating and managing fast, secure, and -dynamic virtual overlay networks using WireGuard. This project offers -OpenWRT packages for Netmaker. -endef - -define Package/netmaker/description -$(call Package/netmaker/Default/description) - -This package contains the binaries. -endef - -define Package/netmaker-dev - TITLE+= (source files) - SECTION:=net - CATEGORY:=Network - SUBMENU:=VPN - PKGARCH:=all -endef - -define Package/netmaker-dev/description -$(call Package/netmaker/Default/description) - -This package provides the source files. -endef - -define Package/netmaker/install - $(INSTALL_DIR) $(1)/etc/netclient/ - $(INSTALL_DIR) $(1)/etc/netclient/config - $(INSTALL_DIR) $(1)/etc/systemd/ - $(INSTALL_DIR) $(1)/etc/systemd/system - $(INSTALL_DIR) $(1)/usr/bin - $(INSTALL_BIN) $(GO_PKG_BUILD_BIN_DIR)/netmaker $(1)/usr/bin/ - $(INSTALL_BIN) $(GO_PKG_BUILD_BIN_DIR)/netclient $(1)/usr/bin/ - $(CP) ./root/* $(1)/ - $(LN) netclient $(1)/etc/netclient/netclient -endef - -$(eval $(call GoBinPackage,netmaker)) -$(eval $(call BuildPackage,netmaker)) - -$(eval $(call GoSrcPackage,netmaker-dev)) -$(eval $(call BuildPackage,netmaker-dev)) diff --git a/netmaker-openwrt/netmaker/root/etc/init.d/netclient b/netmaker-openwrt/netmaker/root/etc/init.d/netclient deleted file mode 100755 index c04977f24..000000000 --- a/netmaker-openwrt/netmaker/root/etc/init.d/netclient +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/sh /etc/rc.common -#Created by oycol - -EXTRA_COMMANDS="status" -EXTRA_HELP=" status Check service is running" -START=99 - -LOG_FILE="/tmp/netclient.logs" - -start() { - mkdir -p /etc/netclient/config - mkdir -p /etc/systemd/system - - if [ ! -f "${LOG_FILE}" ];then - touch "${LOG_FILE}" - fi - local PID=$(ps|grep "netclient checkin -n all"|grep -v grep|awk '{print $1}') - if [ "${PID}" ];then - echo "service is running" - return - fi - /bin/sh -c "while [ 1 ]; do netclient checkin -n all >> ${LOG_FILE} 2>&1;sleep 15;\ - if [ $(ls -l ${LOG_FILE}|awk '{print $5}') -gt 10240000 ];then tar zcf "${LOG_FILE}.tar" -C / "tmp/netclient.logs" && > $LOG_FILE;fi;done &" - echo "start" -} - -stop() { - local PID=$(ps|grep "netclient checkin -n all"|grep -v grep|awk '{print $1}') - if [ "${PID}" ];then - kill "${PID}" - fi - echo "stop" -} - -status() { - local PID=$(ps|grep "netclient checkin -n all"|grep -v grep|awk '{print $1}') - if [ "${PID}" ];then - echo -e "netclient[${PID}] is running \n" - else - echo -e "netclient is not running \n" - fi -} diff --git a/netmaker-openwrt/scripts/build_ipk.sh b/netmaker-openwrt/scripts/build_ipk.sh deleted file mode 100755 index 1ee25de06..000000000 --- a/netmaker-openwrt/scripts/build_ipk.sh +++ /dev/null @@ -1,177 +0,0 @@ -#!/bin/bash - -# setting working directory -WORK_DIR="/home/user" - -# setting branch -if [ "${OPENWRT_BRANCH}" = "" ] -then - DEFAULT_OPENWRT_BRANCH="openwrt-21.02" -else - DEFAULT_OPENWRT_BRANCH="${OPENWRT_BRANCH}" -fi - -download_openwrt() { - cd ${WORK_DIR} - - # pull code - if [ ! -d "openwrt" ]; then - git clone https://git.openwrt.org/openwrt/openwrt.git - fi -} - -change_openwrt_branch() { - cd ${WORK_DIR}/openwrt - - if [ "${1}" = "" ] - then - echo "Building ${DEFAULT_OPENWRT_BRANCH}" - git checkout -B ${DEFAULT_OPENWRT_BRANCH} origin/${DEFAULT_OPENWRT_BRANCH} - else - echo "Building ${1}" - git checkout -B ${1} origin/${1} - fi -} - -init_openwrt_branch() { - cd ${WORK_DIR}/openwrt - - git stash - git pull --all - git pull --tags -} - -init_openwrt_link() { - cd ${WORK_DIR}/openwrt - - sudo chown 1000:1000 /src -R - - mkdir -p /src/dl - mkdir -p /src/staging_dir - mkdir -p /src/build_dir - mkdir -p /src/tmp - mkdir -p /src/bin - - ln -s /src/dl ${WORK_DIR}/openwrt/dl - ln -s /src/staging_dir ${WORK_DIR}/openwrt/staging_dir - ln -s /src/build_dir ${WORK_DIR}/openwrt/build_dir - ln -s /src/tmp ${WORK_DIR}/openwrt/tmp -} - -update_install_openwrt_feeds() { - cd ${WORK_DIR}/openwrt - - ./scripts/feeds update -a - ./scripts/feeds install -a -} - -openwrt_init_config() { - cd ${WORK_DIR}/openwrt - - echo "CONFIG_TARGET_x86=y" > ${WORK_DIR}/openwrt/.config - echo "CONFIG_TARGET_x86_64=y" >> ${WORK_DIR}/openwrt/.config -} - -openwrt_make_build_env() { - cd ${WORK_DIR}/openwrt - - make defconfig - make -j4 download - make -j4 tools/install - make -j4 toolchain/install -} - -openwrt_make() { - cd ${WORK_DIR}/openwrt - - make -j4 -} - -openwrt_install_netmaker_feeds() { - cd ${WORK_DIR}/openwrt - - echo "src-git netmaker http://github.com/sbilly/netmaker-openwrt.git" >> feeds.conf.default - - ./scripts/feeds update netmaker - ./scripts/feeds install netmaker -} - -openwrt_install_package_netmaker_config() { - cd ${WORK_DIR}/openwrt - - echo "CONFIG_FEED_netmaker=y" >> ${WORK_DIR}/openwrt/.config - echo "CONFIG_PACKAGE_netmaker=m" >> ${WORK_DIR}/openwrt/.config - echo "CONFIG_PACKAGE_netmaker-dev=m" >> ${WORK_DIR}/openwrt/.config -} - - -openwrt_patch_golang_host() { - cd ${WORK_DIR}/openwrt - echo "patching ${1}" - - if [ "${1}" = "openwrt-19.07" ] - then - sed -i 's/5fb43171046cf8784325e67913d55f88a683435071eef8e9da1aa8a1588fcf5d/2255eb3e4e824dd7d5fcdc2e7f84534371c186312e546fb1086a34c17752f431/g' ${WORK_DIR}/openwrt/feeds/packages/lang/golang/golang/Makefile - sed -i 's/1.13/1.17/g' ${WORK_DIR}/openwrt/feeds/packages/lang/golang/golang-version.mk - sed -i 's/15/2/g' ${WORK_DIR}/openwrt/feeds/packages/lang/golang/golang-version.mk - fi - - if [ "${1}" = "openwrt-18.06" ] - then - sed -i 's/6faf74046b5e24c2c0b46e78571cca4d65e1b89819da1089e53ea57539c63491/2255eb3e4e824dd7d5fcdc2e7f84534371c186312e546fb1086a34c17752f431/g' ${WORK_DIR}/openwrt/feeds/packages/lang/golang/golang/Makefile - sed -i 's/1.10/1.17/g' ${WORK_DIR}/openwrt/feeds/packages/lang/golang/golang-version.mk - sed -i 's/8/2/g' ${WORK_DIR}/openwrt/feeds/packages/lang/golang/golang-version.mk - fi -} - -openwrt_make_netmaker_package() { - cd ${WORK_DIR}/openwrt - - make defconfig - make toolchain/gcc/final/compile - make package/netmaker/clean - find ./ -type d | xargs -n1 sudo chmod 755 -R - make package/netmaker/compile V=s -} - - -openwrt_copy_pacage() { - echo ${1} - echo > /tmp/copy.sh - - cd ${WORK_DIR}/openwrt/bin/packages/x86_64/netmaker/ - - for ipk in ./*.ipk - do - if [ -f "$ipk" ] - then - echo ${ipk} | gawk -F".ipk" -v BRANCH=${1} '{ print "cp -rfv "$0" /src/bin/"$1"-"BRANCH".ipk" }' >> /tmp/copy.sh - fi - done - - /bin/bash /tmp/copy.sh -} - -download_openwrt - -change_openwrt_branch ${DEFAULT_OPENWRT_BRANCH} - -init_openwrt_branch - -init_openwrt_link - -openwrt_install_netmaker_feeds - -update_install_openwrt_feeds - -openwrt_init_config - -openwrt_install_package_netmaker_config - -openwrt_patch_golang_host ${DEFAULT_OPENWRT_BRANCH} - -openwrt_make_netmaker_package - -openwrt_copy_pacage ${DEFAULT_OPENWRT_BRANCH} - -ls -alF ${WORK_DIR}/openwrt/bin/ /src/bin diff --git a/nginx/Config.in b/nginx/Config.in deleted file mode 100755 index 68b037098..000000000 --- a/nginx/Config.in +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright (C) 2010-2016 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - -menu "Configuration" - depends on PACKAGE_nginx - -config NGINX_SSL - bool - prompt "Enable SSL module" - help - Enable HTTPS/SSL support. - default n - -config NGINX_DAV - bool - prompt "Enable WebDAV module" - help - Enable the HTTP and WebDAV methods PUT, DELETE, MKCOL, COPY and MOVE. - default n - -config NGINX_FLV - bool - prompt "Enable FLV module" - help - Provides the ability to seek within FLV (Flash) files using time-based offsets. - default n - -config NGINX_STUB_STATUS - bool - prompt "Enable stub status module" - help - Enable the stub status module which gives some status from the server. - default n - -config NGINX_HTTP_CHARSET - bool - prompt "Enable HTTP charset module" - default y - -config NGINX_HTTP_GZIP - bool - prompt "Enable HTTP gzip module" - default y - -config NGINX_HTTP_SSI - bool - prompt "Enable HTTP ssi module" - default y - -config NGINX_HTTP_USERID - bool - prompt "Enable HTTP userid module" - default y - -config NGINX_HTTP_ACCESS - bool - prompt "Enable HTTP access module" - default y - -config NGINX_HTTP_AUTH_BASIC - bool - prompt "Enable HTTP auth basic" - default y - -config NGINX_HTTP_AUTH_REQUEST - bool - prompt "Enable HTTP auth request module" - default n - -config NGINX_HTTP_AUTOINDEX - bool - prompt "Enable HTTP autoindex module" - default y - -config NGINX_HTTP_GEO - bool - prompt "Enable HTTP geo module" - default y - -config NGINX_HTTP_MAP - bool - prompt "Enable HTTP map module" - default y - -config NGINX_HTTP_SPLIT_CLIENTS - bool - prompt "Enable HTTP split clients" - default y - -config NGINX_HTTP_REFERER - bool - prompt "Enable HTTP referer module" - default y - -config NGINX_HTTP_REWRITE - bool - prompt "Enable HTTP rewrite module" - select NGINX_PCRE - default y - -config NGINX_HTTP_PROXY - bool - prompt "Enable HTTP proxy module" - default y - -config NGINX_HTTP_FASTCGI - bool - prompt "Enable HTTP fastcgi module" - default y - -config NGINX_HTTP_UWSGI - bool - prompt "Enable HTTP uwsgi module" - default y - -config NGINX_HTTP_SCGI - bool - prompt "Enable HTTP scgi module" - default y - -config NGINX_HTTP_MEMCACHED - bool - prompt "Enable HTTP memcached module" - default y - -config NGINX_HTTP_LIMIT_CONN - bool - prompt "Enable HTTP limit conn" - default y - -config NGINX_HTTP_LIMIT_REQ - bool - prompt "Enable HTTP limit req" - default y - -config NGINX_HTTP_EMPTY_GIF - bool - prompt "Enable HTTP empty gif" - default y - -config NGINX_HTTP_BROWSER - bool - prompt "Enable HTTP browser module" - default y - -config NGINX_HTTP_UPSTREAM_HASH - bool - prompt "Enable HTTP hash module" - default y - -config NGINX_HTTP_UPSTREAM_IP_HASH - bool - prompt "Enable HTTP IP hash module" - default y - -config NGINX_HTTP_UPSTREAM_LEAST_CONN - bool - prompt "Enable HTTP least conn module" - default y - -config NGINX_HTTP_UPSTREAM_KEEPALIVE - bool - prompt "Enable HTTP keepalive module" - default y - -config NGINX_HTTP_CACHE - bool - prompt "Enable HTTP cache" - default y - -config NGINX_HTTP_V2 - bool - prompt "Enable HTTP_V2 module" - default n - -config NGINX_PCRE - bool - prompt "Enable PCRE library usage" - default y - -config NGINX_NAXSI - bool - prompt "Enable NAXSI module" - default y - -config NGINX_LUA - bool - prompt "Enable Lua module" - default n - -config NGINX_HTTP_REAL_IP - bool - prompt "Enable HTTP real ip module" - default n - -config NGINX_HTTP_SECURE_LINK - bool - prompt "Enable HTTP secure link module" - default n - -config NGINX_HTTP_SUB - bool - prompt "Enable HTTP sub module" - default n - -config NGINX_HEADERS_MORE - bool - prompt "Enable Headers_more module" - help - Set and clear input and output headers...more than "add"! - default y - -config NGINX_HTTP_BROTLI - bool - prompt "Enable Brotli compression module" - help - Add support for brotli compression module. - default n - -config NGINX_STREAM_CORE_MODULE - bool - prompt "Enable stream support" - help - Add support for NGINX request streaming. - default y - -config NGINX_RTMP_MODULE - bool - prompt "Enable RTMP module" - depends on NGINX_SSL - help - Add support for NGINX-based Media Streaming Server module. - DASH enhanced - https://github.com/ut0mt8/nginx-rtmp-module - default n - -config NGINX_TS_MODULE - bool - prompt "Enable TS module" - help - Add support for MPEG-TS Live Module module. - default n - -endmenu diff --git a/nginx/Config_ssl.in b/nginx/Config_ssl.in deleted file mode 100755 index 9325fba51..000000000 --- a/nginx/Config_ssl.in +++ /dev/null @@ -1,239 +0,0 @@ -# -# Copyright (C) 2010-2016 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - -menu "Configuration" - depends on PACKAGE_nginx-ssl - -config NGINX_DAV - bool - prompt "Enable WebDAV module" - help - Enable the HTTP and WebDAV methods PUT, DELETE, MKCOL, COPY and MOVE. - default n - -config NGINX_FLV - bool - prompt "Enable FLV module" - help - Provides the ability to seek within FLV (Flash) files using time-based offsets. - default n - -config NGINX_STUB_STATUS - bool - prompt "Enable stub status module" - help - Enable the stub status module which gives some status from the server. - default n - -config NGINX_HTTP_CHARSET - bool - prompt "Enable HTTP charset module" - default y - -config NGINX_HTTP_GZIP - bool - prompt "Enable HTTP gzip module" - default y - -config NGINX_HTTP_SSI - bool - prompt "Enable HTTP ssi module" - default y - -config NGINX_HTTP_USERID - bool - prompt "Enable HTTP userid module" - default y - -config NGINX_HTTP_ACCESS - bool - prompt "Enable HTTP access module" - default y - -config NGINX_HTTP_AUTH_BASIC - bool - prompt "Enable HTTP auth basic" - default y - -config NGINX_HTTP_AUTH_REQUEST - bool - prompt "Enable HTTP auth request module" - default n - -config NGINX_HTTP_AUTOINDEX - bool - prompt "Enable HTTP autoindex module" - default y - -config NGINX_HTTP_GEO - bool - prompt "Enable HTTP geo module" - default y - -config NGINX_HTTP_MAP - bool - prompt "Enable HTTP map module" - default y - -config NGINX_HTTP_SPLIT_CLIENTS - bool - prompt "Enable HTTP split clients" - default y - -config NGINX_HTTP_REFERER - bool - prompt "Enable HTTP referer module" - default y - -config NGINX_HTTP_REWRITE - bool - prompt "Enable HTTP rewrite module" - select NGINX_PCRE - default y - -config NGINX_HTTP_PROXY - bool - prompt "Enable HTTP proxy module" - default y - -config NGINX_HTTP_FASTCGI - bool - prompt "Enable HTTP fastcgi module" - default y - -config NGINX_HTTP_UWSGI - bool - prompt "Enable HTTP uwsgi module" - default y - -config NGINX_HTTP_SCGI - bool - prompt "Enable HTTP scgi module" - default y - -config NGINX_HTTP_MEMCACHED - bool - prompt "Enable HTTP memcached module" - default y - -config NGINX_HTTP_LIMIT_CONN - bool - prompt "Enable HTTP limit conn" - default y - -config NGINX_HTTP_LIMIT_REQ - bool - prompt "Enable HTTP limit req" - default y - -config NGINX_HTTP_EMPTY_GIF - bool - prompt "Enable HTTP empty gif" - default y - -config NGINX_HTTP_BROWSER - bool - prompt "Enable HTTP browser module" - default y - -config NGINX_HTTP_UPSTREAM_HASH - bool - prompt "Enable HTTP hash module" - default y - -config NGINX_HTTP_UPSTREAM_IP_HASH - bool - prompt "Enable HTTP IP hash module" - default y - -config NGINX_HTTP_UPSTREAM_LEAST_CONN - bool - prompt "Enable HTTP least conn module" - default y - -config NGINX_HTTP_UPSTREAM_KEEPALIVE - bool - prompt "Enable HTTP keepalive module" - default y - -config NGINX_HTTP_CACHE - bool - prompt "Enable HTTP cache" - default y - -config NGINX_HTTP_V2 - bool - prompt "Enable HTTP_V2 module" - default n - -config NGINX_PCRE - bool - prompt "Enable PCRE library usage" - default y - -config NGINX_NAXSI - bool - prompt "Enable NAXSI module" - default y - -config NGINX_LUA - bool - prompt "Enable Lua module" - default n - -config NGINX_HTTP_REAL_IP - bool - prompt "Enable HTTP real ip module" - default n - -config NGINX_HTTP_SECURE_LINK - bool - prompt "Enable HTTP secure link module" - default n - -config NGINX_HTTP_SUB - bool - prompt "Enable HTTP sub module" - default n - -config NGINX_HEADERS_MORE - bool - prompt "Enable Headers_more module" - help - Set and clear input and output headers...more than "add"! - default y - -config NGINX_HTTP_BROTLI - bool - prompt "Enable Brotli compression module" - help - Add support for brotli compression module. - default n - -config NGINX_STREAM_CORE_MODULE - bool - prompt "Enable stream support" - help - Add support for NGINX request streaming. - default n - -config NGINX_RTMP_MODULE - bool - prompt "Enable RTMP module" - help - Add support for NGINX-based Media Streaming Server module. - DASH enhanced - https://github.com/ut0mt8/nginx-rtmp-module - default n - -config NGINX_TS_MODULE - bool - prompt "Enable TS module" - help - Add support for MPEG-TS Live Module module. - default n - -endmenu diff --git a/nginx/Makefile b/nginx/Makefile deleted file mode 100755 index dc32fbb04..000000000 --- a/nginx/Makefile +++ /dev/null @@ -1,532 +0,0 @@ -# -# Copyright (C) 2012-2016 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - -include $(TOPDIR)/rules.mk - -PKG_NAME:=nginx -PKG_VERSION:=1.16.1 -PKG_RELEASE:=2 - -PKG_SOURCE:=nginx-$(PKG_VERSION).tar.gz -PKG_SOURCE_URL:=http://nginx.org/download/ -PKG_HASH:=f11c2a6dd1d3515736f0324857957db2de98be862461b5a542a3ac6188dbe32b - -PKG_MAINTAINER:=Thomas Heil \ - Ansuel Smith -PKG_LICENSE:=2-clause BSD-like license - -PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION) - -PKG_FIXUP:=autoreconf -PKG_BUILD_PARALLEL:=1 -PKG_INSTALL:=1 - -PKG_CONFIG_DEPENDS := \ - CONFIG_NGINX_SSL \ - CONFIG_NGINX_DAV \ - CONFIG_NGINX_FLV \ - CONFIG_NGINX_STUB_STATUS \ - CONFIG_NGINX_HTTP_CHARSET \ - CONFIG_NGINX_HTTP_GZIP \ - CONFIG_NGINX_HTTP_SSI \ - CONFIG_NGINX_HTTP_USERID \ - CONFIG_NGINX_HTTP_ACCESS \ - CONFIG_NGINX_HTTP_AUTH_BASIC \ - CONFIG_NGINX_HTTP_AUTH_REQUEST \ - CONFIG_NGINX_HTTP_AUTOINDEX \ - CONFIG_NGINX_HTTP_GEO \ - CONFIG_NGINX_HTTP_MAP \ - CONFIG_NGINX_HTTP_SPLIT_CLIENTS \ - CONFIG_NGINX_HTTP_REFERER \ - CONFIG_NGINX_HTTP_REWRITE \ - CONFIG_NGINX_HTTP_PROXY \ - CONFIG_NGINX_HTTP_FASTCGI \ - CONFIG_NGINX_HTTP_UWSGI \ - CONFIG_NGINX_HTTP_SCGI \ - CONFIG_NGINX_HTTP_MEMCACHED \ - CONFIG_NGINX_HTTP_LIMIT_CONN \ - CONFIG_NGINX_HTTP_LIMIT_REQ \ - CONFIG_NGINX_HTTP_EMPTY_GIF \ - CONFIG_NGINX_HTTP_BROWSER \ - CONFIG_NGINX_HTTP_UPSTREAM_HASH \ - CONFIG_NGINX_HTTP_UPSTREAM_IP_HASH \ - CONFIG_NGINX_HTTP_UPSTREAM_LEAST_CONN \ - CONFIG_NGINX_HTTP_UPSTREAM_KEEPALIVE \ - CONFIG_NGINX_HTTP_UPSTREAM_ZONE \ - CONFIG_NGINX_HTTP_CACHE \ - CONFIG_NGINX_HTTP_V2 \ - CONFIG_NGINX_PCRE \ - CONFIG_NGINX_NAXSI \ - CONFIG_NGINX_LUA \ - CONFIG_NGINX_HTTP_REAL_IP \ - CONFIG_NGINX_HTTP_SECURE_LINK \ - CONFIG_NGINX_HTTP_BROTLI \ - CONFIG_NGINX_HEADERS_MORE \ - CONFIG_NGINX_STREAM_CORE_MODULE \ - CONFIG_NGINX_RTMP_MODULE \ - CONFIG_NGINX_TS_MODULE \ - -include $(INCLUDE_DIR)/package.mk - -define Package/nginx/default - SECTION:=net - CATEGORY:=Network - SUBMENU:=Web Servers/Proxies - TITLE:=Nginx web server - URL:=http://nginx.org/ - DEPENDS:=+NGINX_PCRE:libpcre +(NGINX_SSL||NGINX_HTTP_CACHE||NGINX_HTTP_AUTH_BASIC):libopenssl \ - +NGINX_HTTP_GZIP:zlib +NGINX_LUA:liblua +libpthread +NGINX_DAV:libexpat -endef - -define Package/nginx/description - nginx is an HTTP and reverse proxy server, as well as a mail proxy server, \ - written by Igor Sysoev. (Some module require SSL module enable to show up in \ - config menu) -endef - -define Package/nginx - $(Package/nginx/default) - VARIANT:=no-ssl -endef - -define Package/nginx-ssl - $(Package/nginx/default) - TITLE += with SSL support - DEPENDS +=+libopenssl - VARIANT:=ssl - PROVIDES:=nginx -endef - -Package/nginx-ssl/description = $(Package/nginx/description) \ - This varian is compiled with SSL support enabled. To enable additional module \ - select them in the nginx default configuration menu. - -define Package/nginx-all-module - $(Package/nginx/default) - TITLE += with ALL module selected - DEPENDS:=+libpcre +libopenssl +zlib +liblua +libpthread +libexpat - VARIANT:=all-module - PROVIDES:=nginx -endef - -Package/nginx-all-module/description = $(Package/nginx/description) \ - This varian is compiled with ALL module selected. - -define Package/nginx/config - source "$(SOURCE)/Config.in" -endef - -define Package/nginx-ssl/config - source "$(SOURCE)/Config_ssl.in" -endef - -config_files=nginx.conf mime.types - -define Package/nginx/conffiles -/etc/nginx/ -endef - -Package/nginx-ssl/conffiles = $(Package/nginx/conffiles) -Package/nginx-all-module/conffiles = $(Package/nginx/conffiles) - - -ADDITIONAL_MODULES:= - -ifneq ($(BUILD_VARIANT),all-module) - ifneq ($(CONFIG_NGINX_HTTP_CACHE),y) - ADDITIONAL_MODULES += --without-http-cache - endif - ifneq ($(CONFIG_NGINX_PCRE),y) - ADDITIONAL_MODULES += --without-pcre - endif - ifneq ($(CONFIG_NGINX_HTTP_CHARSET),y) - ADDITIONAL_MODULES += --without-http_charset_module - else - config_files += koi-utf koi-win win-utf - endif - ifneq ($(CONFIG_NGINX_HTTP_GZIP),y) - ADDITIONAL_MODULES += --without-http_gzip_module - endif - ifneq ($(CONFIG_NGINX_HTTP_SSI),y) - ADDITIONAL_MODULES += --without-http_ssi_module - endif - ifneq ($(CONFIG_NGINX_HTTP_USERID),y) - ADDITIONAL_MODULES += --without-http_userid_module - endif - ifneq ($(CONFIG_NGINX_HTTP_ACCESS),y) - ADDITIONAL_MODULES += --without-http_access_module - endif - ifneq ($(CONFIG_NGINX_HTTP_AUTH_BASIC),y) - ADDITIONAL_MODULES += --without-http_auth_basic_module - endif - ifneq ($(CONFIG_NGINX_HTTP_AUTOINDEX),y) - ADDITIONAL_MODULES += --without-http_autoindex_module - endif - ifneq ($(CONFIG_NGINX_HTTP_GEO),y) - ADDITIONAL_MODULES += --without-http_geo_module - endif - ifneq ($(CONFIG_NGINX_HTTP_MAP),y) - ADDITIONAL_MODULES += --without-http_map_module - endif - ifneq ($(CONFIG_NGINX_HTTP_SPLIT_CLIENTS),y) - ADDITIONAL_MODULES += --without-http_split_clients_module - endif - ifneq ($(CONFIG_NGINX_HTTP_REFERER),y) - ADDITIONAL_MODULES += --without-http_referer_module - endif - ifneq ($(CONFIG_NGINX_HTTP_REWRITE),y) - ADDITIONAL_MODULES += --without-http_rewrite_module - endif - ifneq ($(CONFIG_NGINX_HTTP_PROXY),y) - ADDITIONAL_MODULES += --without-http_proxy_module - endif - ifneq ($(CONFIG_NGINX_HTTP_FASTCGI),y) - ADDITIONAL_MODULES += --without-http_fastcgi_module - else - config_files += fastcgi_params - endif - ifneq ($(CONFIG_NGINX_HTTP_UWSGI),y) - ADDITIONAL_MODULES += --without-http_uwsgi_module - endif - ifneq ($(CONFIG_NGINX_HTTP_SCGI),y) - ADDITIONAL_MODULES += --without-http_scgi_module - endif - ifneq ($(CONFIG_NGINX_HTTP_MEMCACHED),y) - ADDITIONAL_MODULES += --without-http_memcached_module - endif - ifneq ($(CONFIG_NGINX_HTTP_LIMIT_CONN),y) - ADDITIONAL_MODULES += --without-http_limit_conn_module - endif - ifneq ($(CONFIG_NGINX_HTTP_LIMIT_REQ),y) - ADDITIONAL_MODULES += --without-http_limit_req_module - endif - ifneq ($(CONFIG_NGINX_HTTP_EMPTY_GIF),y) - ADDITIONAL_MODULES += --without-http_empty_gif_module - endif - ifneq ($(CONFIG_NGINX_HTTP_BROWSER),y) - ADDITIONAL_MODULES += --without-http_browser_module - endif - ifneq ($(CONFIG_NGINX_HTTP_UPSTREAM_HASH),y) - ADDITIONAL_MODULES += --without-http_upstream_hash_module - endif - ifneq ($(CONFIG_NGINX_HTTP_UPSTREAM_IP_HASH),y) - ADDITIONAL_MODULES += --without-http_upstream_ip_hash_module - endif - ifneq ($(CONFIG_NGINX_HTTP_UPSTREAM_LEAST_CONN),y) - ADDITIONAL_MODULES += --without-http_upstream_least_conn_module - endif - ifneq ($(CONFIG_NGINX_HTTP_UPSTREAM_KEEPALIVE),y) - ADDITIONAL_MODULES += --without-http_upstream_keepalive_module - endif - - ifeq ($(BUILD_VARIANT),ssl) - ifneq ($(CONFIG_NGINX_SSL),y) - ADDITIONAL_MODULES += --with-http_ssl_module - endif - endif - - ifeq ($(CONFIG_NGINX_SSL),y) - ADDITIONAL_MODULES += --with-http_ssl_module - endif - ifeq ($(CONFIG_NGINX_NAXSI),y) - ADDITIONAL_MODULES += --add-module=$(PKG_BUILD_DIR)/nginx-naxsi/naxsi_src - endif - ifeq ($(CONFIG_NGINX_LUA),y) - ADDITIONAL_MODULES += --add-module=$(PKG_BUILD_DIR)/lua-nginx - endif - ifeq ($(CONFIG_IPV6),y) - ADDITIONAL_MODULES += --with-ipv6 - endif - ifeq ($(CONFIG_NGINX_STUB_STATUS),y) - ADDITIONAL_MODULES += --with-http_stub_status_module - endif - ifeq ($(CONFIG_NGINX_FLV),y) - ADDITIONAL_MODULES += --with-http_flv_module - endif - ifeq ($(CONFIG_NGINX_DAV),y) - ADDITIONAL_MODULES += --with-http_dav_module --add-module=$(PKG_BUILD_DIR)/nginx-dav-ext-module - endif - ifeq ($(CONFIG_NGINX_HTTP_AUTH_REQUEST),y) - ADDITIONAL_MODULES += --with-http_auth_request_module - endif - ifeq ($(CONFIG_NGINX_HTTP_V2),y) - ADDITIONAL_MODULES += --with-http_v2_module - endif - ifeq ($(CONFIG_NGINX_HTTP_REAL_IP),y) - ADDITIONAL_MODULES += --with-http_realip_module - endif - ifeq ($(CONFIG_NGINX_HTTP_SECURE_LINK),y) - ADDITIONAL_MODULES += --with-http_secure_link_module - endif - ifeq ($(CONFIG_NGINX_HTTP_SUB),y) - ADDITIONAL_MODULES += --with-http_sub_module - endif - ifeq ($(CONFIG_NGINX_STREAM_CORE_MODULE),y) - ADDITIONAL_MODULES += --with-stream - endif - ifeq ($(CONFIG_NGINX_HEADERS_MORE),y) - ADDITIONAL_MODULES += --add-module=$(PKG_BUILD_DIR)/nginx-headers-more - endif - ifeq ($(CONFIG_NGINX_HTTP_BROTLI),y) - ADDITIONAL_MODULES += --add-module=$(PKG_BUILD_DIR)/nginx-brotli - endif - ifeq ($(CONFIG_NGINX_RTMP_MODULE),y) - ADDITIONAL_MODULES += --add-module=$(PKG_BUILD_DIR)/nginx-rtmp - endif - ifeq ($(CONFIG_NGINX_TS_MODULE),y) - ADDITIONAL_MODULES += --add-module=$(PKG_BUILD_DIR)/nginx-ts - endif -else - CONFIG_NGINX_HEADERS_MORE:=y - CONFIG_NGINX_HTTP_BROTLI:=y - CONFIG_NGINX_RTMP_MODULE:=y - CONFIG_NGINX_TS_MODULE:=y - CONFIG_NGINX_NAXSI:=y - CONFIG_NGINX_LUA:=y - CONFIG_NGINX_DAV:=y - ADDITIONAL_MODULES += --with-http_ssl_module --add-module=$(PKG_BUILD_DIR)/nginx-naxsi/naxsi_src \ - --add-module=$(PKG_BUILD_DIR)/lua-nginx --with-ipv6 --with-http_stub_status_module --with-http_flv_module \ - --with-http_dav_module --add-module=$(PKG_BUILD_DIR)/nginx-dav-ext-module \ - --with-http_auth_request_module --with-http_v2_module --with-http_realip_module \ - --with-http_secure_link_module --with-http_sub_module --add-module=$(PKG_BUILD_DIR)/nginx-headers-more \ - --with-stream \ - --add-module=$(PKG_BUILD_DIR)/nginx-brotli --add-module=$(PKG_BUILD_DIR)/nginx-rtmp \ - --add-module=$(PKG_BUILD_DIR)/nginx-ts - config_files += koi-utf koi-win win-utf fastcgi_params -endif - -define Package/nginx-mod-luci/default - TITLE:=Nginx on LuCI - SECTION:=net - CATEGORY:=Network - SUBMENU:=Web Servers/Proxies - TITLE:=Support file for Nginx - URL:=http://nginx.org/ - DEPENDS:=+uwsgi-cgi +uwsgi-cgi-luci-support -endef - -define Package/nginx-mod-luci - $(Package/nginx-mod-luci/default) - DEPENDS += +nginx -endef - -define Package/nginx-mod-luci/description - Support file for LuCI in nginx. Include custom nginx configuration, autostart script for uwsgi. -endef - -define Package/nginx-mod-luci-ssl - $(Package/nginx-mod-luci/default) - TITLE += with HTTPS support - DEPENDS += +nginx-ssl -endef - -Package/nginx-mod-luci-ssl/description = $(define Package/nginx-mod-luci/description) \ - This also include redirect from http to https and cert autogeneration. - -TARGET_CFLAGS += -fvisibility=hidden -ffunction-sections -fdata-sections -DNGX_LUA_NO_BY_LUA_BLOCK -TARGET_LDFLAGS += -Wl,--gc-sections - -ifeq ($(CONFIG_NGINX_LUA),y) - CONFIGURE_VARS += LUA_INC=$(STAGING_DIR)/usr/include \ - LUA_LIB=$(STAGING_DIR)/usr/lib -endif - -CONFIGURE_ARGS += \ - --crossbuild=Linux::$(ARCH) \ - --prefix=/usr \ - --conf-path=/etc/nginx/nginx.conf \ - $(ADDITIONAL_MODULES) \ - --error-log-path=/var/log/nginx/error.log \ - --pid-path=/var/run/nginx.pid \ - --lock-path=/var/lock/nginx.lock \ - --http-log-path=/var/log/nginx/access.log \ - --http-client-body-temp-path=/var/lib/nginx/body \ - --http-proxy-temp-path=/var/lib/nginx/proxy \ - --http-fastcgi-temp-path=/var/lib/nginx/fastcgi \ - --with-cc="$(TARGET_CC)" \ - --with-cc-opt="$(TARGET_CPPFLAGS) $(TARGET_CFLAGS)" \ - --with-ld-opt="$(TARGET_LDFLAGS)" \ - --without-http_upstream_zone_module - -define Package/nginx-mod-luci/install - $(INSTALL_DIR) $(1)/etc/nginx - $(INSTALL_BIN) ./files-luci-support/luci_uwsgi.conf $(1)/etc/nginx/luci_uwsgi.conf - $(INSTALL_BIN) ./files-luci-support/luci_nginx.conf $(1)/etc/nginx/luci_nginx.conf - $(INSTALL_DIR) $(1)/etc/uci-defaults - $(INSTALL_BIN) ./files-luci-support/60_nginx-luci-support $(1)/etc/uci-defaults/60_nginx-luci-support -endef - -define Package/nginx-mod-luci-ssl/install - $(Package/nginx-mod-luci/install) - $(INSTALL_DIR) $(1)/etc/nginx - $(INSTALL_BIN) ./files-luci-support/luci_nginx_ssl.conf $(1)/etc/nginx/luci_nginx_ssl.conf - $(INSTALL_DIR) $(1)/etc/uci-defaults - $(INSTALL_BIN) ./files-luci-support/70_nginx-luci-support-ssl $(1)/etc/uci-defaults/70_nginx-luci-support-ssl -endef - -define Package/nginx/install - $(INSTALL_DIR) $(1)/usr/sbin - $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/nginx $(1)/usr/sbin/ - $(INSTALL_DIR) $(1)/etc/nginx - $(INSTALL_DATA) $(addprefix $(PKG_INSTALL_DIR)/etc/nginx/,$(config_files)) $(1)/etc/nginx/ - $(INSTALL_DIR) $(1)/etc/init.d - $(INSTALL_BIN) ./files/nginx.init $(1)/etc/init.d/nginx -ifeq ($(CONFIG_NGINX_NAXSI),y) - $(INSTALL_DIR) $(1)/etc/nginx - $(INSTALL_BIN) $(PKG_BUILD_DIR)/nginx-naxsi/naxsi_config/naxsi_core.rules $(1)/etc/nginx - chmod 0640 $(1)/etc/nginx/naxsi_core.rules -endif - $(if $(CONFIG_NGINX_NAXSI),$($(INSTALL_BIN) $(PKG_BUILD_DIR)/nginx-naxsi/naxsi_config/naxsi_core.rules $(1)/etc/nginx)) - $(if $(CONFIG_NGINX_NAXSI),$(chmod 0640 $(1)/etc/nginx/naxsi_core.rules)) -endef - -Package/nginx-ssl/install = $(Package/nginx/install) -Package/nginx-all-module/install = $(Package/nginx/install) - -define Build/Prepare - $(Build/Prepare/Default) - $(Prepare/nginx-naxsi) - $(Prepare/lua-nginx) - $(Prepare/nginx-brotli) - $(Prepare/nginx-headers-more) - $(Prepare/nginx-rtmp) - $(Prepare/nginx-ts) - $(Prepare/nginx-dav-ext-module) -endef - - -ifeq ($(CONFIG_NGINX_HEADERS_MORE),y) - define Download/nginx-headers-more - VERSION:=a9f7c7e86cc7441d04e2f11f01c2e3a9c4b0301d - SUBDIR:=nginx-headers-more - FILE:=headers-more-nginx-module-$(PKG_VERSION)-$$(VERSION).tar.gz - URL:=https://github.com/openresty/headers-more-nginx-module.git - MIRROR_HASH:=432609015719aaa7241e5166c7cda427acbe004f725887f78ef629d51bd9cb3f - PROTO:=git - endef - $(eval $(call Download,nginx-headers-more)) - - define Prepare/nginx-headers-more - $(eval $(Download/nginx-headers-more)) - gzip -dc $(DL_DIR)/$(FILE) | tar -C $(PKG_BUILD_DIR) $(TAR_OPTIONS) - endef -endif - - -ifeq ($(CONFIG_NGINX_HTTP_BROTLI),y) - define Download/nginx-brotli - VERSION:=e26248ee361c04e25f581b92b85d95681bdffb39 - SUBDIR:=nginx-brotli - FILE:=ngx-brotli-module-$(PKG_VERSION)-$$(VERSION).tar.gz - URL:=https://github.com/eustas/ngx_brotli.git - MIRROR_HASH:=76b891ba49f82f0cfbc9cba875646e26ee986b522373e0aa2698a9923a4adcdb - PROTO:=git - endef - $(eval $(call Download,nginx-brotli)) - - define Prepare/nginx-brotli - $(eval $(Download/nginx-brotli)) - gzip -dc $(DL_DIR)/$(FILE) | tar -C $(PKG_BUILD_DIR) $(TAR_OPTIONS) - endef -endif - - -ifeq ($(CONFIG_NGINX_RTMP_MODULE),y) - define Download/nginx-rtmp - VERSION:=f0ea62342a4eca504b311cd5df910d026c3ea4cf - SUBDIR:=nginx-rtmp - FILE:=ngx-rtmp-module-$(PKG_VERSION)-$$(VERSION).tar.gz - URL:=https://github.com/ut0mt8/nginx-rtmp-module.git - MIRROR_HASH:=9ba7625718d21f658c4878729271832a07bd989165f1d1c720b3a9b54cf738cc - PROTO:=git - endef - $(eval $(call Download,nginx-rtmp)) - - define Prepare/nginx-rtmp - $(eval $(Download/nginx-rtmp)) - gzip -dc $(DL_DIR)/$(FILE) | tar -C $(PKG_BUILD_DIR) $(TAR_OPTIONS) - endef -endif - - -ifeq ($(CONFIG_NGINX_TS_MODULE),y) - define Download/nginx-ts - VERSION:=ef2f874d95cc75747eb625a292524a702aefb0fd - SUBDIR:=nginx-ts - FILE:=ngx-ts-module-$(PKG_VERSION)-$$(VERSION).tar.gz - URL:=https://github.com/arut/nginx-ts-module.git - MIRROR_HASH:=31ecc9968b928886b54884138eafe2fa747648bca5094d4c3132e8ae9509d1d3 - PROTO:=git - endef - $(eval $(call Download,nginx-ts)) - - define Prepare/nginx-ts - $(eval $(Download/nginx-ts)) - gzip -dc $(DL_DIR)/$(FILE) | tar -C $(PKG_BUILD_DIR) $(TAR_OPTIONS) - endef -endif - - -ifeq ($(CONFIG_NGINX_NAXSI),y) - define Download/nginx-naxsi - VERSION:=951123ad456bdf5ac94e8d8819342fe3d49bc002 - SUBDIR:=nginx-naxsi - FILE:=nginx-naxsi-module-$(PKG_VERSION)-$$(VERSION).tar.gz - URL:=https://github.com/nbs-system/naxsi.git - MIRROR_HASH:=7ab791f2ff38096f48013141bbfe20ba213d5e04dcac08ca82e0cac07d5c30f0 - PROTO:=git - endef - $(eval $(call Download,nginx-naxsi)) - - define Prepare/nginx-naxsi - $(eval $(Download/nginx-naxsi)) - gzip -dc $(DL_DIR)/$(FILE) | tar -C $(PKG_BUILD_DIR) $(TAR_OPTIONS) - endef -endif - - -ifeq ($(CONFIG_NGINX_LUA),y) - define Download/lua-nginx - VERSION:=e94f2e5d64daa45ff396e262d8dab8e56f5f10e0 - SUBDIR:=lua-nginx - FILE:=lua-nginx-module-$(PKG_VERSION)-$$(VERSION).tar.gz - URL:=https://github.com/openresty/lua-nginx-module.git - MIRROR_HASH:=ae439f9a8b3c34d7240735b844db72ee721af4791bbaff5692bca20e6785f541 - PROTO:=git - endef - $(eval $(call Download,lua-nginx)) - - define Prepare/lua-nginx - $(eval $(Download/lua-nginx)) - gzip -dc $(DL_DIR)/$(FILE) | tar -C $(PKG_BUILD_DIR) $(TAR_OPTIONS) - $(call PatchDir,$(PKG_BUILD_DIR),./patches-lua-nginx) - endef -endif - - -ifeq ($(CONFIG_NGINX_DAV),y) - define Download/nginx-dav-ext-module - VERSION:=430fd774fe838a04f1a5defbf1dd571d42300cf9 - SUBDIR:=nginx-dav-ext-module - FILE:=nginx-dav-ext-module-$(PKG_VERSION)-$$(VERSION).tar.gz - URL:=https://github.com/arut/nginx-dav-ext-module.git - MIRROR_HASH:=0566053a8756423ecab455fd9d218cec1e017598fcbb3d6415a06f816851611e - PROTO:=git - endef - $(eval $(call Download,nginx-dav-ext-module)) - - define Prepare/nginx-dav-ext-module - $(eval $(Download/nginx-dav-ext-module)) - gzip -dc $(DL_DIR)/$(FILE) | tar -C $(PKG_BUILD_DIR) $(TAR_OPTIONS) - endef -endif - -$(eval $(call BuildPackage,nginx)) -$(eval $(call BuildPackage,nginx-ssl)) -$(eval $(call BuildPackage,nginx-all-module)) -#$(eval $(call BuildPackage,nginx-mod-luci)) -#$(eval $(call BuildPackage,nginx-mod-luci-ssl)) diff --git a/nginx/files-luci-support/60_nginx-luci-support b/nginx/files-luci-support/60_nginx-luci-support deleted file mode 100755 index dd076d260..000000000 --- a/nginx/files-luci-support/60_nginx-luci-support +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/sh - -if [ -f "/etc/nginx/luci_nginx.conf" ] && [ -f "/etc/nginx/nginx.conf" ]; then - if [ ! "$(cat '/etc/nginx/nginx.conf' | grep 'luci_uwsgi.conf')" ]; then - mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf_old - mv /etc/nginx/luci_nginx.conf /etc/nginx/nginx.conf - core_number=$(grep -c ^processor /proc/cpuinfo) - sed -i "3s/.*/worker_processes "$core_number";/" /etc/nginx/nginx.conf - if [ -n "$(pgrep uhttpd)" ]; then - /etc/init.d/uhttpd stop - /etc/init.d/uhttpd disable - fi - if [ -n "$(pgrep nginx)" ]; then - /etc/init.d/nginx restart - else - /etc/init.d/nginx start - fi - if [ -n "$(pgrep uwsgi)" ]; then - /etc/init.d/uwsgi restart - else - /etc/init.d/uwsgi start - fi - else - rm /etc/nginx/luci_nginx.conf - fi -fi - -exit 0 diff --git a/nginx/files-luci-support/70_nginx-luci-support-ssl b/nginx/files-luci-support/70_nginx-luci-support-ssl deleted file mode 100755 index 76ce3a819..000000000 --- a/nginx/files-luci-support/70_nginx-luci-support-ssl +++ /dev/null @@ -1,48 +0,0 @@ -#!/bin/sh - - -if [ -f "/etc/nginx/luci_nginx_ssl.conf" ] && [ -f "/etc/nginx/nginx.conf" ]; then - if [ ! "$(cat '/etc/nginx/nginx.conf' | grep 'return 301 https://$host$request_uri;')" ]; then - if [ -f "/etc/nginx/nginx.conf_old" ]; then - rm /etc/nginx/nginx.conf - else - mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf_old - fi - mv /etc/nginx/luci_nginx_ssl.conf /etc/nginx/nginx.conf - core_number=$(grep -c ^processor /proc/cpuinfo) - sed -i "3s/.*/worker_processes "$core_number";/" /etc/nginx/nginx.conf - if [ -n "$(pgrep nginx)" ]; then - /etc/init.d/nginx restart - else - /etc/init.d/nginx start - fi - else - rm /etc/nginx/luci_nginx_ssl.conf - fi -fi - - -if [ ! -f "/etc/nginx/nginx.key" ]; then - - NGINX_KEY=/etc/nginx/nginx.key - NGINX_CER=/etc/nginx/nginx.cer - OPENSSL_BIN=/usr/bin/openssl - PX5G_BIN=/usr/sbin/px5g - - # Prefer px5g for certificate generation (existence evaluated last) - GENKEY_CMD="" - UNIQUEID=$(dd if=/dev/urandom bs=1 count=4 | hexdump -e '1/1 "%02x"') - [ -x "$OPENSSL_BIN" ] && GENKEY_CMD="$OPENSSL_BIN req -x509 -nodes" - [ -x "$PX5G_BIN" ] && GENKEY_CMD="$PX5G_BIN selfsigned" - [ -n "$GENKEY_CMD" ] && { - $GENKEY_CMD \ - -days 730 -newkey rsa:2048 -keyout "${NGINX_KEY}.new" -out "${NGINX_CER}.new" \ - -subj /C="ZZ"/ST="Somewhere"/L="Unknown"/O="OpenWrt""$UNIQUEID"/CN="OpenWrt" - sync - mv "${NGINX_KEY}.new" "${NGINX_KEY}" - mv "${NGINX_CER}.new" "${NGINX_CER}" - } -fi - - -exit 0 diff --git a/nginx/files-luci-support/luci_nginx.conf b/nginx/files-luci-support/luci_nginx.conf deleted file mode 100755 index 31af664a2..000000000 --- a/nginx/files-luci-support/luci_nginx.conf +++ /dev/null @@ -1,51 +0,0 @@ - -user nobody nogroup; -worker_processes 1; - -#error_log logs/error.log; -#error_log logs/error.log notice; -#error_log logs/error.log info; - -pid /var/run/nginx.pid; - - -events { - worker_connections 1024; -} - - -http { - include mime.types; - default_type application/octet-stream; - - sendfile on; - keepalive_timeout 0; - - client_body_buffer_size 10K; - client_header_buffer_size 1k; - client_max_body_size 1G; - large_client_header_buffers 2 1k; - - gzip on; - gzip_http_version 1.1; - gzip_vary on; - gzip_comp_level 1; - gzip_proxied any; - - root /www; - - server { - listen 80 default_server; - listen [::]:80 default_server; - server_name localhost; - - location ~* .(jpg|jpeg|png|gif|ico|css|js)$ { - expires 365d; - } - - include luci_uwsgi.conf; - - } - - include /etc/nginx/conf.d/*.conf; -} diff --git a/nginx/files-luci-support/luci_nginx_ssl.conf b/nginx/files-luci-support/luci_nginx_ssl.conf deleted file mode 100755 index 318453b54..000000000 --- a/nginx/files-luci-support/luci_nginx_ssl.conf +++ /dev/null @@ -1,66 +0,0 @@ - -user root; -worker_processes 1; - -#error_log logs/error.log; -#error_log logs/error.log notice; -#error_log logs/error.log info; - -pid /var/run/nginx.pid; - - -events { - worker_connections 1024; -} - - -http { - include mime.types; - default_type application/octet-stream; - - sendfile on; - keepalive_timeout 0; - - client_body_buffer_size 10K; - client_header_buffer_size 1k; - client_max_body_size 1G; - large_client_header_buffers 2 1k; - - gzip on; - gzip_http_version 1.1; - gzip_vary on; - gzip_comp_level 1; - gzip_proxied any; - - root /www; - - server { - listen 80 default_server; - listen [::]:80 default_server; - server_name _; - return 301 https://$host$request_uri; - } - - server { - listen 443 ssl default_server; - listen [::]:443 ssl default_server; - server_name localhost; - - ssl_protocols TLSv1 TLSv1.1 TLSv1.2; - ssl_prefer_server_ciphers on; - ssl_ciphers "EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH:DHE+AESGCM:DHE:!RSA!aNULL:!eNULL:!LOW:!RC4:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:!CAMELLIA:!SEED"; - ssl_session_tickets off; - - ssl_certificate /etc/nginx/nginx.cer; - ssl_certificate_key /etc/nginx/nginx.key; - - location ~* .(jpg|jpeg|png|gif|ico|css|js)$ { - expires 365d; - } - - include luci_uwsgi.conf; - - } - - include /etc/nginx/conf.d/*.conf; -} diff --git a/nginx/files-luci-support/luci_uwsgi.conf b/nginx/files-luci-support/luci_uwsgi.conf deleted file mode 100755 index 6211db74a..000000000 --- a/nginx/files-luci-support/luci_uwsgi.conf +++ /dev/null @@ -1,20 +0,0 @@ -location /cgi-bin/luci { - index index.html; - uwsgi_param QUERY_STRING $query_string; - uwsgi_param REQUEST_METHOD $request_method; - uwsgi_param CONTENT_TYPE $content_type; - uwsgi_param CONTENT_LENGTH $content_length if_not_empty; - uwsgi_param REQUEST_URI $request_uri; - uwsgi_param PATH_INFO $document_uri; - uwsgi_param SERVER_PROTOCOL $server_protocol; - uwsgi_param REMOTE_ADDR $remote_addr; - uwsgi_param REMOTE_PORT $remote_port; - uwsgi_param SERVER_ADDR $server_addr; - uwsgi_param SERVER_PORT $server_port; - uwsgi_param SERVER_NAME $server_name; - uwsgi_modifier1 9; - uwsgi_pass unix:////var/run/uwsgi.sock; -} - -location /luci-static { -} diff --git a/nginx/files/nginx.init b/nginx/files/nginx.init deleted file mode 100755 index 40d389719..000000000 --- a/nginx/files/nginx.init +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh /etc/rc.common -# Copyright (C) 2015 OpenWrt.org - -START=80 - -USE_PROCD=1 - -start_service() { - [ -d /var/log/nginx ] || mkdir -p /var/log/nginx - [ -d /var/lib/nginx ] || mkdir -p /var/lib/nginx - - procd_open_instance - procd_set_param command /usr/sbin/nginx -c /etc/nginx/nginx.conf -g 'daemon off;' - procd_set_param file /etc/nginx/nginx.conf - procd_set_param respawn - procd_close_instance -} diff --git a/nginx/patches-lua-nginx/100-no_by_lua_block.patch b/nginx/patches-lua-nginx/100-no_by_lua_block.patch deleted file mode 100755 index 968e12d58..000000000 --- a/nginx/patches-lua-nginx/100-no_by_lua_block.patch +++ /dev/null @@ -1,195 +0,0 @@ ---- a/lua-nginx/src/ngx_http_lua_module.c -+++ b/lua-nginx/src/ngx_http_lua_module.c -@@ -165,14 +165,14 @@ static ngx_command_t ngx_http_lua_cmds[] - NGX_HTTP_LOC_CONF_OFFSET, - offsetof(ngx_http_lua_loc_conf_t, log_socket_errors), - NULL }, -- -+#ifndef NGX_LUA_NO_BY_LUA_BLOCK - { ngx_string("init_by_lua_block"), - NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS, - ngx_http_lua_init_by_lua_block, - NGX_HTTP_MAIN_CONF_OFFSET, - 0, - (void *) ngx_http_lua_init_by_inline }, -- -+#endif - { ngx_string("init_by_lua"), - NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1, - ngx_http_lua_init_by_lua, -@@ -186,14 +186,14 @@ static ngx_command_t ngx_http_lua_cmds[] - NGX_HTTP_MAIN_CONF_OFFSET, - 0, - (void *) ngx_http_lua_init_by_file }, -- -+#ifndef NGX_LUA_NO_BY_LUA_BLOCK - { ngx_string("init_worker_by_lua_block"), - NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS, - ngx_http_lua_init_worker_by_lua_block, - NGX_HTTP_MAIN_CONF_OFFSET, - 0, - (void *) ngx_http_lua_init_worker_by_inline }, -- -+#endif - { ngx_string("init_worker_by_lua"), - NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1, - ngx_http_lua_init_worker_by_lua, -@@ -209,6 +209,7 @@ static ngx_command_t ngx_http_lua_cmds[] - (void *) ngx_http_lua_init_worker_by_file }, - - #if defined(NDK) && NDK -+#ifndef NGX_LUA_NO_BY_LUA_BLOCK - /* set_by_lua $res { inline Lua code } [$arg1 [$arg2 [...]]] */ - { ngx_string("set_by_lua_block"), - NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF -@@ -217,7 +218,7 @@ static ngx_command_t ngx_http_lua_cmds[] - NGX_HTTP_LOC_CONF_OFFSET, - 0, - (void *) ngx_http_lua_filter_set_by_lua_inline }, -- -+#endif - /* set_by_lua $res [$arg1 [$arg2 [...]]] */ - { ngx_string("set_by_lua"), - NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF -@@ -245,7 +246,7 @@ static ngx_command_t ngx_http_lua_cmds[] - NGX_HTTP_LOC_CONF_OFFSET, - 0, - (void *) ngx_http_lua_rewrite_handler_inline }, -- -+#ifndef NGX_LUA_NO_BY_LUA_BLOCK - /* rewrite_by_lua_block { } */ - { ngx_string("rewrite_by_lua_block"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF -@@ -254,7 +255,7 @@ static ngx_command_t ngx_http_lua_cmds[] - NGX_HTTP_LOC_CONF_OFFSET, - 0, - (void *) ngx_http_lua_rewrite_handler_inline }, -- -+#endif - /* access_by_lua "" */ - { ngx_string("access_by_lua"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF -@@ -263,7 +264,7 @@ static ngx_command_t ngx_http_lua_cmds[] - NGX_HTTP_LOC_CONF_OFFSET, - 0, - (void *) ngx_http_lua_access_handler_inline }, -- -+#ifndef NGX_LUA_NO_BY_LUA_BLOCK - /* access_by_lua_block { } */ - { ngx_string("access_by_lua_block"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF -@@ -272,7 +273,7 @@ static ngx_command_t ngx_http_lua_cmds[] - NGX_HTTP_LOC_CONF_OFFSET, - 0, - (void *) ngx_http_lua_access_handler_inline }, -- -+#endif - /* content_by_lua "" */ - { ngx_string("content_by_lua"), - NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_TAKE1, -@@ -280,7 +281,7 @@ static ngx_command_t ngx_http_lua_cmds[] - NGX_HTTP_LOC_CONF_OFFSET, - 0, - (void *) ngx_http_lua_content_handler_inline }, -- -+#ifndef NGX_LUA_NO_BY_LUA_BLOCK - /* content_by_lua_block { } */ - { ngx_string("content_by_lua_block"), - NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS, -@@ -288,7 +289,7 @@ static ngx_command_t ngx_http_lua_cmds[] - NGX_HTTP_LOC_CONF_OFFSET, - 0, - (void *) ngx_http_lua_content_handler_inline }, -- -+#endif - /* log_by_lua */ - { ngx_string("log_by_lua"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF -@@ -297,7 +298,7 @@ static ngx_command_t ngx_http_lua_cmds[] - NGX_HTTP_LOC_CONF_OFFSET, - 0, - (void *) ngx_http_lua_log_handler_inline }, -- -+#ifndef NGX_LUA_NO_BY_LUA_BLOCK - /* log_by_lua_block { } */ - { ngx_string("log_by_lua_block"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF -@@ -306,7 +307,7 @@ static ngx_command_t ngx_http_lua_cmds[] - NGX_HTTP_LOC_CONF_OFFSET, - 0, - (void *) ngx_http_lua_log_handler_inline }, -- -+#endif - { ngx_string("rewrite_by_lua_file"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF - |NGX_CONF_TAKE1, -@@ -361,7 +362,7 @@ static ngx_command_t ngx_http_lua_cmds[] - NGX_HTTP_LOC_CONF_OFFSET, - 0, - (void *) ngx_http_lua_header_filter_inline }, -- -+#ifndef NGX_LUA_NO_BY_LUA_BLOCK - /* header_filter_by_lua_block { } */ - { ngx_string("header_filter_by_lua_block"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF -@@ -370,7 +371,7 @@ static ngx_command_t ngx_http_lua_cmds[] - NGX_HTTP_LOC_CONF_OFFSET, - 0, - (void *) ngx_http_lua_header_filter_inline }, -- -+#endif - { ngx_string("header_filter_by_lua_file"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF - |NGX_CONF_TAKE1, -@@ -386,7 +387,7 @@ static ngx_command_t ngx_http_lua_cmds[] - NGX_HTTP_LOC_CONF_OFFSET, - 0, - (void *) ngx_http_lua_body_filter_inline }, -- -+#ifndef NGX_LUA_NO_BY_LUA_BLOCK - /* body_filter_by_lua_block { } */ - { ngx_string("body_filter_by_lua_block"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF -@@ -395,7 +396,7 @@ static ngx_command_t ngx_http_lua_cmds[] - NGX_HTTP_LOC_CONF_OFFSET, - 0, - (void *) ngx_http_lua_body_filter_inline }, -- -+#endif - { ngx_string("body_filter_by_lua_file"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF - |NGX_CONF_TAKE1, -@@ -403,14 +404,14 @@ static ngx_command_t ngx_http_lua_cmds[] - NGX_HTTP_LOC_CONF_OFFSET, - 0, - (void *) ngx_http_lua_body_filter_file }, -- -+#ifndef NGX_LUA_NO_BY_LUA_BLOCK - { ngx_string("balancer_by_lua_block"), - NGX_HTTP_UPS_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS, - ngx_http_lua_balancer_by_lua_block, - NGX_HTTP_SRV_CONF_OFFSET, - 0, - (void *) ngx_http_lua_balancer_handler_inline }, -- -+#endif - { ngx_string("balancer_by_lua_file"), - NGX_HTTP_UPS_CONF|NGX_CONF_TAKE1, - ngx_http_lua_balancer_by_lua, -@@ -517,14 +518,14 @@ static ngx_command_t ngx_http_lua_cmds[] - NGX_HTTP_LOC_CONF_OFFSET, - offsetof(ngx_http_lua_loc_conf_t, ssl_ciphers), - NULL }, -- -+#ifndef NGX_LUA_NO_BY_LUA_BLOCK - { ngx_string("ssl_certificate_by_lua_block"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS, - ngx_http_lua_ssl_cert_by_lua_block, - NGX_HTTP_SRV_CONF_OFFSET, - 0, - (void *) ngx_http_lua_ssl_cert_handler_inline }, -- -+#endif - { ngx_string("ssl_certificate_by_lua_file"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, - ngx_http_lua_ssl_cert_by_lua, diff --git a/nginx/patches/101-feature_test_fix.patch b/nginx/patches/101-feature_test_fix.patch deleted file mode 100755 index b867c88dd..000000000 --- a/nginx/patches/101-feature_test_fix.patch +++ /dev/null @@ -1,116 +0,0 @@ ---- a/auto/cc/name -+++ b/auto/cc/name -@@ -7,7 +7,7 @@ if [ "$NGX_PLATFORM" != win32 ]; then - - ngx_feature="C compiler" - ngx_feature_name= -- ngx_feature_run=yes -+ ngx_feature_run= - ngx_feature_incs= - ngx_feature_path= - ngx_feature_libs= ---- a/auto/cc/conf -+++ b/auto/cc/conf -@@ -183,7 +183,7 @@ if [ "$NGX_PLATFORM" != win32 ]; then - else - ngx_feature="gcc builtin atomic operations" - ngx_feature_name=NGX_HAVE_GCC_ATOMIC -- ngx_feature_run=yes -+ ngx_feature_run=no - ngx_feature_incs= - ngx_feature_path= - ngx_feature_libs= -@@ -204,7 +204,7 @@ if [ "$NGX_PLATFORM" != win32 ]; then - else - ngx_feature="C99 variadic macros" - ngx_feature_name="NGX_HAVE_C99_VARIADIC_MACROS" -- ngx_feature_run=yes -+ ngx_feature_run=no - ngx_feature_incs="#include - #define var(dummy, ...) sprintf(__VA_ARGS__)" - ngx_feature_path= -@@ -218,7 +218,7 @@ if [ "$NGX_PLATFORM" != win32 ]; then - - ngx_feature="gcc variadic macros" - ngx_feature_name="NGX_HAVE_GCC_VARIADIC_MACROS" -- ngx_feature_run=yes -+ ngx_feature_run=no - ngx_feature_incs="#include - #define var(dummy, args...) sprintf(args)" - ngx_feature_path= ---- a/auto/os/linux -+++ b/auto/os/linux -@@ -36,7 +36,7 @@ fi - - ngx_feature="epoll" - ngx_feature_name="NGX_HAVE_EPOLL" --ngx_feature_run=yes -+ngx_feature_run=no - ngx_feature_incs="#include " - ngx_feature_path= - ngx_feature_libs= -@@ -110,7 +110,7 @@ ngx_feature_test="int fd; struct stat sb - CC_AUX_FLAGS="$cc_aux_flags -D_GNU_SOURCE" - ngx_feature="sendfile()" - ngx_feature_name="NGX_HAVE_SENDFILE" --ngx_feature_run=yes -+ngx_feature_run=no - ngx_feature_incs="#include - #include " - ngx_feature_path= -@@ -131,7 +131,7 @@ fi - CC_AUX_FLAGS="$cc_aux_flags -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64" - ngx_feature="sendfile64()" - ngx_feature_name="NGX_HAVE_SENDFILE64" --ngx_feature_run=yes -+ngx_feature_run=no - ngx_feature_incs="#include - #include " - ngx_feature_path= -@@ -149,7 +149,7 @@ ngx_include="sys/prctl.h"; . auto/includ - - ngx_feature="prctl(PR_SET_DUMPABLE)" - ngx_feature_name="NGX_HAVE_PR_SET_DUMPABLE" --ngx_feature_run=yes -+ngx_feature_run=no - ngx_feature_incs="#include " - ngx_feature_path= - ngx_feature_libs= ---- a/auto/unix -+++ b/auto/unix -@@ -840,7 +840,7 @@ ngx_feature_test="void *p; p = memalign( - - ngx_feature="mmap(MAP_ANON|MAP_SHARED)" - ngx_feature_name="NGX_HAVE_MAP_ANON" --ngx_feature_run=yes -+ngx_feature_run=no - ngx_feature_incs="#include " - ngx_feature_path= - ngx_feature_libs= -@@ -853,7 +853,7 @@ ngx_feature_test="void *p; - - ngx_feature='mmap("/dev/zero", MAP_SHARED)' - ngx_feature_name="NGX_HAVE_MAP_DEVZERO" --ngx_feature_run=yes -+ngx_feature_run=no - ngx_feature_incs="#include - #include - #include " -@@ -868,7 +868,7 @@ ngx_feature_test='void *p; int fd; - - ngx_feature="System V shared memory" - ngx_feature_name="NGX_HAVE_SYSVSHM" --ngx_feature_run=yes -+ngx_feature_run=no - ngx_feature_incs="#include - #include " - ngx_feature_path= -@@ -882,7 +882,7 @@ ngx_feature_test="int id; - - ngx_feature="POSIX semaphores" - ngx_feature_name="NGX_HAVE_POSIX_SEM" --ngx_feature_run=yes -+ngx_feature_run=no - ngx_feature_incs="#include " - ngx_feature_path= - ngx_feature_libs= diff --git a/nginx/patches/102-sizeof_test_fix.patch b/nginx/patches/102-sizeof_test_fix.patch deleted file mode 100755 index 7d2430eab..000000000 --- a/nginx/patches/102-sizeof_test_fix.patch +++ /dev/null @@ -1,27 +0,0 @@ ---- a/auto/types/sizeof -+++ b/auto/types/sizeof -@@ -25,8 +25,14 @@ $NGX_INCLUDE_UNISTD_H - $NGX_INCLUDE_INTTYPES_H - $NGX_INCLUDE_AUTO_CONFIG_H - -+char object_code_block[] = { -+ '\n', 'e', '4', 'V', 'A', -+ '0', 'x', ('0' + sizeof($ngx_type)), -+ 'Y', '3', 'p', 'M', '\n' -+}; -+ - int main(void) { -- printf("%d", (int) sizeof($ngx_type)); -+ printf("dummy use of object_code_block to avoid gc-section: %c", object_code_block[0]); - return 0; - } - -@@ -40,7 +46,7 @@ eval "$ngx_test >> $NGX_AUTOCONF_ERR 2>& - - - if [ -x $NGX_AUTOTEST ]; then -- ngx_size=`$NGX_AUTOTEST` -+ ngx_size=`sed -ne 's/^e4VA0x\(.\)Y3pM$/\1/p' < $NGX_AUTOTEST` - echo " $ngx_size bytes" - fi - diff --git a/nginx/patches/103-sys_nerr.patch b/nginx/patches/103-sys_nerr.patch deleted file mode 100755 index 5f5d106fe..000000000 --- a/nginx/patches/103-sys_nerr.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- a/src/os/unix/ngx_errno.c -+++ b/src/os/unix/ngx_errno.c -@@ -8,6 +8,9 @@ - #include - #include - -+#ifndef NGX_SYS_NERR -+#define NGX_SYS_NERR 128 -+#endif - - /* - * The strerror() messages are copied because: diff --git a/nginx/patches/200-config.patch b/nginx/patches/200-config.patch deleted file mode 100755 index f35009576..000000000 --- a/nginx/patches/200-config.patch +++ /dev/null @@ -1,18 +0,0 @@ ---- a/conf/nginx.conf -+++ b/conf/nginx.conf -@@ -1,5 +1,5 @@ - --#user nobody; -+user nobody nogroup; - worker_processes 1; - - #error_log logs/error.log; -@@ -16,7 +16,7 @@ events { - - http { - include mime.types; -- default_type application/octet-stream; -+ #default_type application/octet-stream; - - #log_format main '$remote_addr - $remote_user [$time_local] "$request" ' - # '$status $body_bytes_sent "$http_referer" ' diff --git a/nginx/patches/201-ignore-invalid-options.patch b/nginx/patches/201-ignore-invalid-options.patch deleted file mode 100755 index 28be2fb71..000000000 --- a/nginx/patches/201-ignore-invalid-options.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- a/auto/options -+++ b/auto/options -@@ -397,8 +397,7 @@ $0: warning: the \"--with-sha1-asm\" opt - --test-build-solaris-sendfilev) NGX_TEST_BUILD_SOLARIS_SENDFILEV=YES ;; - - *) -- echo "$0: error: invalid option \"$option\"" -- exit 1 -+ echo "$0: error: ignoring invalid option \"$option\"" - ;; - esac - done diff --git a/nginx/patches/300-max-processes.patch b/nginx/patches/300-max-processes.patch deleted file mode 100755 index f7465d434..000000000 --- a/nginx/patches/300-max-processes.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/src/os/unix/ngx_process.h -+++ b/src/os/unix/ngx_process.h -@@ -44,7 +44,7 @@ typedef struct { - } ngx_exec_ctx_t; - - --#define NGX_MAX_PROCESSES 1024 -+#define NGX_MAX_PROCESSES 8 - - #define NGX_PROCESS_NORESPAWN -1 - #define NGX_PROCESS_JUST_SPAWN -2 diff --git a/protobuf/Makefile b/protobuf/Makefile old mode 100755 new mode 100644 index cc314bbea..de6aa5a40 --- a/protobuf/Makefile +++ b/protobuf/Makefile @@ -8,20 +8,18 @@ include $(TOPDIR)/rules.mk PKG_NAME:=protobuf -PKG_VERSION:=3.14.0 -PKG_RELEASE:=2 +PKG_VERSION:=3.17.3 +PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-cpp-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://github.com/google/protobuf/releases/download/v$(PKG_VERSION) -PKG_HASH:=50ec5a07c0c55d4ec536dd49021f2e194a26bfdbc531d03d1e9d4d3e27175659 +PKG_HASH:=51cec99f108b83422b7af1170afd7aeb2dd77d2bcbb7b6bad1f92509e9ccf8cb PKG_MAINTAINER:=Ken Keys PKG_LICENSE:=BSD-3-Clause PKG_LICENSE_FILES:=LICENSE PKG_CPE_ID:=cpe:/a:google:protobuf -HOST_BUILD_PARALLEL:=1 -PKG_BUILD_PARALLEL:=1 CMAKE_SOURCE_SUBDIR:=cmake include $(INCLUDE_DIR)/package.mk diff --git a/protobuf/patches/010-rpath.patch b/protobuf/patches/010-rpath.patch new file mode 100644 index 000000000..ef3e98ab1 --- /dev/null +++ b/protobuf/patches/010-rpath.patch @@ -0,0 +1,24 @@ +--- a/cmake/install.cmake ++++ b/cmake/install.cmake +@@ -16,8 +16,8 @@ foreach(_library ${_protobuf_libraries}) + $ + $) + if (UNIX AND NOT APPLE) +- set_property(TARGET ${_library} +- PROPERTY INSTALL_RPATH "$ORIGIN") ++# set_property(TARGET ${_library} ++# PROPERTY INSTALL_RPATH "$ORIGIN") + elseif (APPLE) + set_property(TARGET ${_library} + PROPERTY INSTALL_RPATH "@loader_path") +@@ -34,8 +34,8 @@ if (protobuf_BUILD_PROTOC_BINARIES) + BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR} + COMPONENT protoc) + if (UNIX AND NOT APPLE) +- set_property(TARGET protoc +- PROPERTY INSTALL_RPATH "$ORIGIN/../${CMAKE_INSTALL_LIBDIR}") ++# set_property(TARGET protoc ++# PROPERTY INSTALL_RPATH "$ORIGIN/../${CMAKE_INSTALL_LIBDIR}") + elseif (APPLE) + set_property(TARGET protoc + PROPERTY INSTALL_RPATH "@loader_path/../lib") diff --git a/serdisplib/Makefile b/serdisplib/Makefile old mode 100755 new mode 100644 index c0b2af05d..8b36a4a51 --- a/serdisplib/Makefile +++ b/serdisplib/Makefile @@ -1,58 +1,83 @@ -# -# Copyright (C) 2006-2011 OpenWrt.org -# Copyright (C) 2019 Ycarus (Yannick Chabanois) -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - include $(TOPDIR)/rules.mk PKG_NAME:=serdisplib -PKG_VERSION:=2.01 -PKG_RELEASE:=1 +PKG_VERSION:=2.02 +PKG_RELEASE:=2 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=@SF/serdisplib -PKG_MD5SUM:=4eb17cd70aa963c30a237d426ac24449 +PKG_HASH:=447b74007dc157b0378044245649850b26432b9185b6540ff681fcb0765c4d8b + +PKG_MAINTAINER:=Daniel Golle +PKG_LICENSE:=GPL-2.0-or-later +PLG_LICENSE_FILES:=COPYING + +PKG_FIXUP:=autoreconf +PKG_INSTALL:=1 +PKG_BUILD_PARALLEL:=1 +PKG_BUILD_DEPENDS:=libusb-compat include $(INCLUDE_DIR)/package.mk define Package/serdisplib SECTION:=libs CATEGORY:=Libraries - TITLE:=A display control library + TITLE:=serdisplib URL:=http://serdisplib.sourceforge.net/ - DEPENDS:=+libusb-1.0 +libusb-compat endef define Package/serdisplib/description - serdisplib is a library to drive serial and parallel displays - with built-in controllers. + serdisplib started as a library to drive serial displays with + built-in controllers. It can optionally dynamically link with + libusb-compat, libgd and libpthread, some features require having + those packages installed as well. endef -CONFIGURE_ARGS+= \ - --enable-shared \ - --enable-static \ - -TARGET_CFLAGS += $(FPIC) - -define Build/Compile - $(MAKE) -C $(PKG_BUILD_DIR) \ - CFLAGS="$(TARGET_CFLAGS) -Wall -Wno-implicit -I../include -I.." \ - all +define Package/serdisplib-tools + SECTION:=utils + CATEGORY:=Utilities + TITLE:=serdisplib tools + URL:=http://serdisplib.sourceforge.net/ + DEPENDS:=+serdisplib +libgd endef +define Package/serdisplib-tools/description + serdisplib started as a library to drive serial displays with + built-in controllers. This package contains tools for serdisplib: + * l4m132c_tool + * l4m320t_tool + * multidisplay + * sdcmegtron_tool + * touchscreen_tool +endef + +CONFIGURE_VARS += \ + ac_cv_build=$(GNU_TARGET_NAME) + +CONFIGURE_ARGS += \ + --enable-dynloading \ + --disable-statictools + define Build/InstallDev - $(INSTALL_DIR) $(1)/usr/include - $(CP) $(PKG_BUILD_DIR)/include/serdisplib $(1)/usr/include/ + $(INSTALL_DIR) $(1)/usr/include/serdisplib + $(CP) $(PKG_INSTALL_DIR)/usr/include/serdisplib/*.h $(1)/usr/include/serdisplib $(INSTALL_DIR) $(1)/usr/lib - $(CP) $(PKG_BUILD_DIR)/lib/libserdisp.{a,so*} $(1)/usr/lib/ + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libserdisp.{a,so*} $(1)/usr/lib/ endef define Package/serdisplib/install $(INSTALL_DIR) $(1)/usr/lib - $(CP) $(PKG_BUILD_DIR)/lib/libserdisp.so.* $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libserdisp.so* $(1)/usr/lib/ +endef + +define Package/serdisplib-tools/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/l4m132c_tool $(1)/usr/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/l4m320t_tool $(1)/usr/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/multidisplay $(1)/usr/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/sdcmegtron_tool $(1)/usr/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/touchscreen_tool $(1)/usr/bin endef $(eval $(call BuildPackage,serdisplib)) +$(eval $(call BuildPackage,serdisplib-tools)) diff --git a/serdisplib/patches/002-allow-1bpp-framebuffer.patch b/serdisplib/patches/002-allow-1bpp-framebuffer.patch new file mode 100644 index 000000000..ada4281e9 --- /dev/null +++ b/serdisplib/patches/002-allow-1bpp-framebuffer.patch @@ -0,0 +1,21 @@ +--- a/src/serdisp_specific_framebuffer.c ++++ b/src/serdisp_specific_framebuffer.c +@@ -312,13 +312,15 @@ serdisp_t* serdisp_framebuffer_setup(con + + if (fb_success) { + /* check if colour mode is supported */ +- if (! (vinfo.bits_per_pixel == 16 || vinfo.bits_per_pixel == 24 || vinfo.bits_per_pixel == 32) ) { ++ if (! (vinfo.bits_per_pixel == 1 ||vinfo.bits_per_pixel == 16 || vinfo.bits_per_pixel == 24 || vinfo.bits_per_pixel == 32) ) { + sd_error(SERDISP_ERUNTIME, "unsupported colour depth (%d)", vinfo.bits_per_pixel); + fb_success = 0; + } + } +- +- dd->scrbuf_size = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel/8; ++ if (vinfo.bits_per_pixel == 1) ++ dd->scrbuf_size = (vinfo.xres * vinfo.yres) / 8; ++ else ++ dd->scrbuf_size = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel/8; + + if (fb_success) { + /* map framebuffer device to memory */ diff --git a/serdisplib/patches/010-cross-compile.patch b/serdisplib/patches/010-cross-compile.patch new file mode 100644 index 000000000..339322251 --- /dev/null +++ b/serdisplib/patches/010-cross-compile.patch @@ -0,0 +1,101 @@ +--- a/Makefile.in ++++ b/Makefile.in +@@ -44,8 +44,8 @@ all: + done && test -z "$$fail" + + install: +- $(top_srcdir)/mkinstalldirs $(libdir)/pkgconfig +- $(INSTALL_DATA) serdisplib.pc $(libdir)/pkgconfig/ ++ $(top_srcdir)/mkinstalldirs $(DESTDIR)$(libdir)/pkgconfig ++ $(INSTALL_DATA) serdisplib.pc $(DESTDIR)$(libdir)/pkgconfig/ + @for dir in ${subdirs}; do \ + (cd $(srcdir) && cd $$dir && $(MAKE) install) \ + || case "$(MFLAGS)" in *k*) fail=yes;; *) exit 1;; esac; \ +--- a/server/Makefile.in ++++ b/server/Makefile.in +@@ -102,9 +102,9 @@ distclean: clean + + + install: $(PROGRAMS) +- $(top_srcdir)/mkinstalldirs $(bindir) +- $(top_srcdir)/mkinstalldirs $(sbindir) +- $(top_srcdir)/mkinstalldirs $(sysconfdir) ++ $(top_srcdir)/mkinstalldirs $(DESTDIR)$(bindir) ++ $(top_srcdir)/mkinstalldirs $(DESTDIR)$(sbindir) ++ $(top_srcdir)/mkinstalldirs $(DESTDIR)$(sysconfdir) + list='$(PROGRAMS_SBIN)'; \ + for prog in $$list; do \ + $(INSTALL_PROGRAM) $$prog $(sbindir)/ ; \ +--- a/src/Makefile.in ++++ b/src/Makefile.in +@@ -28,7 +28,7 @@ includedir = @includedir@ + datarootdir = @datarootdir@ + + CC=@CC@ +-AR=@AR@ -r ++AR=@AR@ + LN_S=@LN_S@ + INSTALL=@INSTALL@ + INSTALL_PROGRAM = @INSTALL_PROGRAM@ +@@ -184,14 +184,14 @@ programs: $(PROGRAMS) + $(CC) $(CFLAGS) $(DEFINES) -c $< + + $(LIB_DIR)/$(LIB_STATIC): $(LIB_OBJECTS) +- $(top_srcdir)/mkinstalldirs $(top_srcdir)/lib +- $(AR) $(LIB_DIR)/$(LIB_STATIC) $(LIB_OBJECTS) ++ $(top_srcdir)/mkinstalldirs $(DESTDIR)$(top_srcdir)/lib ++ $(AR) -r -- $(LIB_DIR)/$(LIB_STATIC) $(LIB_OBJECTS) + + $(LIB_DIR)/$(LIB_SHARED): $(LIB_OBJECTS) +- $(top_srcdir)/mkinstalldirs $(top_srcdir)/lib ++ $(top_srcdir)/mkinstalldirs $(DESTDIR)$(top_srcdir)/lib + $(CC) -fPIC -shared $(SONAME_FLAG) -o $(LIB_DIR)/$(LIB_SHARED) $(LIB_OBJECTS) $(LDFLAGS) $(EXTRA_LIBS) +- cd $(LIB_DIR) && $(LN_S) -f $(LIB_SHARED) lib$(LIB_NAME).so.$(VERSION_MAJOR) +- cd $(LIB_DIR) && $(LN_S) -f lib$(LIB_NAME).so.$(VERSION_MAJOR) lib$(LIB_NAME).so ++ cd $(DESTDIR)$(LIB_DIR) && $(LN_S) -f $(LIB_SHARED) lib$(LIB_NAME).so.$(VERSION_MAJOR) ++ cd $(DESTDIR)$(LIB_DIR) && $(LN_S) -f lib$(LIB_NAME).so.$(VERSION_MAJOR) lib$(LIB_NAME).so + + testserdisp: $(LIB_DIR)/$(LIB_STATIC) $(OBJECTS) + $(CC) -o testserdisp $(OBJECTS) $(LIB_SERDISP) $(EXTRA_LIBS_STATIC) +@@ -204,20 +204,20 @@ distclean: clean + /bin/rm -f Makefile + + install: $(LIB_DIR)/$(LIB_SHARED) $(LIB_DIR)/$(LIB_STATIC) +- $(top_srcdir)/mkinstalldirs $(bindir) +- $(top_srcdir)/mkinstalldirs $(libdir) +- $(top_srcdir)/mkinstalldirs $(includedir) +- $(top_srcdir)/mkinstalldirs $(includedir)/serdisplib ++ $(top_srcdir)/mkinstalldirs $(DESTDIR)$(bindir) ++ $(top_srcdir)/mkinstalldirs $(DESTDIR)$(libdir) ++ $(top_srcdir)/mkinstalldirs $(DESTDIR)$(includedir) ++ $(top_srcdir)/mkinstalldirs $(DESTDIR)$(includedir)/serdisplib + +- $(INSTALL_PROGRAM) $(PROGRAMS) $(bindir)/ +- $(INSTALL_PROGRAM) $(LIB_DIR)/$(LIB_SHARED) $(libdir)/ +- $(INSTALL_DATA) $(LIB_DIR)/$(LIB_STATIC) $(libdir)/ ++ $(INSTALL_PROGRAM) $(PROGRAMS) $(DESTDIR)$(bindir)/ ++ $(INSTALL_PROGRAM) $(LIB_DIR)/$(LIB_SHARED) $(DESTDIR)$(libdir)/ ++ $(INSTALL_DATA) $(LIB_DIR)/$(LIB_STATIC) $(DESTDIR)$(libdir)/ + list='$(LIB_HEADERFILES)'; \ + for headerfile in $$list; do \ +- $(INSTALL_DATA) ../include/serdisplib/$$headerfile $(includedir)/serdisplib/ ; \ ++ $(INSTALL_DATA) ../include/serdisplib/$$headerfile $(DESTDIR)$(includedir)/serdisplib/ ; \ + done +- cd $(libdir) && $(LN_S) -f $(LIB_SHARED) lib$(LIB_NAME).so.$(VERSION_MAJOR) +- cd $(libdir) && $(LN_S) -f lib$(LIB_NAME).so.$(VERSION_MAJOR) lib$(LIB_NAME).so ++ cd $(DESTDIR)$(libdir) && $(LN_S) -f $(LIB_SHARED) lib$(LIB_NAME).so.$(VERSION_MAJOR) ++ cd $(DESTDIR)$(libdir) && $(LN_S) -f lib$(LIB_NAME).so.$(VERSION_MAJOR) lib$(LIB_NAME).so + + uninstall: + -/bin/rm -f $(libdir)/libserdisp* +--- a/tools/Makefile.in ++++ b/tools/Makefile.in +@@ -151,7 +151,7 @@ distclean: clean + install: $(PROGRAMS) + list='$(PROGRAMS)'; \ + for prog in $$list; do \ +- $(INSTALL_PROGRAM) $$prog $(bindir)/ ; \ ++ $(INSTALL_PROGRAM) $$prog $(DESTDIR)$(bindir)/ ; \ + done + + uninstall: $(PROGRAMS) diff --git a/speedtestcpp/Makefile b/speedtestcpp/Makefile old mode 100755 new mode 100644 index db25f5bb8..95e8dc382 --- a/speedtestcpp/Makefile +++ b/speedtestcpp/Makefile @@ -1,42 +1,66 @@ -# -# Copyright (C) 2021 Ycarus (Yannick Chabanois) for OpenMPTCProuter project -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - include $(TOPDIR)/rules.mk PKG_NAME:=speedtestcpp -PKG_VERSION:=1.12 -PKG_RELEASE:=2 +PKG_VERSION:=1.20.2 +PKG_RELEASE:=1 -PKG_SOURCE_PROTO:=git -PKG_SOURCE_VERSION:=a01ae6eb04c5d3f4847aef73bf77849275ccc6eb PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz -PKG_SOURCE_URL:=https://github.com/fmantz/SpeedTest.git +PKG_SOURCE_URL:=https://codeload.github.com/oskarirauta/speedtestcpp/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=7d5c85f1d9a46f7d8a3ac4261ef1f92e53c511430bae096f7ec6f12a33d38904 -PKG_MAINTAINER:=Ycarus +PKG_MAINTAINER:=Oskari Rauta PKG_LICENSE:=MIT PKG_LICENSE_FILES:=LICENSE -CMAKE_INSTALL:=1 - include $(INCLUDE_DIR)/package.mk -include $(INCLUDE_DIR)/cmake.mk + +define Package/libspeedtestcpp + SECTION:=libs + CATEGORY:=Libraries + TITLE:=library for ookla's speedtest + DEPENDS:=+libcurl +libstdcpp + URL:=https://github.com/oskarirauta/speedtestcpp +endef + +define Package/libspeedtestcpp/description + Shared library that provides support for ookla's speedtest +endef define Package/speedtestcpp - SECTION:=net - CATEGORY:=Network - TITLE:=Yet another unofficial speedtest.net client cli interface - URL:=https://github.com/fmantz/SpeedTest - DEPENDS:=+curl +libstdcpp +libopenssl +libxml2 + SECTION:=net + CATEGORY:=Network + TITLE:=SpeedTest++ + DEPENDS:=+libspeedtestcpp +libstdcpp + URL:=https://github.com/oskarirauta/speedtestcpp + PROVIDES:=speedtestpp +endef + +define Package/speedtestcpp/description + Yet another unofficial speedtest.net client cli interface + forked from taganaka's SpeedTest with few improments and + lesser depends. +endef + +TARGET_CXXFLAGS += --std=c++23 -fPIC + +define Build/Configure +endef + +define Package/libspeedtestcpp/install + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_BUILD_DIR)/libspeedtestcpp.so* $(1)/usr/lib/ endef define Package/speedtestcpp/install $(INSTALL_DIR) $(1)/usr/bin - $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/SpeedTest $(1)/usr/bin/ - $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/speedtestJson $(1)/usr/bin/ + $(INSTALL_BIN) $(PKG_BUILD_DIR)/speedtest $(1)/usr/bin/ endef -$(eval $(call BuildPackage,speedtestcpp)) \ No newline at end of file +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/lib $(1)/usr/include/speedtest + $(CP) $(PKG_BUILD_DIR)/libspeedtestcpp.{so*,a} $(1)/usr/lib/ + $(CP) $(PKG_BUILD_DIR)/include/speedtest/*.hpp $(1)/usr/include/speedtest/ +endef + +$(eval $(call BuildPackage,libspeedtestcpp)) +$(eval $(call BuildPackage,speedtestcpp)) diff --git a/upx/Makefile b/upx/Makefile deleted file mode 100755 index 9310bcf81..000000000 --- a/upx/Makefile +++ /dev/null @@ -1,66 +0,0 @@ -# -# Copyright (C) 2011-2020 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# -include $(TOPDIR)/rules.mk - -PKG_NAME:=upx -PKG_RELEASE:=1 - -PKG_MAINTAINER:=Xingwang Liao -PKG_LICENSE:=GPL-2.0-only -PKG_LICENSE_FILES:=COPYING LICENSE - -PKG_SOURCE_PROTO:=git -PKG_SOURCE_DATE:=2022-01-15 -PKG_SOURCE_VERSION:=1050de5171f70fd4ba113016e4db994e898c7be3 -PKG_SOURCE_URL:=https://github.com/upx/upx.git -PKG_SOURCE:=$(PKG_NAME)-$(PKG_SOURCE_DATE).tar.gz - -HOST_BUILD_DEPENDS:=ucl/host - -include $(INCLUDE_DIR)/host-build.mk -include $(INCLUDE_DIR)/package.mk - -define Host/Compile - UPX_UCLDIR=$(STAGING_DIR_HOST) \ - $(MAKE) -C $(HOST_BUILD_DIR)/src \ - CXXFLAGS_WERROR="" LDFLAGS="$(HOST_LDFLAGS)" \ - CXX="$(HOSTCXX)" -endef - -define Host/Install - $(CP) $(HOST_BUILD_DIR)/src/upx.out $(STAGING_DIR_HOST)/bin/upx -endef - -define Host/Clean - rm -f $(STAGING_DIR_HOST)/bin/upx -endef - -define Package/upx - SECTION:=utils - CATEGORY:=Utilities - DEPENDS:=+libucl +libstdcpp +zlib - TITLE:=The Ultimate Packer for eXecutables - URL:=https://upx.github.io/ -endef - -define Package/upx/description -UPX is a free, portable, extendable, high-performance executable packer for -several different executable formats. It achieves an excellent compression ratio -and offers very fast decompression. Your executables suffer no memory overhead -or other drawbacks for most of the formats supported, because of in-place -decompression. -endef - -MAKE_PATH := src - -define Package/upx/install - $(INSTALL_DIR) $(1)/usr/bin - $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/upx.out $(1)/usr/bin/upx -endef - -$(eval $(call HostBuild)) -$(eval $(call BuildPackage,upx))