From 313e67b7ca7247a2f84793034901d807f7ca0f14 Mon Sep 17 00:00:00 2001 From: ling <1042585959@qq.com> Date: Mon, 10 Apr 2023 11:55:17 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../usr/lib/lua/luci/controller/schedule.lua | 6 +- .../usr/lib/lua/luci/model/cbi/schedule.lua | 4 +- .../usr/lib/lua/luci/controller/p910ndx.lua | 5 +- .../usr/lib/lua/luci/controller/hd_idle.lua | 6 +- .../usr/lib/lua/luci/controller/umount.lua | 5 +- .../usr/lib/lua/luci/model/cbi/hd_idle.lua | 3 +- .../files/usr/lib/lua/luci/controller/sms.lua | 32 +- .../usr/lib/lua/luci/view/rooter/sms.htm | 197 +-- .../ext-sms/files/usr/lib/sms/delall.sh | 35 - .../ext-sms/files/usr/lib/sms/delsms.sh | 6 +- .../ext-sms/files/usr/lib/sms/merge.lua | 165 -- .../ext-sms/files/usr/lib/sms/smsread.lua | 1 - .../usr/lib/lua/luci/controller/guestwifi.lua | 5 +- .../usr/lib/lua/luci/model/cbi/guestwifi.lua | 10 +- .../rmbim/files/lib/netifd/proto/mbim.sh | 17 +- rooter/0drivers/rqmi/Makefile | 12 +- .../files/usr/lib/rooter/qmi/connectqmi.sh | 8 - rooter/0mesh/mesh-mesh/Makefile | 34 + .../mesh-mesh/files/etc/config/batman-adv | 16 + rooter/0mesh/mesh-mesh/files/etc/config/mesh | 18 + .../files/etc/hotplug.d/net/99-batman-gw | 34 + rooter/0mesh/mesh-mesh/files/etc/init.d/zmesh | 9 + .../usr/lib/lua/luci/controller/batman.lua | 249 +++ .../usr/lib/lua/luci/controller/mesh.lua | 76 + .../usr/lib/lua/luci/view/batman/batman.htm | 300 ++++ .../usr/lib/lua/luci/view/mesh/mesh-setup.htm | 912 ++++++++++ .../mesh-mesh/files/usr/lib/mesh/checker.sh | 251 +++ .../mesh-mesh/files/usr/lib/mesh/ping.sh | 34 + .../mesh-mesh/files/usr/lib/mesh/radio.sh | 78 + .../mesh-mesh/files/usr/lib/mesh/save.sh | 25 + .../mesh-mesh/files/usr/lib/mesh/savecfg.sh | 16 + .../mesh-mesh/files/usr/lib/mesh/startstop.sh | 8 + .../resources/dracula/dracula_graffle.js | 1 + .../resources/dracula/dracula_graph.js | 1 + .../resources/dracula/raphael-min.js | 7 + .../resources/jquery/jquery-1.4.js | 154 ++ .../luci-static/resources/protocol/batadv.js | 8 + .../resources/protocol/batadv_hardif.js | 8 + rooter/0mesh/mesh-wpad/Makefile | 29 + .../lua/luci/model/cbi/fullmenu/bwmenu.lua | 2 +- .../bwmon/files/etc/init.d/bwmon | 2 +- .../bwmon/files/usr/lib/bwmon/amtleft.lua | 10 +- .../bwmon/files/usr/lib/bwmon/dataper.lua | 7 +- .../bwmon/files/usr/lib/bwmon/textbw.sh | 6 +- .../usr/lib/lua/luci/controller/blacklist.lua | 9 +- rooter/0optionalapps/ext-domain/Makefile | 15 +- .../ext-domain/files/etc/config/blockport | 4 - .../ext-domain/files/etc/config/filter | 1 + .../ext-domain/files/etc/init.d/domain | 46 + .../files/usr/lib/blockport/blockport.sh | 37 - .../ext-domain/files/usr/lib/domain/filter.sh | 26 + .../usr/lib/lua/luci/controller/blockport.lua | 12 - .../usr/lib/lua/luci/controller/domain.lua | 15 + .../model/cbi/{portblk.lua => domainfltr.lua} | 8 +- rooter/0optionalapps/ext-menu/Makefile | 35 + .../ext-menu/files/etc/uci-defaults/63-menu | 10 + .../usr/lib/fullmenu/full19/firewall.lua | 28 + .../lib/fullmenu/full19/luci-mod-status.json | 103 ++ .../lib/fullmenu/full19/luci-mod-system.json | 111 ++ .../files/usr/lib/fullmenu/full19/network.lua | 44 + .../files/usr/lib/fullmenu/full19/opkg.lua | 117 ++ .../fullmenu/full21/luci-app-firewall.json | 70 + .../lib/fullmenu/full21/luci-app-opkg.json | 13 + .../lib/fullmenu/full21/luci-mod-network.json | 98 ++ .../lib/fullmenu/full21/luci-mod-status.json | 137 ++ .../lib/fullmenu/full21/luci-mod-system.json | 136 ++ .../usr/lib/fullmenu/limited19/firewall.lua | 28 + .../fullmenu/limited19/luci-mod-status.json | 19 + .../fullmenu/limited19/luci-mod-system.json | 45 + .../usr/lib/fullmenu/limited19/network.lua | 44 + .../files/usr/lib/fullmenu/limited19/opkg.lua | 117 ++ .../fullmenu/limited21/luci-app-firewall.json | 70 + .../fullmenu/limited21/luci-mod-network.json | 98 ++ .../fullmenu/limited21/luci-mod-status.json | 38 + .../fullmenu/limited21/luci-mod-system.json | 60 + .../files/usr/lib/fullmenu/setmenu.sh | 34 + .../usr/lib/lua/luci/controller/fullmenu.lua | 28 + .../lib/lua/luci/view/fullmenu/fullmenu.htm | 166 ++ .../usr/lib/lua/luci/controller/speedtest.lua | 8 +- .../lib/lua/luci/view/speedtest/speedtest.htm | 4 +- .../usr/lib/lua/luci/controller/texting.lua | 12 +- rooter/0optionalapps/ext-throttle/Makefile | 36 + .../ext-throttle/files/etc/config/sqm | 34 + .../files/etc/hotplug.d/iface/11-sqm | 27 + .../ext-throttle/files/etc/init.d/sqm | 31 + .../ext-throttle/files/etc/sqm/sqm.conf | 5 + .../files/etc/uci-defaults/50-luci-sqm | 12 + .../files/usr/lib/sqm/defaults.sh | 109 ++ .../files/usr/lib/sqm/functions.sh | 923 ++++++++++ .../files/usr/lib/sqm/layer_cake.qos | 52 + .../files/usr/lib/sqm/layer_cake.qos.help | 4 + .../files/usr/lib/sqm/piece_of_cake.qos | 52 + .../files/usr/lib/sqm/piece_of_cake.qos.help | 4 + .../ext-throttle/files/usr/lib/sqm/run.sh | 130 ++ .../ext-throttle/files/usr/lib/sqm/simple.qos | 234 +++ .../files/usr/lib/sqm/simple.qos.help | 1 + .../files/usr/lib/sqm/simplest.qos | 104 ++ .../files/usr/lib/sqm/simplest.qos.help | 1 + .../files/usr/lib/sqm/simplest_tbf.qos | 85 + .../files/usr/lib/sqm/simplest_tbf.qos.help | 2 + .../ext-throttle/files/usr/lib/sqm/start-sqm | 66 + .../ext-throttle/files/usr/lib/sqm/stop-sqm | 54 + .../files/usr/lib/sqm/update-available-qdiscs | 14 + .../ext-wireguard/files/etc/init.d/wireguard | 5 - .../lua/luci/model/cbi/wireguard-client.lua | 5 - .../lib/lua/luci/view/wireguard/wireguard.htm | 87 +- .../files/usr/lib/wireguard/conf.sh | 18 +- .../files/usr/lib/wireguard/create.sh | 5 - .../files/usr/lib/wireguard/startvpn.sh | 45 +- .../files/usr/lib/wireguard/stopvpn.sh | 20 +- rooter/0optionalapps/libmicroxml/Makefile | 54 + .../lib/lua/luci/controller/dnsmasq-ipset.lua | 5 +- .../etc/hotplug.d/iface/99-travelmate-iface | 8 +- .../files/etc/init.d/travelmate | 4 - .../files/usr/lib/hotspot/travelmate.sh | 10 +- .../Makefile | 16 +- .../luci-app-iperf/files/etc/config/iperf | 96 ++ .../usr/lib/lua/luci/controller/iperf.lua | 56 + .../usr/lib/lua/luci/view/iperf/test.htm | 185 +++ .../usr/share/luci/menu.d/luci-app-iperf.json | 13 + .../usr/share/rpcd/acl.d/luci-app-iperf.json | 11 + .../usr/lib/lua/luci/controller/nft-qos.lua | 55 - .../lua/luci/model/cbi/nft-qos/nft-qos.lua | 229 --- .../usr/lib/lua/luci/view/nft-qos/rate.htm | 167 -- .../luci-app-nft-qos/po/bg/nft-qos.po | 233 --- .../luci-app-nft-qos/po/ca/nft-qos.po | 239 --- .../luci-app-nft-qos/po/cs/nft-qos.po | 239 --- .../luci-app-nft-qos/po/de/nft-qos.po | 240 --- .../luci-app-nft-qos/po/el/nft-qos.po | 239 --- .../luci-app-nft-qos/po/en/nft-qos.po | 233 --- .../luci-app-nft-qos/po/es/nft-qos.po | 246 --- .../luci-app-nft-qos/po/fr/nft-qos.po | 239 --- .../luci-app-nft-qos/po/he/nft-qos.po | 240 --- .../luci-app-nft-qos/po/hi/nft-qos.po | 233 --- .../luci-app-nft-qos/po/hu/nft-qos.po | 240 --- .../luci-app-nft-qos/po/it/nft-qos.po | 239 --- .../luci-app-nft-qos/po/ja/nft-qos.po | 239 --- .../luci-app-nft-qos/po/ko/nft-qos.po | 239 --- .../luci-app-nft-qos/po/mr/nft-qos.po | 239 --- .../luci-app-nft-qos/po/ms/nft-qos.po | 239 --- .../luci-app-nft-qos/po/nb_NO/nft-qos.po | 239 --- .../luci-app-nft-qos/po/pl/nft-qos.po | 240 --- .../luci-app-nft-qos/po/pt/nft-qos.po | 240 --- .../luci-app-nft-qos/po/pt_BR/nft-qos.po | 239 --- .../luci-app-nft-qos/po/ro/nft-qos.po | 240 --- .../luci-app-nft-qos/po/ru/nft-qos.po | 240 --- .../luci-app-nft-qos/po/sk/nft-qos.po | 239 --- .../luci-app-nft-qos/po/sv/nft-qos.po | 239 --- .../luci-app-nft-qos/po/templates/nft-qos.pot | 230 --- .../luci-app-nft-qos/po/tr/nft-qos.po | 239 --- .../luci-app-nft-qos/po/uk/nft-qos.po | 240 --- .../luci-app-nft-qos/po/vi/nft-qos.po | 239 --- .../luci-app-nft-qos/po/zh_Hans/nft-qos.po | 245 --- .../luci-app-nft-qos/po/zh_Hant/nft-qos.po | 245 --- .../share/rpcd/acl.d/luci-app-nft-qos.json | 11 - .../luci-app-rooterddns/Makefile | 34 - .../files/etc/uci-defaults/40_luci-ddns | 10 - .../usr/lib/lua/luci/controller/ddns.lua | 308 ---- .../lib/lua/luci/model/cbi/ddns/detail.lua | 1479 ----------------- .../lib/lua/luci/model/cbi/ddns/global.lua | 121 -- .../usr/lib/lua/luci/model/cbi/ddns/hints.lua | 166 -- .../lib/lua/luci/model/cbi/ddns/overview.lua | 219 --- .../files/usr/lib/lua/luci/tools/ddns.lua | 315 ---- .../lua/luci/view/admin_status/index/ddns.htm | 1 - .../lib/lua/luci/view/ddns/detail_logview.htm | 56 - .../lib/lua/luci/view/ddns/detail_lvalue.htm | 23 - .../lib/lua/luci/view/ddns/detail_value.htm | 9 - .../lib/lua/luci/view/ddns/global_value.htm | 34 - .../luci/view/ddns/overview_doubleline.htm | 10 - .../lua/luci/view/ddns/overview_enabled.htm | 16 - .../lua/luci/view/ddns/overview_startstop.htm | 17 - .../lua/luci/view/ddns/overview_status.htm | 180 -- .../lib/lua/luci/view/ddns/system_status.htm | 144 -- .../usr/lib/lua/luci/view/easyrsa/easyrsa.htm | 10 +- rooter/0optionalapps/nft-qos/Makefile | 59 - .../0optionalapps/nft-qos/files/lib/core.sh | 93 -- .../nft-qos/files/lib/dynamic.sh | 90 - .../nft-qos/files/lib/monitor.sh | 39 - .../nft-qos/files/lib/priority.sh | 93 -- .../0optionalapps/nft-qos/files/lib/static.sh | 74 - .../nft-qos/files/nft-qos-dynamic.hotplug | 36 - .../nft-qos/files/nft-qos-monitor.hotplug | 23 - .../nft-qos/files/nft-qos.config | 107 -- .../0optionalapps/nft-qos/files/nft-qos.init | 47 - .../pingtest/files/etc/config/ping | 6 - .../files/usr/lib/lua/luci/model/cbi/ping.lua | 14 +- .../qfirehose/src/firehose_protocol.c | 621 ++++--- rooter/0optionalapps/qfirehose/src/md5.c | 2 +- .../0optionalapps/qfirehose/src/qfirehose.c | 90 +- .../qfirehose/src/sahara_protocol.c | 41 +- .../0optionalapps/qfirehose/src/usb_linux.c | 105 +- .../0optionalapps/qfirehose/src/usb_linux.h | 6 +- rooter/0protocols/luci-proto-3x/Makefile | 11 +- .../lib/lua/luci/model/network/proto_3x.lua | 103 +- .../www/luci-static/resources/protocol/3x.js | 11 + rooter/0protocols/luci-proto-mbim/Makefile | 11 +- .../lib/lua/luci/model/network/proto_mbim.lua | 10 +- .../luci-static/resources/protocol/mbim.js | 107 ++ rooter/0routerspecfic/alix2d13/Makefile | 35 + .../alix2d13/files/usr/lib/rooter/special.sh | 7 + rooter/0routerspecfic/apu2c4/Makefile | 33 + rooter/0routerspecfic/b1300/Makefile | 35 + .../b1300/files/usr/lib/rooter/special.sh | 30 + rooter/0routerspecfic/d240/Makefile | 35 + .../d240/files/usr/lib/sdcard/sdcard.sh | 14 + rooter/0routerspecfic/dir860l/Makefile | 35 + .../files/etc/hotplug.d/iface/99-dir860-led | 13 + .../dir860l/files/usr/lib/rooter/special.sh | 8 + rooter/0routerspecfic/ext-ssh/Makefile | 36 + .../ext-ssh/files/etc/init.d/sshd | 54 + .../ext-ssh/files/etc/ssh/moduli | 407 +++++ .../ext-ssh/files/etc/ssh/ssh_config | 49 + .../ext-ssh/files/etc/ssh/ssh_host_ecdsa_key | 5 + .../files/etc/ssh/ssh_host_ecdsa_key.pub | 1 + .../files/etc/ssh/ssh_host_ed25519_key | 7 + .../files/etc/ssh/ssh_host_ed25519_key.pub | 1 + .../ext-ssh/files/etc/ssh/ssh_host_rsa_key | 27 + .../files/etc/ssh/ssh_host_rsa_key.pub | 1 + .../ext-ssh/files/etc/ssh/sshd_config | 120 ++ rooter/0routerspecfic/fscheck/Makefile | 36 + .../usr/lib/lua/luci/controller/filecheck.lua | 37 + .../lua/luci/view/admin_system/filecheck.htm | 104 ++ .../fscheck/files/usr/lib/rooter/filecheck.sh | 19 + rooter/0routerspecfic/h721/Makefile | 36 + .../h721/files/etc/exportgpio.sh | 24 + .../h721/files/etc/init.d/custom | 10 + .../h721/files/etc/init.d/exportgpio | 15 + .../h721/files/usr/lib/custom/custom.lua | 38 + .../h721/files/usr/lib/custom/hostname.sh | 10 + .../h721/files/usr/lib/custom/wifi.sh | 30 + .../h721/files/usr/lib/rooter/modem-led.sh | 94 ++ .../h721/files/usr/lib/rooter/special.sh | 4 + rooter/0routerspecfic/mt1300/Makefile | 35 + .../mt1300/files/etc/init.d/mt1300 | 23 + rooter/0routerspecfic/rbm11g/Makefile | 35 + .../rbm11g/files/usr/lib/rooter/modem-led.sh | 124 ++ .../rbm11g/files/usr/lib/rooter/special.sh | 11 + rooter/0routerspecfic/rbm33g/Makefile | 35 + .../rbm33g/files/usr/lib/rooter/special.sh | 70 + rooter/0routerspecfic/rbsxtr/Makefile | 35 + .../files/etc/uci-defaults/40_luci-theme | 11 + .../rbsxtr/files/usr/lib/rooter/modem-led.sh | 34 + .../www/luci-static/background/main_bg.jpg | Bin 0 -> 34809 bytes .../rbsxtr/files/www/luci-static/img/open.png | Bin 0 -> 41195 bytes rooter/0routerspecfic/rd05a1/Makefile | 2 +- .../firmware/ath10k/QCA9887/hw1.0/board.bin | Bin 1024 -> 0 bytes .../ath10k/QCA9887/hw1.0/firmware-5.bin | Bin 236104 -> 0 bytes .../firmware/ath10k/cal-pci-0000_00_00.0.bin | Bin 2116 -> 0 bytes rooter/0routerspecfic/vpnpolicy/Makefile | 31 + rooter/0routerspecfic/we826/Makefile | 35 + .../we826/files/etc/init.d/wd-init} | 6 +- .../we826/files/usr/lib/custom/watchdog.sh | 19 + .../files/usr/lib/rooter/changedevice.sh | 11 - rooter/0routerspecfic/wg1602/Makefile | 36 + .../wg1602/files/etc/init.d/sw-init | 15 + .../wg1602/files/usr/lib/rooter/special.sh | 28 + rooter/0routerspecfic/wg1608/Makefile | 36 + .../wg1608/files/etc/init.d/wd-init | 15 + .../wg1608/files/usr/lib/custom/watchdog.sh | 23 + .../wg1608/files/usr/lib/rooter/modem-led.sh | 51 + .../wg1608/files/usr/lib/rooter/special.sh | 15 + rooter/0routerspecfic/wg209/Makefile | 33 + .../wg209/files/usr/lib/rooter/modem-led.sh | 76 + rooter/0routerspecfic/wg259/Makefile | 34 + .../wg259/files/usr/lib/rooter/special.sh | 23 + rooter/0routerspecfic/wg3526/Makefile | 33 + .../wg3526/files/usr/lib/rooter/special.sh | 19 + rooter/0routerspecfic/wg827/Makefile | 36 + .../wg827/files/usr/lib/rooter/modem-led.sh | 38 + rooter/0routerspecfic/wrt1900/Makefile | 35 + .../wrt1900/files/etc/init.d/amsdu | 14 + rooter/0routerspecfic/x750/Makefile | 33 + .../x750/files/usr/lib/rooter/special.sh | 23 + .../files/usr/lib/iframe/mframe.html | 111 -- .../files/usr/lib/iframe/status.html | 4 - .../files/usr/lib/iframe/stupdate.sh | 112 +- .../ext-splash/files/usr/lib/iframe/update.sh | 224 +-- .../usr/lib/lua/luci/controller/splash.lua | 7 +- .../usr/lib/lua/luci/model/cbi/splashm.lua | 32 +- rooter/0splash/status/files/etc/config/splash | 4 +- .../usr/lib/lua/luci/controller/splashset.lua | 4 +- .../status/files/www/splash_files/check.gif | Bin 49 -> 0 bytes .../status/files/www/splash_files/full.gif | Bin 49 -> 0 bytes rooter/ext-rooter-basic/Makefile | 2 +- 284 files changed, 9889 insertions(+), 13018 deletions(-) delete mode 100644 rooter/0basicsupport/ext-sms/files/usr/lib/sms/delall.sh delete mode 100644 rooter/0basicsupport/ext-sms/files/usr/lib/sms/merge.lua create mode 100644 rooter/0mesh/mesh-mesh/Makefile create mode 100644 rooter/0mesh/mesh-mesh/files/etc/config/batman-adv create mode 100644 rooter/0mesh/mesh-mesh/files/etc/config/mesh create mode 100644 rooter/0mesh/mesh-mesh/files/etc/hotplug.d/net/99-batman-gw create mode 100644 rooter/0mesh/mesh-mesh/files/etc/init.d/zmesh create mode 100644 rooter/0mesh/mesh-mesh/files/usr/lib/lua/luci/controller/batman.lua create mode 100644 rooter/0mesh/mesh-mesh/files/usr/lib/lua/luci/controller/mesh.lua create mode 100644 rooter/0mesh/mesh-mesh/files/usr/lib/lua/luci/view/batman/batman.htm create mode 100644 rooter/0mesh/mesh-mesh/files/usr/lib/lua/luci/view/mesh/mesh-setup.htm create mode 100644 rooter/0mesh/mesh-mesh/files/usr/lib/mesh/checker.sh create mode 100644 rooter/0mesh/mesh-mesh/files/usr/lib/mesh/ping.sh create mode 100644 rooter/0mesh/mesh-mesh/files/usr/lib/mesh/radio.sh create mode 100644 rooter/0mesh/mesh-mesh/files/usr/lib/mesh/save.sh create mode 100644 rooter/0mesh/mesh-mesh/files/usr/lib/mesh/savecfg.sh create mode 100644 rooter/0mesh/mesh-mesh/files/usr/lib/mesh/startstop.sh create mode 100644 rooter/0mesh/mesh-mesh/files/www/luci-static/resources/dracula/dracula_graffle.js create mode 100644 rooter/0mesh/mesh-mesh/files/www/luci-static/resources/dracula/dracula_graph.js create mode 100644 rooter/0mesh/mesh-mesh/files/www/luci-static/resources/dracula/raphael-min.js create mode 100644 rooter/0mesh/mesh-mesh/files/www/luci-static/resources/jquery/jquery-1.4.js create mode 100644 rooter/0mesh/mesh-mesh/files/www/luci-static/resources/protocol/batadv.js create mode 100644 rooter/0mesh/mesh-mesh/files/www/luci-static/resources/protocol/batadv_hardif.js create mode 100644 rooter/0mesh/mesh-wpad/Makefile delete mode 100644 rooter/0optionalapps/ext-domain/files/etc/config/blockport create mode 100644 rooter/0optionalapps/ext-domain/files/etc/config/filter create mode 100644 rooter/0optionalapps/ext-domain/files/etc/init.d/domain delete mode 100644 rooter/0optionalapps/ext-domain/files/usr/lib/blockport/blockport.sh create mode 100644 rooter/0optionalapps/ext-domain/files/usr/lib/domain/filter.sh delete mode 100644 rooter/0optionalapps/ext-domain/files/usr/lib/lua/luci/controller/blockport.lua create mode 100644 rooter/0optionalapps/ext-domain/files/usr/lib/lua/luci/controller/domain.lua rename rooter/0optionalapps/ext-domain/files/usr/lib/lua/luci/model/cbi/{portblk.lua => domainfltr.lua} (50%) create mode 100644 rooter/0optionalapps/ext-menu/Makefile create mode 100644 rooter/0optionalapps/ext-menu/files/etc/uci-defaults/63-menu create mode 100644 rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/full19/firewall.lua create mode 100644 rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/full19/luci-mod-status.json create mode 100644 rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/full19/luci-mod-system.json create mode 100644 rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/full19/network.lua create mode 100644 rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/full19/opkg.lua create mode 100644 rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/full21/luci-app-firewall.json create mode 100644 rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/full21/luci-app-opkg.json create mode 100644 rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/full21/luci-mod-network.json create mode 100644 rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/full21/luci-mod-status.json create mode 100644 rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/full21/luci-mod-system.json create mode 100644 rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/limited19/firewall.lua create mode 100644 rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/limited19/luci-mod-status.json create mode 100644 rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/limited19/luci-mod-system.json create mode 100644 rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/limited19/network.lua create mode 100644 rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/limited19/opkg.lua create mode 100644 rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/limited21/luci-app-firewall.json create mode 100644 rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/limited21/luci-mod-network.json create mode 100644 rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/limited21/luci-mod-status.json create mode 100644 rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/limited21/luci-mod-system.json create mode 100644 rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/setmenu.sh create mode 100644 rooter/0optionalapps/ext-menu/files/usr/lib/lua/luci/controller/fullmenu.lua create mode 100644 rooter/0optionalapps/ext-menu/files/usr/lib/lua/luci/view/fullmenu/fullmenu.htm create mode 100644 rooter/0optionalapps/ext-throttle/Makefile create mode 100644 rooter/0optionalapps/ext-throttle/files/etc/config/sqm create mode 100644 rooter/0optionalapps/ext-throttle/files/etc/hotplug.d/iface/11-sqm create mode 100644 rooter/0optionalapps/ext-throttle/files/etc/init.d/sqm create mode 100644 rooter/0optionalapps/ext-throttle/files/etc/sqm/sqm.conf create mode 100644 rooter/0optionalapps/ext-throttle/files/etc/uci-defaults/50-luci-sqm create mode 100644 rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/defaults.sh create mode 100644 rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/functions.sh create mode 100644 rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/layer_cake.qos create mode 100644 rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/layer_cake.qos.help create mode 100644 rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/piece_of_cake.qos create mode 100644 rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/piece_of_cake.qos.help create mode 100644 rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/run.sh create mode 100644 rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/simple.qos create mode 100644 rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/simple.qos.help create mode 100644 rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/simplest.qos create mode 100644 rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/simplest.qos.help create mode 100644 rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/simplest_tbf.qos create mode 100644 rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/simplest_tbf.qos.help create mode 100644 rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/start-sqm create mode 100644 rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/stop-sqm create mode 100644 rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/update-available-qdiscs create mode 100644 rooter/0optionalapps/libmicroxml/Makefile rename rooter/0optionalapps/{luci-app-nft-qos => luci-app-iperf}/Makefile (55%) create mode 100644 rooter/0optionalapps/luci-app-iperf/files/etc/config/iperf create mode 100644 rooter/0optionalapps/luci-app-iperf/files/usr/lib/lua/luci/controller/iperf.lua create mode 100644 rooter/0optionalapps/luci-app-iperf/files/usr/lib/lua/luci/view/iperf/test.htm create mode 100644 rooter/0optionalapps/luci-app-iperf/files/usr/share/luci/menu.d/luci-app-iperf.json create mode 100644 rooter/0optionalapps/luci-app-iperf/files/usr/share/rpcd/acl.d/luci-app-iperf.json delete mode 100644 rooter/0optionalapps/luci-app-nft-qos/files/usr/lib/lua/luci/controller/nft-qos.lua delete mode 100644 rooter/0optionalapps/luci-app-nft-qos/files/usr/lib/lua/luci/model/cbi/nft-qos/nft-qos.lua delete mode 100644 rooter/0optionalapps/luci-app-nft-qos/files/usr/lib/lua/luci/view/nft-qos/rate.htm delete mode 100644 rooter/0optionalapps/luci-app-nft-qos/po/bg/nft-qos.po delete mode 100644 rooter/0optionalapps/luci-app-nft-qos/po/ca/nft-qos.po delete mode 100644 rooter/0optionalapps/luci-app-nft-qos/po/cs/nft-qos.po delete mode 100644 rooter/0optionalapps/luci-app-nft-qos/po/de/nft-qos.po delete mode 100644 rooter/0optionalapps/luci-app-nft-qos/po/el/nft-qos.po delete mode 100644 rooter/0optionalapps/luci-app-nft-qos/po/en/nft-qos.po delete mode 100644 rooter/0optionalapps/luci-app-nft-qos/po/es/nft-qos.po delete mode 100644 rooter/0optionalapps/luci-app-nft-qos/po/fr/nft-qos.po delete mode 100644 rooter/0optionalapps/luci-app-nft-qos/po/he/nft-qos.po delete mode 100644 rooter/0optionalapps/luci-app-nft-qos/po/hi/nft-qos.po delete mode 100644 rooter/0optionalapps/luci-app-nft-qos/po/hu/nft-qos.po delete mode 100644 rooter/0optionalapps/luci-app-nft-qos/po/it/nft-qos.po delete mode 100644 rooter/0optionalapps/luci-app-nft-qos/po/ja/nft-qos.po delete mode 100644 rooter/0optionalapps/luci-app-nft-qos/po/ko/nft-qos.po delete mode 100644 rooter/0optionalapps/luci-app-nft-qos/po/mr/nft-qos.po delete mode 100644 rooter/0optionalapps/luci-app-nft-qos/po/ms/nft-qos.po delete mode 100644 rooter/0optionalapps/luci-app-nft-qos/po/nb_NO/nft-qos.po delete mode 100644 rooter/0optionalapps/luci-app-nft-qos/po/pl/nft-qos.po delete mode 100644 rooter/0optionalapps/luci-app-nft-qos/po/pt/nft-qos.po delete mode 100644 rooter/0optionalapps/luci-app-nft-qos/po/pt_BR/nft-qos.po delete mode 100644 rooter/0optionalapps/luci-app-nft-qos/po/ro/nft-qos.po delete mode 100644 rooter/0optionalapps/luci-app-nft-qos/po/ru/nft-qos.po delete mode 100644 rooter/0optionalapps/luci-app-nft-qos/po/sk/nft-qos.po delete mode 100644 rooter/0optionalapps/luci-app-nft-qos/po/sv/nft-qos.po delete mode 100644 rooter/0optionalapps/luci-app-nft-qos/po/templates/nft-qos.pot delete mode 100644 rooter/0optionalapps/luci-app-nft-qos/po/tr/nft-qos.po delete mode 100644 rooter/0optionalapps/luci-app-nft-qos/po/uk/nft-qos.po delete mode 100644 rooter/0optionalapps/luci-app-nft-qos/po/vi/nft-qos.po delete mode 100644 rooter/0optionalapps/luci-app-nft-qos/po/zh_Hans/nft-qos.po delete mode 100644 rooter/0optionalapps/luci-app-nft-qos/po/zh_Hant/nft-qos.po delete mode 100644 rooter/0optionalapps/luci-app-nft-qos/root/usr/share/rpcd/acl.d/luci-app-nft-qos.json delete mode 100644 rooter/0optionalapps/luci-app-rooterddns/Makefile delete mode 100644 rooter/0optionalapps/luci-app-rooterddns/files/etc/uci-defaults/40_luci-ddns delete mode 100644 rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/controller/ddns.lua delete mode 100644 rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/model/cbi/ddns/detail.lua delete mode 100644 rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/model/cbi/ddns/global.lua delete mode 100644 rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/model/cbi/ddns/hints.lua delete mode 100644 rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/model/cbi/ddns/overview.lua delete mode 100644 rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/tools/ddns.lua delete mode 100644 rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/view/admin_status/index/ddns.htm delete mode 100644 rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/view/ddns/detail_logview.htm delete mode 100644 rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/view/ddns/detail_lvalue.htm delete mode 100644 rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/view/ddns/detail_value.htm delete mode 100644 rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/view/ddns/global_value.htm delete mode 100644 rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/view/ddns/overview_doubleline.htm delete mode 100644 rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/view/ddns/overview_enabled.htm delete mode 100644 rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/view/ddns/overview_startstop.htm delete mode 100644 rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/view/ddns/overview_status.htm delete mode 100644 rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/view/ddns/system_status.htm delete mode 100644 rooter/0optionalapps/nft-qos/Makefile delete mode 100644 rooter/0optionalapps/nft-qos/files/lib/core.sh delete mode 100644 rooter/0optionalapps/nft-qos/files/lib/dynamic.sh delete mode 100644 rooter/0optionalapps/nft-qos/files/lib/monitor.sh delete mode 100644 rooter/0optionalapps/nft-qos/files/lib/priority.sh delete mode 100644 rooter/0optionalapps/nft-qos/files/lib/static.sh delete mode 100644 rooter/0optionalapps/nft-qos/files/nft-qos-dynamic.hotplug delete mode 100644 rooter/0optionalapps/nft-qos/files/nft-qos-monitor.hotplug delete mode 100644 rooter/0optionalapps/nft-qos/files/nft-qos.config delete mode 100644 rooter/0optionalapps/nft-qos/files/nft-qos.init delete mode 100644 rooter/0optionalapps/pingtest/files/etc/config/ping create mode 100644 rooter/0protocols/luci-proto-3x/files/www/luci-static/resources/protocol/3x.js create mode 100644 rooter/0protocols/luci-proto-mbim/files/www/luci-static/resources/protocol/mbim.js create mode 100644 rooter/0routerspecfic/alix2d13/Makefile create mode 100644 rooter/0routerspecfic/alix2d13/files/usr/lib/rooter/special.sh create mode 100644 rooter/0routerspecfic/apu2c4/Makefile create mode 100644 rooter/0routerspecfic/b1300/Makefile create mode 100644 rooter/0routerspecfic/b1300/files/usr/lib/rooter/special.sh create mode 100644 rooter/0routerspecfic/d240/Makefile create mode 100644 rooter/0routerspecfic/d240/files/usr/lib/sdcard/sdcard.sh create mode 100644 rooter/0routerspecfic/dir860l/Makefile create mode 100644 rooter/0routerspecfic/dir860l/files/etc/hotplug.d/iface/99-dir860-led create mode 100644 rooter/0routerspecfic/dir860l/files/usr/lib/rooter/special.sh create mode 100644 rooter/0routerspecfic/ext-ssh/Makefile create mode 100644 rooter/0routerspecfic/ext-ssh/files/etc/init.d/sshd create mode 100644 rooter/0routerspecfic/ext-ssh/files/etc/ssh/moduli create mode 100644 rooter/0routerspecfic/ext-ssh/files/etc/ssh/ssh_config create mode 100644 rooter/0routerspecfic/ext-ssh/files/etc/ssh/ssh_host_ecdsa_key create mode 100644 rooter/0routerspecfic/ext-ssh/files/etc/ssh/ssh_host_ecdsa_key.pub create mode 100644 rooter/0routerspecfic/ext-ssh/files/etc/ssh/ssh_host_ed25519_key create mode 100644 rooter/0routerspecfic/ext-ssh/files/etc/ssh/ssh_host_ed25519_key.pub create mode 100644 rooter/0routerspecfic/ext-ssh/files/etc/ssh/ssh_host_rsa_key create mode 100644 rooter/0routerspecfic/ext-ssh/files/etc/ssh/ssh_host_rsa_key.pub create mode 100644 rooter/0routerspecfic/ext-ssh/files/etc/ssh/sshd_config create mode 100644 rooter/0routerspecfic/fscheck/Makefile create mode 100644 rooter/0routerspecfic/fscheck/files/usr/lib/lua/luci/controller/filecheck.lua create mode 100644 rooter/0routerspecfic/fscheck/files/usr/lib/lua/luci/view/admin_system/filecheck.htm create mode 100644 rooter/0routerspecfic/fscheck/files/usr/lib/rooter/filecheck.sh create mode 100644 rooter/0routerspecfic/h721/Makefile create mode 100644 rooter/0routerspecfic/h721/files/etc/exportgpio.sh create mode 100644 rooter/0routerspecfic/h721/files/etc/init.d/custom create mode 100644 rooter/0routerspecfic/h721/files/etc/init.d/exportgpio create mode 100644 rooter/0routerspecfic/h721/files/usr/lib/custom/custom.lua create mode 100644 rooter/0routerspecfic/h721/files/usr/lib/custom/hostname.sh create mode 100644 rooter/0routerspecfic/h721/files/usr/lib/custom/wifi.sh create mode 100644 rooter/0routerspecfic/h721/files/usr/lib/rooter/modem-led.sh create mode 100644 rooter/0routerspecfic/h721/files/usr/lib/rooter/special.sh create mode 100644 rooter/0routerspecfic/mt1300/Makefile create mode 100644 rooter/0routerspecfic/mt1300/files/etc/init.d/mt1300 create mode 100644 rooter/0routerspecfic/rbm11g/Makefile create mode 100644 rooter/0routerspecfic/rbm11g/files/usr/lib/rooter/modem-led.sh create mode 100644 rooter/0routerspecfic/rbm11g/files/usr/lib/rooter/special.sh create mode 100644 rooter/0routerspecfic/rbm33g/Makefile create mode 100644 rooter/0routerspecfic/rbm33g/files/usr/lib/rooter/special.sh create mode 100644 rooter/0routerspecfic/rbsxtr/Makefile create mode 100644 rooter/0routerspecfic/rbsxtr/files/etc/uci-defaults/40_luci-theme create mode 100644 rooter/0routerspecfic/rbsxtr/files/usr/lib/rooter/modem-led.sh create mode 100644 rooter/0routerspecfic/rbsxtr/files/www/luci-static/background/main_bg.jpg create mode 100644 rooter/0routerspecfic/rbsxtr/files/www/luci-static/img/open.png delete mode 100644 rooter/0routerspecfic/rd05a1/files/lib/firmware/ath10k/QCA9887/hw1.0/board.bin delete mode 100644 rooter/0routerspecfic/rd05a1/files/lib/firmware/ath10k/QCA9887/hw1.0/firmware-5.bin delete mode 100644 rooter/0routerspecfic/rd05a1/files/lib/firmware/ath10k/cal-pci-0000_00_00.0.bin create mode 100644 rooter/0routerspecfic/vpnpolicy/Makefile create mode 100644 rooter/0routerspecfic/we826/Makefile rename rooter/{0optionalapps/pingtest/files/etc/init.d/pingtest => 0routerspecfic/we826/files/etc/init.d/wd-init} (58%) create mode 100644 rooter/0routerspecfic/we826/files/usr/lib/custom/watchdog.sh delete mode 100644 rooter/0routerspecfic/we826q/files/usr/lib/rooter/changedevice.sh create mode 100644 rooter/0routerspecfic/wg1602/Makefile create mode 100644 rooter/0routerspecfic/wg1602/files/etc/init.d/sw-init create mode 100644 rooter/0routerspecfic/wg1602/files/usr/lib/rooter/special.sh create mode 100644 rooter/0routerspecfic/wg1608/Makefile create mode 100644 rooter/0routerspecfic/wg1608/files/etc/init.d/wd-init create mode 100644 rooter/0routerspecfic/wg1608/files/usr/lib/custom/watchdog.sh create mode 100644 rooter/0routerspecfic/wg1608/files/usr/lib/rooter/modem-led.sh create mode 100644 rooter/0routerspecfic/wg1608/files/usr/lib/rooter/special.sh create mode 100644 rooter/0routerspecfic/wg209/Makefile create mode 100644 rooter/0routerspecfic/wg209/files/usr/lib/rooter/modem-led.sh create mode 100644 rooter/0routerspecfic/wg259/Makefile create mode 100644 rooter/0routerspecfic/wg259/files/usr/lib/rooter/special.sh create mode 100644 rooter/0routerspecfic/wg3526/Makefile create mode 100644 rooter/0routerspecfic/wg3526/files/usr/lib/rooter/special.sh create mode 100644 rooter/0routerspecfic/wg827/Makefile create mode 100644 rooter/0routerspecfic/wg827/files/usr/lib/rooter/modem-led.sh create mode 100644 rooter/0routerspecfic/wrt1900/Makefile create mode 100644 rooter/0routerspecfic/wrt1900/files/etc/init.d/amsdu create mode 100644 rooter/0routerspecfic/x750/Makefile create mode 100644 rooter/0routerspecfic/x750/files/usr/lib/rooter/special.sh delete mode 100644 rooter/0splash/ext-splash/files/usr/lib/iframe/mframe.html delete mode 100644 rooter/0splash/status/files/www/splash_files/check.gif delete mode 100644 rooter/0splash/status/files/www/splash_files/full.gif diff --git a/rooter/0basicapps/ext-extra/files/usr/lib/lua/luci/controller/schedule.lua b/rooter/0basicapps/ext-extra/files/usr/lib/lua/luci/controller/schedule.lua index 8c1bda3..d64b6c6 100644 --- a/rooter/0basicapps/ext-extra/files/usr/lib/lua/luci/controller/schedule.lua +++ b/rooter/0basicapps/ext-extra/files/usr/lib/lua/luci/controller/schedule.lua @@ -2,8 +2,12 @@ module("luci.controller.schedule", package.seeall) +I18N = require "luci.i18n" +translate = I18N.translate + function index() local page - page = entry({"admin", "services", "schedule"}, cbi("schedule"), _("Scheduled Reboot"), 61) + + page = entry({"admin", "services", "schedule"}, cbi("schedule"), _(translate("Scheduled Reboot")), 61) page.dependent = true end diff --git a/rooter/0basicapps/ext-extra/files/usr/lib/lua/luci/model/cbi/schedule.lua b/rooter/0basicapps/ext-extra/files/usr/lib/lua/luci/model/cbi/schedule.lua index e6cbf29..e6ddaa7 100644 --- a/rooter/0basicapps/ext-extra/files/usr/lib/lua/luci/model/cbi/schedule.lua +++ b/rooter/0basicapps/ext-extra/files/usr/lib/lua/luci/model/cbi/schedule.lua @@ -23,8 +23,8 @@ o = d1:option(DummyValue, "zonename", translate("Timezone : "), translate("Be su d = m:section(TypedSection, "reboot", " ") c1 = d:option(ListValue, "enable", " "); -c1:value("0", "Disabled") -c1:value("1", "Enabled") +c1:value("0", translate("Disabled")) +c1:value("1", translate("Enabled")) c1.default=0 sdhour = d:option(ListValue, "sdhour", translate("Reboot Time :")) diff --git a/rooter/0basicapps/ext-p910nd/files/usr/lib/lua/luci/controller/p910ndx.lua b/rooter/0basicapps/ext-p910nd/files/usr/lib/lua/luci/controller/p910ndx.lua index 2fc941f..c6feee8 100644 --- a/rooter/0basicapps/ext-p910nd/files/usr/lib/lua/luci/controller/p910ndx.lua +++ b/rooter/0basicapps/ext-p910nd/files/usr/lib/lua/luci/controller/p910ndx.lua @@ -3,6 +3,9 @@ module("luci.controller.p910ndx", package.seeall) +I18N = require "luci.i18n" +translate = I18N.translate + function index() if not nixio.fs.access("/etc/config/p910nd") then return @@ -10,6 +13,6 @@ function index() local page - page = entry({"admin", "services", "p910ndx"}, cbi("p910ndx"), _("Print Server"), 60) + page = entry({"admin", "services", "p910ndx"}, cbi("p910ndx"), _(translate("Print Server")), 60) page.dependent = true end diff --git a/rooter/0basicapps/usb-storage/files/usr/lib/lua/luci/controller/hd_idle.lua b/rooter/0basicapps/usb-storage/files/usr/lib/lua/luci/controller/hd_idle.lua index 3e99da2..0cd3229 100644 --- a/rooter/0basicapps/usb-storage/files/usr/lib/lua/luci/controller/hd_idle.lua +++ b/rooter/0basicapps/usb-storage/files/usr/lib/lua/luci/controller/hd_idle.lua @@ -3,13 +3,15 @@ module("luci.controller.hd_idle", package.seeall) +I18N = require "luci.i18n" +translate = I18N.translate + function index() if not nixio.fs.access("/etc/config/hd-idle") then return end local page - - page = entry({"admin", "services", "hd_idle"}, cbi("hd_idle"), _("Hard Drive Idle"), 60) + page = entry({"admin", "services", "hd_idle"}, cbi("hd_idle"), _(translate("Hard Drive Idle")), 60) page.dependent = true end diff --git a/rooter/0basicapps/usb-storage/files/usr/lib/lua/luci/controller/umount.lua b/rooter/0basicapps/usb-storage/files/usr/lib/lua/luci/controller/umount.lua index dbc085c..37bcf31 100644 --- a/rooter/0basicapps/usb-storage/files/usr/lib/lua/luci/controller/umount.lua +++ b/rooter/0basicapps/usb-storage/files/usr/lib/lua/luci/controller/umount.lua @@ -1,8 +1,11 @@ module("luci.controller.umount", package.seeall) +I18N = require "luci.i18n" +translate = I18N.translate + function index() local page - page = entry({"admin", "services", "umount"}, cbi("umount", {hidesavebtn=true, hideresetbtn=true}), "Safely Eject Drive", 25) + page = entry({"admin", "services", "umount"}, cbi("umount", {hidesavebtn=true, hideresetbtn=true}), translate("Safely Eject Drive"), 25) page.dependent = true end diff --git a/rooter/0basicapps/usb-storage/files/usr/lib/lua/luci/model/cbi/hd_idle.lua b/rooter/0basicapps/usb-storage/files/usr/lib/lua/luci/model/cbi/hd_idle.lua index 272e926..1c3c18f 100644 --- a/rooter/0basicapps/usb-storage/files/usr/lib/lua/luci/model/cbi/hd_idle.lua +++ b/rooter/0basicapps/usb-storage/files/usr/lib/lua/luci/model/cbi/hd_idle.lua @@ -4,8 +4,7 @@ require("nixio.fs") m = Map("hd-idle", "Hard Drive Idle", - translate("This is a utility program for spinning-down external " .. - "disks after a period of idle time.")) + translate("This is a utility program for spinning-down external disks after a period of idle time.")) s = m:section(TypedSection, "hd-idle", translate("Settings")) s.anonymous = true diff --git a/rooter/0basicsupport/ext-sms/files/usr/lib/lua/luci/controller/sms.lua b/rooter/0basicsupport/ext-sms/files/usr/lib/lua/luci/controller/sms.lua index e17e2ee..aa9dc01 100644 --- a/rooter/0basicsupport/ext-sms/files/usr/lib/lua/luci/controller/sms.lua +++ b/rooter/0basicsupport/ext-sms/files/usr/lib/lua/luci/controller/sms.lua @@ -5,13 +5,15 @@ translate = I18N.translate function index() local fs = require "nixio.fs" - if not fs.stat("/etc/nosms") then - local page - page = entry({"admin", "modem", "sms"}, template("rooter/sms"), translate("短信功能"), 35) - page.dependent = true - - end - + + + + if not fs.stat("/etc/nosms") then + local page + page = entry({"admin", "modem", "sms"}, template("rooter/sms"), translate("短信功能"), 35) + page.dependent = true + + end entry({"admin", "modem", "check_read"}, call("action_check_read")) entry({"admin", "modem", "del_sms"}, call("action_del_sms")) @@ -19,7 +21,6 @@ function index() entry({"admin", "modem", "change_sms"}, call("action_change_sms")) entry({"admin", "modem", "change_smsdn"}, call("action_change_smsdn")) entry({"admin", "modem", "change_smsflag"}, call("action_change_smsflag")) - entry({"admin", "modem", "delall_sms"}, call("action_delall_sms")) end function trim(s) @@ -70,16 +71,12 @@ function action_send_sms() luci.http.write_json(rv) end -function action_delall_sms() - smsnum = luci.model.uci.cursor():get("modem", "general", "smsnum") - os.execute("/usr/lib/sms/delall.sh " .. smsnum) -end - function action_del_sms() - local set = luci.http.formvalue("set") - if set ~= nil then + local set = tonumber(luci.http.formvalue("set")) + if set ~= nil and set > 0 then + set = set - 1; smsnum = luci.model.uci.cursor():get("modem", "general", "smsnum") - os.execute("/usr/lib/sms/delsms.sh " .. smsnum .. " " .. set) + os.execute("/usr/lib/sms/delsms.sh " .. smsnum .. " " .. set) os.execute("touch /tmp/smswakeup" .. smsnum) end end @@ -125,7 +122,7 @@ function action_check_read() line = file:read("*line") full = full .. line if k < i then - full = full .. '\n' + full = full .. '
' end end else @@ -160,3 +157,4 @@ function action_change_smsflag() local set = tonumber(luci.http.formvalue("set")) os.execute("/usr/lib/sms/toggle.sh " .. set) end + diff --git a/rooter/0basicsupport/ext-sms/files/usr/lib/lua/luci/view/rooter/sms.htm b/rooter/0basicsupport/ext-sms/files/usr/lib/lua/luci/view/rooter/sms.htm index 6b4c787..fda6d81 100644 --- a/rooter/0basicsupport/ext-sms/files/usr/lib/lua/luci/view/rooter/sms.htm +++ b/rooter/0basicsupport/ext-sms/files/usr/lib/lua/luci/view/rooter/sms.htm @@ -22,7 +22,7 @@ if ( ss == "0" ) { clearListBox("smsList"); - document.getElementById('message').value=""; + document.getElementById('message').innerHTML=""; document.getElementById('total').innerHTML=""; document.getElementById('used').innerHTML=""; document.getElementById('mslots').innerHTML=""; @@ -32,7 +32,7 @@ if ( ss == "1" ) { clearListBox("smsList"); - document.getElementById('message').value=""; + document.getElementById('message').innerHTML=""; document.getElementById('total').innerHTML=""; document.getElementById('used').innerHTML=""; document.getElementById('mslots').innerHTML=""; @@ -86,7 +86,7 @@ var i; for(i=0;i"); - document.getElementById("sstat").innerHTML="<%:状态 消息正在发送%>"; + document.getElementById("sstat").innerHTML="<%:状态 :消息正在发送%>"; XHR.get('<%=luci.dispatcher.build_url("admin", "modem", "send_sms")%>', { set: num }, function(x, rv) @@ -214,92 +214,6 @@ } ); } - - function readcheck() - { - XHR.get('<%=luci.dispatcher.build_url("admin", "modem", "check_read")%>', null, - function(x, rv) - { - var ss = rv.ready; - document.getElementById('message').style.color = "initial"; - document.getElementById('conntype').innerHTML=rv.conntype; - if ( ss == "1" ) - { - clearListBox("smsList"); - document.getElementById('message').value=""; - document.getElementById('total').innerHTML=""; - document.getElementById('used').innerHTML=""; - document.getElementById('supported').innerHTML="<%:您有未读的短信,请前往查看%>"; - } - if ( ss == "3" ) - { - document.getElementById('supported').innerHTML="<%:消息读取有问题%>"; - } - if ( ss == "2" ) - { - document.getElementById('supported').innerHTML="<%:存在短信%>"; - clearListBox("smsList"); - document.getElementById('total').innerHTML=rv.max; - document.getElementById('used').innerHTML=rv.used; - var line=rv.line; - var arr=(line.split("\x1D")); - var len = arr.length; - indx = 0; - var i; - for(i=0;i indx-1 ) - { - selectline = indx -1 ; - } - select.value = selectline; - document.getElementById('message').value=ttext[selectline]; - } - } - } - } - ); - } - - function delallsms() - { - var r=confirm("<%:是否确定要删除所有短信?%>"); - if (r==false) - { - return false; - } - clearListBox("smsList"); - document.getElementById('message').style.color = "red"; - document.getElementById('message').value="<%:将删除所有短信.更新列表可能需要一些时间.%>"; - XHR.get('<%=luci.dispatcher.build_url("admin", "modem", "删除所有短信")%>', - null, - function() - { - readcheck(); - } - ); - } function delsms() { @@ -307,21 +221,84 @@ { return false; } - var r=confirm("<%:确认删除选中消息?%>"); + var r=confirm("<%:确认删除选中消息 ?%>"); if (r==false) { return false; } var s = document.getElementById("smsList").value; var dx = index[s]; + dx = dx + 1; clearListBox("smsList"); document.getElementById('message').style.color = "red"; - document.getElementById('message').value="<%:短信将被删除,同步到列表可能会很久(反复提交删除申请一样很久)%>"; + document.getElementById('message').innerHTML="<%:短信将被删除,同步到列表可能会很久(反复提交删除申请一样很久)%>"; XHR.get('<%=luci.dispatcher.build_url("admin", "modem", "del_sms")%>', { set: dx }, function() { - readcheck(); + XHR.get('<%=luci.dispatcher.build_url("admin", "modem", "check_read")%>', null, + function(x, rv) + { + var ss = rv.ready; + document.getElementById('message').style.color = "initial"; + document.getElementById('conntype').innerHTML=rv.conntype; + if ( ss == "1" ) + { + clearListBox("smsList"); + document.getElementById('message').innerHTML=""; + document.getElementById('total').innerHTML=""; + document.getElementById('used').innerHTML=""; + document.getElementById('supported').innerHTML="<%:您有未读的短信,请前往查看%>"; + } + if ( ss == "3" ) + { + document.getElementById('supported').innerHTML="<%:消息读取有问题%>"; + } + if ( ss == "2" ) + { + document.getElementById('supported').innerHTML="<%:存在短信%>"; + clearListBox("smsList"); + document.getElementById('total').innerHTML=rv.max; + document.getElementById('used').innerHTML=rv.used; + var line=rv.line; + var arr=(line.split("\x1D")); + var len = arr.length; + indx = 0; + var i; + for(i=0;i indx-1 ) + { + selectline = indx -1 ; + } + select.value = selectline; + document.getElementById('message').innerHTML=ttext[selectline]; + } + } + } + } + ); } ); } @@ -436,8 +413,8 @@ - - + + @@ -465,14 +442,6 @@
<%:SIM可存放的短信空间 (条)%>
<%:已使用的SIM短信空间 (条)%>
<%:SIM可存放的短信空间 (条)%>
<%:已使用的SIM短信空间 (条)%>
 
 
- - - - - - - -
  
@@ -481,6 +450,7 @@ + @@ -497,18 +467,15 @@
<%:Date%>
<%:时间%>
<%:短信%>
- - - - + + +
<%:短信内容 :%>
- -  
<%:短信内容 :%>
     
    - + @@ -527,6 +494,7 @@
     
    + @@ -554,3 +522,4 @@ <%+footer%> + diff --git a/rooter/0basicsupport/ext-sms/files/usr/lib/sms/delall.sh b/rooter/0basicsupport/ext-sms/files/usr/lib/sms/delall.sh deleted file mode 100644 index aa0c50b..0000000 --- a/rooter/0basicsupport/ext-sms/files/usr/lib/sms/delall.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/sh - -ROOTER=/usr/lib/rooter - -log() { - modlog "Delete SMS" "$@" -} - -CURRMODEM=$1 -COMMPORT="/dev/ttyUSB"$(uci get modem.modem$CURRMODEM.commport) -SMSLOC=$(uci -q get modem.modem$CURRMODEM.smsloc) - -LOCKDIR="/tmp/smslock$CURRMODEM" -PIDFILE="${LOCKDIR}/PID" - -while [ 1 -lt 6 ]; do - if mkdir "${LOCKDIR}" &>/dev/null; then - echo "$$" > "${PIDFILE}" - ATCMDD="AT+CPMS=\"$SMSLOC\";+CMGD=1,4" - OX=$($ROOTER/gcom/gcom-locked "$COMMPORT" "run-at.gcom" "$CURRMODEM" "$ATCMDD") - log "$OX" - uci set modem.modem$CURRMODEM.smsnum=999 - uci commit modem - break - else - OTHERPID="$(cat "${PIDFILE}")" - if [ $? = 0 ]; then - if ! kill -0 $OTHERPID &>/dev/null; then - rm -rf "${LOCKDIR}" - fi - fi - sleep 1 - fi -done -rm -rf "${LOCKDIR}" \ No newline at end of file diff --git a/rooter/0basicsupport/ext-sms/files/usr/lib/sms/delsms.sh b/rooter/0basicsupport/ext-sms/files/usr/lib/sms/delsms.sh index a8ccfc8..5294092 100644 --- a/rooter/0basicsupport/ext-sms/files/usr/lib/sms/delsms.sh +++ b/rooter/0basicsupport/ext-sms/files/usr/lib/sms/delsms.sh @@ -3,13 +3,12 @@ ROOTER=/usr/lib/rooter log() { - modlog "Delete SMS" "$@" + logger -t "Delete SMS" "$@" } CURRMODEM=$1 shift 1 SLOTS="$@" -log "$SLOTS" COMMPORT="/dev/ttyUSB"$(uci get modem.modem$CURRMODEM.commport) @@ -18,14 +17,13 @@ SMSLOC=$(uci -q get modem.modem$CURRMODEM.smsloc) LOCKDIR="/tmp/smslock$CURRMODEM" PIDFILE="${LOCKDIR}/PID" -while [ true ]; do +while [ 1 -lt 6 ]; do if mkdir "${LOCKDIR}" &>/dev/null; then echo "$$" > "${PIDFILE}" for SLOT in $SLOTS do ATCMDD="AT+CPMS=\"$SMSLOC\";+CMGD=$SLOT" OX=$($ROOTER/gcom/gcom-locked "$COMMPORT" "run-at.gcom" "$CURRMODEM" "$ATCMDD") - log "$OX" done uci set modem.modem$CURRMODEM.smsnum=999 uci commit modem diff --git a/rooter/0basicsupport/ext-sms/files/usr/lib/sms/merge.lua b/rooter/0basicsupport/ext-sms/files/usr/lib/sms/merge.lua deleted file mode 100644 index 4a7442c..0000000 --- a/rooter/0basicsupport/ext-sms/files/usr/lib/sms/merge.lua +++ /dev/null @@ -1,165 +0,0 @@ -#!/usr/bin/lua - -function ltrim(s) - return s:match'^%s*(.*)' -end - -file=arg[1] -filet=arg[1] - -overall = {} - -cntr = 1 -filein = io.open(file, "r") -maxslot = -1 -repeat - message = {} - local line = filein:read("*line") - if line == nil then - break - end - if cntr < 2 then - maxused = line - line = filein:read("*line") - maxslots = line - cntr=2 - else - message['slot'] = line - message['phone'] = filein:read("*line") - nline = filein:read("*line") - message['nline'] = nline - ncntr = 1 - msg="" - message['msgnum'] = "xxx" - message['msgord'] = "xxx" - message['msgmax'] = "xxx" - lines = filein:read("*line") - s, e = lines:find("Msg# ") - if s ~= nil then - bs, be = lines:find(",", e+1) - msgnum = lines:sub(e+1, be-1) - message['msgnum'] = msgnum - s, e = lines:find("/", be+1) - msgord = lines:sub(be+1, e-1) - message['msgord'] = msgord - message['msgmax'] = lines:sub(e+1) - lines = filein:read("*line") - end - msg = lines - nc = tonumber(nline) - if nc > 2 then - for i=1,nc-2,1 - do - lines = filein:read("*line") - if lines ~= "" then - msg = msg .. "\n" .. lines - else - if i == nc-2 then - if msgord == message['msgmax'] then - msg = msg .. "\n\n" - else - msg = msg .. "\n\n" - end - else - msg = msg .. "\n" - - end - end - end - --print(nln, msg) - --msg = msg .. "\n" - end - message['msg'] = msg - message['numlines'] = nc - 1 - sht = filein:read("*line") - s, e = sht:find("Msg#") - if s ~= nil then - shtt = sht:sub(1, s-1) - bs, be = sht:find("/", e) - sht = shtt .. sht:sub(be+2) - end - message['short'] = sht - overall[message['slot']] = message - if maxslot < tonumber(message['slot']) then - maxslot = tonumber(message['slot']) - end - end -until 1==0 -filein:close() - -fileout = io.open(filet, "w") -fileout:write(maxused, "\n") -fileout:write(maxslots, "\n") - -for i=0,maxslot,1 -do - msgbuild = {} - shortmsg = {} - if overall[tostring(i)] ~= nil then - --print(i, overall[tostring(i)]['msgnum']) - if overall[tostring(i)]['msgnum'] == "xxx" then - fileout:write(overall[tostring(i)]['slot'], "\n") - fileout:write(overall[tostring(i)]['phone'], "\n") - fileout:write(overall[tostring(i)]['nline'], "\n") - fileout:write(overall[tostring(i)]['msg'], "\n") - fileout:write(overall[tostring(i)]['short'], "\n") - else - msgnum = overall[tostring(i)]['msgnum'] - msgtmp = overall[tostring(i)]['slot'] - msgord = overall[tostring(i)]['msgord'] - msgmax = tonumber(overall[tostring(i)]['msgmax']) - msg = overall[tostring(i)]['msg'] - numlines = overall[tostring(i)]['numlines'] - --print(numlines) - msgbuild[overall[tostring(i)]['msgord']] = overall[tostring(i)]['msg'] - shortmsg[overall[tostring(i)]['msgord']] = overall[tostring(i)]['short'] - for j=i+1,maxslot,1 - do - if overall[tostring(j)] ~= nil then - if overall[tostring(j)]['msgnum'] == msgnum then - numlines = numlines + (overall[tostring(j)]['numlines']) - --print(overall[tostring(j)]['numlines']) - msgtmp = msgtmp .. " " .. overall[tostring(j)]['slot'] - msgbuild[overall[tostring(j)]['msgord']] = overall[tostring(j)]['msg'] - shortmsg[overall[tostring(j)]['msgord']] = overall[tostring(j)]['short'] - overall[tostring(j)] = nil - end - end - end - msg="" - mflg = 0 - short = nil - for j=1,msgmax,1 - do - if msgbuild[tostring(j)] ~= nil then - msg = msg .. msgbuild[tostring(j)] - if short == nil then - short = shortmsg[tostring(j)] - end - else - mflg = 1 - end - end - fileout:write(msgtmp, "\n") - fileout:write(overall[tostring(i)]['phone'], "\n") - - if mflg ~= 0 then - msg = "Partial Message : " .. msg - t = short:gsub("%s+", " ") - short = "Partial Message " .. t - end - endc = string.sub(msg, -2) - if endc == "\n\n" then - mlen = msg:len() - 2 - msg = string.sub(msg,1,mlen) - end - local _,n = msg:gsub("\n","") - fileout:write(tostring(n+1), "\n") - fileout:write(msg, "\n") - fileout:write(short, "\n") - end - end -end -fileout:close() - - diff --git a/rooter/0basicsupport/ext-sms/files/usr/lib/sms/smsread.lua b/rooter/0basicsupport/ext-sms/files/usr/lib/sms/smsread.lua index 65903a4..c881724 100644 --- a/rooter/0basicsupport/ext-sms/files/usr/lib/sms/smsread.lua +++ b/rooter/0basicsupport/ext-sms/files/usr/lib/sms/smsread.lua @@ -855,7 +855,6 @@ else end tfile:close() end -os.execute("/usr/lib/sms/merge.lua " .. tfname) os.execute("mv " .. tfname .. " /tmp/smstext" .. modemn) if #delslots > 0 then diff --git a/rooter/0basicsupport/luci-app-guestwifi/files/usr/lib/lua/luci/controller/guestwifi.lua b/rooter/0basicsupport/luci-app-guestwifi/files/usr/lib/lua/luci/controller/guestwifi.lua index a4cabce..37bf0ee 100644 --- a/rooter/0basicsupport/luci-app-guestwifi/files/usr/lib/lua/luci/controller/guestwifi.lua +++ b/rooter/0basicsupport/luci-app-guestwifi/files/usr/lib/lua/luci/controller/guestwifi.lua @@ -1,12 +1,15 @@ module("luci.controller.guestwifi", package.seeall) +I18N = require "luci.i18n" +translate = I18N.translate + function index() local page if not nixio.fs.access("/etc/config/wireless") then return end - page = entry({"admin", "network", "guestwifi"}, cbi("guestwifi", {hidesavebtn=true, hideresetbtn=true}), "Guest Wifi", 22) + page = entry({"admin", "network", "guestwifi"}, cbi("guestwifi", {hidesavebtn=true, hideresetbtn=true}), translate("Guest Wifi"), 22) page.dependent = true entry( {"admin", "network", "guestwifi", "edit"}, cbi("guestwifi-edit"), nil ).leaf = true diff --git a/rooter/0basicsupport/luci-app-guestwifi/files/usr/lib/lua/luci/model/cbi/guestwifi.lua b/rooter/0basicsupport/luci-app-guestwifi/files/usr/lib/lua/luci/model/cbi/guestwifi.lua index 6ec09c2..4500c32 100644 --- a/rooter/0basicsupport/luci-app-guestwifi/files/usr/lib/lua/luci/model/cbi/guestwifi.lua +++ b/rooter/0basicsupport/luci-app-guestwifi/files/usr/lib/lua/luci/model/cbi/guestwifi.lua @@ -99,12 +99,12 @@ function auto.cfgvalue(self, section) val = 0 end if val == "1" then - return "WPA-PSK (Medium Security)" + return translate("WPA-PSK (Medium Security)") else if val == "2" then - return "WPA2-PSK (Strong Security)" + return translate("WPA2-PSK (Strong Security)") else - return "None" + return translate("None") end end end @@ -118,9 +118,9 @@ function qos.cfgvalue(self, section) if val == "1" then dl_cfg = self.map:get(section, "dl") ul_cfg = self.map:get(section, "ul") - return "Download : " .. dl_cfg .. " Mbit/s / Upload : " .. ul_cfg .. " Mbit/s" + return translate("Download : ") .. dl_cfg .. translate(" Mbit/s / Upload : ") .. ul_cfg .. translate(" Mbit/s") else - return "Disabled" + return translate("Disabled") end end diff --git a/rooter/0drivers/rmbim/files/lib/netifd/proto/mbim.sh b/rooter/0drivers/rmbim/files/lib/netifd/proto/mbim.sh index 67e48fd..436635a 100644 --- a/rooter/0drivers/rmbim/files/lib/netifd/proto/mbim.sh +++ b/rooter/0drivers/rmbim/files/lib/netifd/proto/mbim.sh @@ -328,14 +328,6 @@ _proto_mbim_setup() { log "Failed to connect to network" return 1 fi - log "Save Connect Data" - uci set modem.modem$CURRMODEM.mdevice=$device - uci set modem.modem$CURRMODEM.mapn=$apn - uci set modem.modem$CURRMODEM.mipt=$itp - uci set modem.modem$CURRMODEM.mauth=$auth - uci set modem.modem$CURRMODEM.musername=$username - uci set modem.modem$CURRMODEM.mpassword=$password - uci commit modem tid=$((tid + 1)) @@ -475,10 +467,6 @@ _proto_mbim_setup() { # SIGNAL=$(umbim $DBG -n -t $tid -d $device signal) # CSQ=$(echo "$SIGNAL" | awk '/rssi:/ {print $2}') - if [ -e $ROOTER/modem-led.sh ]; then - $ROOTER/modem-led.sh $CURRMODEM 3 - fi - $ROOTER/log/logger "Modem #$CURRMODEM Connected" log "Modem $CURRMODEM Connected" @@ -552,8 +540,7 @@ _proto_mbim_setup() { $ROOTER/timezone.sh & fi fi - #CLB=$(uci -q get modem.modeminfo$CURRMODEM.lb) - CLB=1 + CLB=$(uci -q get modem.modeminfo$CURRMODEM.lb) if [ -e /etc/config/mwan3 ]; then INTER=$(uci get modem.modeminfo$CURRMODEM.inter) if [ -z $INTER ]; then @@ -590,8 +577,6 @@ proto_mbim_setup() { CPORT=$(uci get modem.modem$CURRMODEM.commport) ATCMDD="AT+COPS=0" OX=$($ROOTER/gcom/gcom-locked "/dev/ttyUSB$CPORT" "run-at.gcom" "$CURRMODEM" "$ATCMDD") - #log "Restart Modem" - #/usr/lib/rooter/luci/restart.sh $CURRMODEM sleep 5 } diff --git a/rooter/0drivers/rqmi/Makefile b/rooter/0drivers/rqmi/Makefile index a69b892..0674e1f 100644 --- a/rooter/0drivers/rqmi/Makefile +++ b/rooter/0drivers/rqmi/Makefile @@ -5,9 +5,9 @@ PKG_RELEASE:=$(AUTORELEASE) PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/project/uqmi.git -PKG_SOURCE_DATE:=2021-11-06 -PKG_SOURCE_VERSION:=6f956265167945267d676c99f123a8c822f0a77b -PKG_MIRROR_HASH:=1dbe14a28ec59b364dbde5dea9e10ed1c5c3eda274b6c7690c793a06643acf3e +PKG_SOURCE_DATE:=2022-05-04 +PKG_SOURCE_VERSION:=56cb2d4056fef132ccf78dfb6f3074ae5d109992 +PKG_MIRROR_HASH:=cc832b5318805df8c8387a3650f250dee72d5f1dbda4e4866b5503e186b2210c PKG_MAINTAINER:=Matti Laakso PKG_LICENSE:=GPL-2.0 @@ -32,7 +32,11 @@ define Package/rqmi/description endef TARGET_CFLAGS += \ - -I$(STAGING_DIR)/usr/include -ffunction-sections -fdata-sections + -I$(STAGING_DIR)/usr/include \ + -ffunction-sections \ + -fdata-sections \ + -Wno-error=dangling-pointer \ + -Wno-error=maybe-uninitialized TARGET_LDFLAGS += -Wl,--gc-sections diff --git a/rooter/0drivers/rqmi/files/usr/lib/rooter/qmi/connectqmi.sh b/rooter/0drivers/rqmi/files/usr/lib/rooter/qmi/connectqmi.sh index e3c4cbf..7dc6d02 100644 --- a/rooter/0drivers/rqmi/files/usr/lib/rooter/qmi/connectqmi.sh +++ b/rooter/0drivers/rqmi/files/usr/lib/rooter/qmi/connectqmi.sh @@ -202,14 +202,6 @@ for isp in $isplist if [[ -z $(echo "$CONN" | grep -o "disconnected") ]]; then ret=0 - uci set modem.modem$CURRMODEM.mdevice=$device - uci set modem.modem$CURRMODEM.mcid=$cid - uci set modem.modem$CURRMODEM.mapn=$NAPN - uci set modem.modem$CURRMODEM.mauth=$auth - uci set modem.modem$CURRMODEM.musername=$username - uci set modem.modem$CURRMODEM.mpassword=$password - uci commit modem - CONN4=$(uqmi -s -d "$device" --set-client-id wds,"$cid" --get-current-settings) log "GET-CURRENT-SETTINGS is $CONN4" diff --git a/rooter/0mesh/mesh-mesh/Makefile b/rooter/0mesh/mesh-mesh/Makefile new file mode 100644 index 0000000..39281b6 --- /dev/null +++ b/rooter/0mesh/mesh-mesh/Makefile @@ -0,0 +1,34 @@ +#Owned by DairyMan@Whirlpool +# +#Copyright GNU act. +include $(TOPDIR)/rules.mk + +PKG_NAME:=mesh-mesh +PKG_VERSION:=4.500 +PKG_RELEASE:=1 + +PKG_MAINTAINER:=Created by DM/makefile by Cobia@whirlpool +include $(INCLUDE_DIR)/package.mk + +define Package/mesh-mesh + SECTION:=utils + CATEGORY:=ROOter + SUBMENU:=Mesh Support + DEPENDS:=+kmod-batman-adv +alfred +batctl +ip + TITLE:=Install scripts for Mesh Network + PKGARCH:=all +endef + +define Package/mesh-mesh/description + Install scripts for Mesh Network +endef + + +define Build/Compile +endef + +define Package/mesh-mesh/install + $(CP) ./files/* $(1)/ +endef + +$(eval $(call BuildPackage,mesh-mesh)) diff --git a/rooter/0mesh/mesh-mesh/files/etc/config/batman-adv b/rooter/0mesh/mesh-mesh/files/etc/config/batman-adv new file mode 100644 index 0000000..0b4e014 --- /dev/null +++ b/rooter/0mesh/mesh-mesh/files/etc/config/batman-adv @@ -0,0 +1,16 @@ +config mesh 'bat0' + option aggregated_ogms '1' + option ap_isolation '0' + option bonding '0' + option fragmentation '0' + option gw_bandwidth '10000/2000' + option gw_mode 'client' + option gw_sel_class '20' + option log_level '2' + option orig_interval '1000' + option bridge_loop_avoidance '1' + option distributed_arp_table '1' + option multicast_mode '1' + option network_coding '0' + option hop_penalty '30' + option isolation_mark '0' \ No newline at end of file diff --git a/rooter/0mesh/mesh-mesh/files/etc/config/mesh b/rooter/0mesh/mesh-mesh/files/etc/config/mesh new file mode 100644 index 0000000..959ba5a --- /dev/null +++ b/rooter/0mesh/mesh-mesh/files/etc/config/mesh @@ -0,0 +1,18 @@ + +config radio 'radio' + option radionumber '0' + option usedfs '1' + option channelwidth '0' + option channellist '0' + option channelindex '10' + option dedicated '0' + +config network 'network' + option networkid 'MeshCloud' + option netencrypted '1' + option netpassword 'MeshPassword123' + +config roam 'roam' + option signalenable '1' + option signalid 'abcd' + diff --git a/rooter/0mesh/mesh-mesh/files/etc/hotplug.d/net/99-batman-gw b/rooter/0mesh/mesh-mesh/files/etc/hotplug.d/net/99-batman-gw new file mode 100644 index 0000000..600f70b --- /dev/null +++ b/rooter/0mesh/mesh-mesh/files/etc/hotplug.d/net/99-batman-gw @@ -0,0 +1,34 @@ +#!/bin/sh + +dhcp4_discover () { + ifup lan_dhcp +} + +dhcp4_kill () { + ifdown lan_dhcp +} + +dnsmasq_start () { + uci revert -P/var/state dhcp.@dnsmasq[0].domainneeded + uci revert -P/var/state dhcp.@dnsmasq[0].boguspriv + uci revert -P/var/state dhcp.@dnsmasq[0].rebind_protection + uci revert -P/var/state dhcp.lan.ignore + /etc/init.d/dnsmasq restart +} + +dnsmasq_stop () { + uci set -P/var/state dhcp.@dnsmasq[0].domainneeded= + uci set -P/var/state dhcp.@dnsmasq[0].boguspriv= + uci set -P/var/state dhcp.@dnsmasq[0].rebind_protection=0 + uci set -P/var/state dhcp.lan.ignore=1 + echo no-dhcp-interface=br-lan >> /var/etc/dnsmasq.conf + /etc/init.d/dnsmasq restart +} + +if [ "$BATTYPE" = "gw" ] ; then + case "$BATACTION" in + add) dnsmasq_stop ; dhcp4_discover ;; + del) dhcp4_kill ; dnsmasq_start ;; + change) dhcp4_kill ; sleep 5 ; dhcp4_discover ;; + esac +fi diff --git a/rooter/0mesh/mesh-mesh/files/etc/init.d/zmesh b/rooter/0mesh/mesh-mesh/files/etc/init.d/zmesh new file mode 100644 index 0000000..68e6158 --- /dev/null +++ b/rooter/0mesh/mesh-mesh/files/etc/init.d/zmesh @@ -0,0 +1,9 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2006 OpenWrt.org + +START=99 + +start() { + /usr/lib/mesh/checker.sh +} + diff --git a/rooter/0mesh/mesh-mesh/files/usr/lib/lua/luci/controller/batman.lua b/rooter/0mesh/mesh-mesh/files/usr/lib/lua/luci/controller/batman.lua new file mode 100644 index 0000000..8f2cf83 --- /dev/null +++ b/rooter/0mesh/mesh-mesh/files/usr/lib/lua/luci/controller/batman.lua @@ -0,0 +1,249 @@ +--[[ +LuCI - Lua Configuration Interface + +Copyright 2012 Jo-Philipp Wich + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +$Id$ +]]-- + +module("luci.controller.batman", package.seeall) + +local function split(str, pat) + local t = {} -- NOTE: use {n = 0} in Lua-5.0 + local fpat = "(.-)" .. pat + local last_end = 1 + local s, e, cap = str:find(fpat, 1) + while s do + if s ~= 1 or cap ~= "" then + table.insert(t,cap) + end + last_end = e+1 + s, e, cap = str:find(fpat, last_end) + end + if last_end <= #str then + cap = str:sub(last_end) + table.insert(t, cap) + end + return t +end + + +function index() + local page + + page = node("admin", "mesh", "batman") + page.target = template("batman/batman") + page.title = _("Mesh Status") + page.order = 1 + + node("batman") + + page = node("batman", "json") + page.target = call("act_json") + + page = node("batman", "topo") + page.target = call("act_topo") + page.leaf = true + + page = node("batman", "graph") + page.target = template("batman_graph") + page.leaf = true +end + +function act_topo(mode) + if not mode or mode == "dot" or mode == "json" then + local fd = io.popen("batadv-vis -f %s" %( mode or "dot" )) + if fd then + if mode == "json" then + luci.http.prepare_content("application/json") + luci.http.write("[") + local ln + repeat + ln = fd:read("*l") + if ln then + luci.http.write(ln) + luci.http.write(", ") + end + until not ln + luci.http.write("{ } ]") + else + luci.http.prepare_content("text/vnd.graphviz") + luci.http.header("Content-Disposition", + "attachment; filename=topo-%s-%s.vd" + %{ luci.sys.hostname(), os.date("%Y%m%d-%H%M%S") }) + luci.http.write(fd:read("*a")) + end + fd:close() + else + luci.http.status(500, "No data") + end + else + luci.http.status(500, "Bad mode") + end +end + +function act_json() + local v, l, fd + local rv = { + interfaces = { }, + originators = { }, + gateways = { } + } + + -- + -- interfaces + -- + fd = io.popen("batctl if") + if fd then + repeat + l = fd:read("*l") + v = l and l:match("^(.-):") + if v then + rv.interfaces[#rv.interfaces+1] = v + end + until not l + fd:close() + end + +os.execute("cat /proc/net/arp > /tmp/arp") + +iplist = {} +maclist = {} +index = 0 +fd = io.open("/tmp/arp") +if fd then + -- skip header line + fd:read("*l") + repeat + l = fd:read("*l") + if l then + lan = l + s1, e1 = lan:find("0x2") + if s1 ~= nil then + s, e = l:find(" ") + if s ~= nil then + ip = l:sub(0, e-1) + + fc = io.popen("batctl translate " .. ip) + if fc then + mac = fc:read("*l") + fc:close() + iplist[index] = ip + maclist[index] = mac + index = index + 1 + end + end + end + end + until not l + fd:close() +end + + -- + -- originators + -- + local originators_command = ( + "batctl o -H 2>/dev/null ".. -- gets originators from batctl + "| tr -d '[]()' ".. -- removes brackets and parenthesis + "| sed 's/^ / -/g' ".. -- normalizes output, adding a minus when no asterisk is outputed in each line + "| sed 's/^ //g' ".. -- removes the space from the beginning of the line + "| sed -r 's/\\s+/,/g'".. -- replaces tabs for commas + "| sed -r 's/s,/,/g'" -- removes the 's' from the last_seen field referencing seconds + ) + fd = io.popen(originators_command) + if fd then + repeat + l = fd:read() + if l then + local asterisk, originator_name, last_seen, link_quality, next_hop, outgoing_if + asterisk, originator_name, last_seen, link_quality, next_hop, outgoing_if = unpack(split(l, ",")) + if originator_name and last_seen and link_quality then + if originator_name == next_hop then + next_hop = "Here" + end + if index > 0 then + for j=0,index-1 do + if maclist[j] == originator_name then + originator_name = iplist[j] .. " (" .. originator_name .. ")" + end + if maclist[j] == next_hop then + next_hop = iplist[j] + end + end + end + rv.originators[#rv.originators+1] = { + originator_name, + tonumber(last_seen) * 1000, + tonumber(link_quality), + next_hop, + outgoing_if + } + end + end + until not l + fd:close() + end + + -- + -- gateways + -- + fd = io.popen("batctl gwl") + if fd then + -- skip header line + fd:read("*l") + fd:read("*l") + + repeat + l = fd:read("*l") + if l then + local a, m, q, n, i, r = l:match("^(%S*) +([^ ]+) +%( *(%d+)%) +([^ ]+) +%[ *(%S+)%]: +(%S+)") + if a and m and q and n and i and r then + c="0" + if index > 0 then + for j=0,index-1 do + if maclist[j] == m then + m = iplist[j] + end + if maclist[j] == n then + n = iplist[j] + end + end + end + rv.gateways[#rv.gateways+1] = { + #a > 0, + m, + tonumber(q), + n, + i, + tonumber(c), + r + } + end + end + until not l + fd:close() + end + + -- local Gateway status + + rv.status = "Client" + fd = io.popen("batctl gw") + if fd then + l = fd:read("*l") + s, e = l:find("server") + if s ~= nil then + rv.status = "Server" + end + fd:close() + end + + + luci.http.prepare_content("application/json") + luci.http.write_json(rv) +end diff --git a/rooter/0mesh/mesh-mesh/files/usr/lib/lua/luci/controller/mesh.lua b/rooter/0mesh/mesh-mesh/files/usr/lib/lua/luci/controller/mesh.lua new file mode 100644 index 0000000..923cec2 --- /dev/null +++ b/rooter/0mesh/mesh-mesh/files/usr/lib/lua/luci/controller/mesh.lua @@ -0,0 +1,76 @@ +module("luci.controller.mesh", package.seeall) +function index() + local page + entry({"admin", "mesh"}, firstchild(), "Mesh", 71).dependent=false + page = entry({"admin", "mesh", "mesh"}, template("mesh/mesh-setup"), "Mesh Configuration", 71) + page.dependent = true + + entry({"admin", "mesh", "getstate"}, call("action_getstate")) + entry({"admin", "mesh", "sendmeshstate"}, call("action_sendmeshstate")) + entry({"admin", "mesh", "meshcfg"}, call("action_meshcfg")) + entry({"admin", "mesh", "meshstartstop"}, call("action_meshstartstop")) +end + +function action_getstate() + local rv = {} + local radiolist = {} + + file = io.open("/etc/meshrun", "r") + if file == nil then + rv["state"] = "0" + else + rv["state"] = "1" + file:close() + end + os.execute("/usr/lib/mesh/radio.sh ") + file = io.open("/tmp/radiolist", "r") + if file ~= nil then + j = file:read("*line") + rv['radio'] = j + if j ~=0 then + for i=0, j-1 do + radiolist[i] = file:read("*line") + end + rv['radiolist'] = radiolist + end + rv['radionumber'] = file:read("*line") + rv['channelindex'] = file:read("*line") + rv['channellist'] = file:read("*line") + rv['channelwidth'] = file:read("*line") + rv['usedfs'] = file:read("*line") + rv['dedicated'] = file:read("*line") + + rv['networkid'] = file:read("*line") + rv['netencrypted'] = file:read("*line") + rv['netpassword'] = file:read("*line") + + rv['signalenable'] = file:read("*line") + rv['signalid'] = file:read("*line") + + file:close() + else + rv["radio"] = "0" + end + + + luci.http.prepare_content("application/json") + luci.http.write_json(rv) +end + +function action_sendmeshstate() + local set = luci.http.formvalue("set") + + os.execute('/usr/lib/mesh/save.sh "' .. set .. '"') +end + +function action_meshcfg() + local set = luci.http.formvalue("set") + + os.execute('/usr/lib/mesh/savecfg.sh "' .. set .. '"') +end + +function action_meshstartstop() + os.execute('/usr/lib/mesh/startstop.sh') + os.execute("reboot &") +end + diff --git a/rooter/0mesh/mesh-mesh/files/usr/lib/lua/luci/view/batman/batman.htm b/rooter/0mesh/mesh-mesh/files/usr/lib/lua/luci/view/batman/batman.htm new file mode 100644 index 0000000..d23421c --- /dev/null +++ b/rooter/0mesh/mesh-mesh/files/usr/lib/lua/luci/view/batman/batman.htm @@ -0,0 +1,300 @@ +<%# +LuCI - Lua Configuration Interface +Copyright 2012 Jo-Philipp Wich + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +$Id$ + +-%> + +<% luci.http.prepare_content("text/html") %> + +<%+header%> + + + + + + + + +

    <%:Mesh Status%>

    + +
    +
    + + + + + +
    Internet Status :
      + + +
      + <%:Active Mesh Nodes%> + + + + + + + + + + + +
      <%:Link Quality%><%:MAC-Address%><%:Last Seen%><%:Interface%><%:Next Hop%>

      <%:Collecting data...%>
      +
      + +
      + <%:Other Mesh Nodes with Internet Access%> + + + + + + + + + + + +
      <%:MAC-Address%><%:Speed%><%:Link Quality%><%:Interface%><%:Next Hop%>

      <%:Collecting data...%>
      +
      + +
      + <%:Visualization%> +
      +
      + +<%+footer%> diff --git a/rooter/0mesh/mesh-mesh/files/usr/lib/lua/luci/view/mesh/mesh-setup.htm b/rooter/0mesh/mesh-mesh/files/usr/lib/lua/luci/view/mesh/mesh-setup.htm new file mode 100644 index 0000000..60a652b --- /dev/null +++ b/rooter/0mesh/mesh-mesh/files/usr/lib/lua/luci/view/mesh/mesh-setup.htm @@ -0,0 +1,912 @@ +<%+header%> +<% +local sys = require "luci.sys" +local utl = require "luci.util" +local fs = require "nixio.fs" + +function showicon(lck) + if lck == 0 then + return resource .. "/icons/unlock1.png" + else + return resource .. "/icons/lock1.png" + end +end + +-%> + + + +
      +
      +

      Mesh Network Configuration

      +
      + +
      + + + + + + + + + + + + + + + + + + + + + +
      Config Status
      Import Configuration File
      Export Configuration File
      Save Settings
      Apply Settings
      Reload Settings
      No Changes
      + + + +
      + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Mesh Radio Settings
      Select Backhaul Radio
      + +
      Dedicated Backhaul Radio
      Select Backhaul Channel
      + +
      Select Backhaul Channel
      + +
      Use DFS Channels
      Select Backhaul Channel
      + +
      Use DFS Channels
      Channel Bandwidth
      + +
      Channel Bandwidth
      + +
      Channel Bandwidth
      + +
      Channel Bandwidth
      + +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Mesh Network Settings
      Mesh Network ID
      Network Encrypted
      +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Access Point Roaming
      Enable Low Signal Roaming
      Roaming ID
      + + + + + +
      + +
      + +
      + +
      +
      +<%+footer%> \ No newline at end of file diff --git a/rooter/0mesh/mesh-mesh/files/usr/lib/mesh/checker.sh b/rooter/0mesh/mesh-mesh/files/usr/lib/mesh/checker.sh new file mode 100644 index 0000000..9bf3cbf --- /dev/null +++ b/rooter/0mesh/mesh-mesh/files/usr/lib/mesh/checker.sh @@ -0,0 +1,251 @@ +#!/bin/sh +. /lib/functions.sh + +log() { + logger -t "Checker" "$@" +} + +channel2="1,2,3,4,5,6,7,8,9,10,11,12,13,14" +channel5="36,40,44,48,149,153,157,161,165,169" +channel5dfs="36,40,44,48,52,56,60,64,100,104,104,112,116,132,136,140,144,149,153,157,161,165,169" + +absolute() { + num=$1 + if [ "$num" -lt 0 ]; then + num=$((-num)) + fi +} + +loadconfig() { + X=$(uci -q get wireless.wmesh.device) + uci set mesh.radio.radionumber=$(echo ${X#radio}) + + uci set mesh.radio.dedicated=$(uci -q get wireless.default_$X.disabled) + + chanwidth=$(uci -q get wireless.$X.htmode) + case $chanwidth in + "HT20" ) + chanwidth=0 + ;; + "HT40" ) + chanwidth=1 + ;; + "VHT80" ) + chanwidth=2 + ;; + "VHT160" ) + chanwidth=2 + ;; + esac + uci set mesh.radio.channelwidth=$chanwidth + + chan=$(uci -q get wireless.$X.channel) + if [ $chan -lt 15 ]; then + uci set mesh.radio.channellist=0 + uci set mesh.radio.channelindex=$((${chan}-1)) + else + dfs=$(uci -q get wireless.$X.usedfs) + if [ -z $dfs ]; then + dfs=1 + uci set mesh.radio.usedfs=1 + else + uci set mesh.radio.usedfs=$dfs + fi + if [ $dfs -eq 0 ]; then + uci set mesh.radio.channellist=1 + clist=$channel5 + else + uci set mesh.radio.channellist=2 + clist=$channel5dfs + fi + cindex=1 + while [ true ] + do + chan=$(echo "$clist" | cut -d, -f$cindex) + if [ $chan -eq $channel ]; then + uci set mesh.radio.channelindex=$((${cindex}-1)) + break + fi + cindex=$((${cindex}+1)) + done + fi + + enc=$(uci -q get wireless.wmesh.encryption) + if [ $enc = "sae" ]; then + uci set mesh.network.netencrypted=1 + uci set mesh.network.netpassword=$(uci -q get wireless.wmesh.key) + else + uci set mesh.network.netencrypted=0 + uci set mesh.network.netpassword="password" + fi + + uci set mesh.network.networkid=$(uci -q get wireless.wmesh.mesh_id) + + snr=$(uci -q get wireless.default_$X.ieee80211r) + if [ ! -z $snr ]; then + uci set mesh.roam.signalenable=$snr + uci set mesh.roam.signalid=$(uci -q get wireless.default_$X.mobility_domain) + else + uci set mesh.roam.signalenable=0 + uci set mesh.roam.signalid="abcd" + fi + + uci commit mesh +} + +count_radio() { + local config=$1 + local channel + + uci set wireless.default_radio$count.ieee80211r=$signalenable + uci set wireless.default_radio$count.mobility_domain=$signalid + uci set wireless.default_radio$count.ft_over_ds="1" + uci set wireless.default_radio$count.ft_psk_generate_local="1" + count=$((${count}+1)) + +} + +loadmesh() { + radionum=$(uci -q get mesh.radio.radionumber) + dedicated=$(uci -q get mesh.radio.dedicated) + if [ -z $dedicated ]; then + dedicated="0" + fi + log "default_radio$radionum disabled = $dedicated" + + chanwidth=$(uci -q get mesh.radio.channelwidth) + case $chanwidth in + "0" ) + chanwidth=20 + ;; + "1" ) + chanwidth=40 + ;; + "2" ) + chanwidth=80 + ;; + "3" ) + chanwidth=80 + ;; + esac + cwidth=$(uci -q get wireless.radio$radionum.htmode) + ht=$(echo "$cwidth" | grep "VHT") + if [ ! -z $ht ]; then + cwidth="VHT"$chanwidth + else + cwidth="HT"$chanwidth + fi + log "radio$radionum htmode = $cwidth" + + clist=$(uci -q get mesh.radio.channellist) + cindex=$(uci -q get mesh.radio.channelindex) + cindex=$((${cindex}+1)) + case $clist in + "0" ) + channel=$(echo "$channel2" | cut -d, -f$cindex) + ;; + "1" ) + channel=$(echo "$channel5" | cut -d, -f$cindex) + ;; + "2" ) + channel=$(echo "$channel5dfs" | cut -d, -f$cindex) + ;; + esac + log "radio$radionum channel = $channel" + + networkid=$(uci -q get mesh.network.networkid) + netencrypted=$(uci -q get mesh.network.netencrypted) + netpassword=$(uci -q get mesh.network.netpassword) + log "mesh_id = $networkid" + log "encryption = $netencrypted key = $netpassword" + + signalenable=$(uci -q get mesh.roam.signalenable) + signalid=$(uci -q get mesh.roam.signalid) + log "roam enable = $signalenable" + log "id = $signalid" + + ipaddr=$(uci -q get network.lan.ipaddr) + + uci set wireless.default_radio$radionum.disabled=$dedicated + uci set wireless.radio$radionum.htmode=$cwidth + uci set wireless.radio$radionum.channel=$channel + + count=0 + config_load wireless + config_foreach count_radio wifi-iface + + uci set wireless.wmesh=wifi-iface + uci set wireless.wmesh.device=radio$radionum + uci set wireless.wmesh.network="mesh" + uci set wireless.wmesh.ifname="if-mesh" + uci set wireless.wmesh.mode="mesh" + uci set wireless.wmesh.mesh_fwding="0" + uci set wireless.wmesh.mesh_id=$networkid + uci set wireless.w.encryption="none" + if [ $netencrypted = "1" ]; then + uci set wireless.wmesh.encryption="sae" + uci set wireless.wmesh.key=$netpassword + fi + uci set wireless.wmesh.mesh_ttl='1' + uci set wireless.wmesh.mcast_rate='24000' + uci set wireless.wmesh.disabled='0' + uci commit wireless + + uci set alfred.alfred.batmanif='bat0' + uci set alfred.alfred.disabled='0' + uci commit alfred + + uci set network.bat0=interface + uci set network.bat0.proto='batadv' + uci set network.bat0.routing_algo='BATMAN_IV' + uci set network.bat0.aggregated_ogms='1' + uci set network.bat0.ap_isolation='0' + uci set network.bat0.bonding='0' + uci set network.bat0.bridge_loop_avoidance='1' + uci set network.bat0.distributed_arp_table='1' + uci set network.bat0.fragmentation='1' + uci set network.bat0.gw_mode='off' + uci set network.bat0.hop_penalty='30' + uci set network.bat0.isolation_mark='0x00000000/0x00000000' + uci set network.bat0.log_level='0' + uci set network.bat0.multicast_mode='1' + uci set network.bat0.multicast_fanout='16' + uci set network.bat0.network_coding='0' + uci set network.bat0.orig_interval='1000' + + uci set network.mesh=interface + uci set network.mesh.proto='batadv_hardif' + uci set network.mesh.master='bat0' + uci set network.mesh.mtu='2304' + uci set network.mesh.throughput_override='0' + + uci set network.bat0_hardif_eth0=interface + uci set network.bat0_hardif_eth0.proto='batadv_hardif' + uci set network.bat0_hardif_eth0.master='bat0' + uci set network.bat0_hardif_eth0.mtu='1536' + uci set network.bat0_hardif_eth0.device='eth0' + + uci set network.bat0_lan=interface + uci set network.bat0_lan.proto='static' + uci set network.bat0_lan.ipaddr=$ipaddr + uci set network.bat0_lan.netmask='255.255.255.0' + uci set network.bat0_lan.ip6assign='60' + uci set network.bat0_lan.device='bat0' + uci commit network +} + +cmd=$1 +if [ -z $cmd ]; then + WW=$(uci get wireless.wmesh) + if [ -z $WW ]; then + loadmesh + reboot -f + else + loadconfig + /usr/lib/mesh/ping.sh & + fi +else + loadmesh +fi + +return diff --git a/rooter/0mesh/mesh-mesh/files/usr/lib/mesh/ping.sh b/rooter/0mesh/mesh-mesh/files/usr/lib/mesh/ping.sh new file mode 100644 index 0000000..c29fbec --- /dev/null +++ b/rooter/0mesh/mesh-mesh/files/usr/lib/mesh/ping.sh @@ -0,0 +1,34 @@ +#!/bin/sh +. /lib/functions.sh + +pinging() { + PING=0 + RETURN_CODE_1=$(curl -m 10 -s -o /dev/null -w "%{http_code}" http://www.google.com/) + RETURN_CODE_2=$(curl -m 10 -s -o /dev/null -w "%{http_code}" http://www.example.org/) + RETURN_CODE_3=$(curl -m 10 -s -o /dev/null -w "%{http_code}" https://github.com) + + if [[ "$RETURN_CODE_1" != "200" && "$RETURN_CODE_2" != "200" && "$RETURN_CODE_3" != "200" ]]; then + PING=1 + fi +} + +gateway() { + mode=$1 +# batman-adv gateway handling (DHCP mangling) + [ "$(uci -q get batman-adv.bat0.gw_mode)" == "client" ] || return + if grep -q "^=>" /sys/kernel/debug/batman_adv/bat0/gateways ; then + BATTYPE=gw BATACTION=$mode /etc/hotplug.d/net/99-batman-gw + fi +} + +while true ; do + sleep 20 + pinging + if [ $PING -eq 1 ]; then + gateway add + batctl gw_mode client + else + gateway del + batctl gw_mode server 10000 + fi +done \ No newline at end of file diff --git a/rooter/0mesh/mesh-mesh/files/usr/lib/mesh/radio.sh b/rooter/0mesh/mesh-mesh/files/usr/lib/mesh/radio.sh new file mode 100644 index 0000000..0ba8076 --- /dev/null +++ b/rooter/0mesh/mesh-mesh/files/usr/lib/mesh/radio.sh @@ -0,0 +1,78 @@ +#!/bin/sh +. /lib/functions.sh + +log() { + logger -t "Radio" "$@" +} + +count_radio() { + local config=$1 + local channel + + config_get channel $1 channel + count=$((${count}+1)) +} + +do_radio() { + local config=$1 + local channel + + config_get channel $1 channel + rn=${config#radio} + freq="1" + if [ $channel -lt 15 ]; then + freq="0" + fi + iwin=$(iw phy phy$rn info) + hw=0 + hwt=$(echo "$iwin" | grep 'short GI for 40 MHz') + if [ ! -z "$hwt" ]; then + hw=1 + fi + hwt=$(echo "$iwin" | grep 'short GI (80 MHz)') + if [ ! -z "$hwt" ]; then + hw=2 + fi + hwt=$(echo "$iwin" | grep 'short GI (160') + if [ ! -z "$hwt" ]; then + hw=3 + fi + echo "$freq|$rn|$hw" >> /tmp/radiolist +} + +count=0 +rm -f /tmp/radiolist +config_load wireless +config_foreach count_radio wifi-device +if [ $count -gt 0 ]; then + echo "$count" > /tmp/radiolist + config_foreach do_radio wifi-device +fi + +CF1=$(uci -q get mesh.radio.radionumber) +CF2=$(uci -q get mesh.radio.channelindex) +CF3=$(uci -q get mesh.radio.channellist) +CF4=$(uci -q get mesh.radio.channelwidth) +CF5=$(uci -q get mesh.radio.usedfs) +CF6=$(uci -q get mesh.radio.dedicated) +echo "$CF1" >> /tmp/radiolist +echo "$CF2" >> /tmp/radiolist +echo "$CF3" >> /tmp/radiolist +echo "$CF4" >> /tmp/radiolist +echo "$CF5" >> /tmp/radiolist +echo "$CF6" >> /tmp/radiolist + +CF1=$(uci -q get mesh.network.networkid) +CF2=$(uci -q get mesh.network.netencrypted) +CF3=$(uci -q get mesh.network.netpassword) +echo "$CF1" >> /tmp/radiolist +echo "$CF2" >> /tmp/radiolist +echo "$CF3" >> /tmp/radiolist + +CF1=$(uci -q get mesh.roam.signalenable) +CF2=$(uci -q get mesh.roam.signalid) +echo "$CF1" >> /tmp/radiolist +echo "$CF2" >> /tmp/radiolist + + + diff --git a/rooter/0mesh/mesh-mesh/files/usr/lib/mesh/save.sh b/rooter/0mesh/mesh-mesh/files/usr/lib/mesh/save.sh new file mode 100644 index 0000000..d050c7d --- /dev/null +++ b/rooter/0mesh/mesh-mesh/files/usr/lib/mesh/save.sh @@ -0,0 +1,25 @@ +#!/bin/sh +. /lib/functions.sh + +log() { + logger -t "Save" "$@" +} + +state=$1 + +state=$(echo "$state" | tr "|" ",") +uci set mesh.radio.radionumber=$(echo "$state" | cut -d, -f1) +uci set mesh.radio.channelindex=$(echo "$state" | cut -d, -f2) +uci set mesh.radio.channellist=$(echo "$state" | cut -d, -f3) +uci set mesh.radio.usedfs=$(echo "$state" | cut -d, -f4) +uci set mesh.radio.channelwidth=$(echo "$state" | cut -d, -f5) +uci set mesh.radio.dedicated=$(echo "$state" | cut -d, -f6) + +uci set mesh.network.networkid=$(echo "$state" | cut -d, -f7) +uci set mesh.network.netencrypted=$(echo "$state" | cut -d, -f8) +uci set mesh.network.netpassword=$(echo "$state" | cut -d, -f9) + +uci set mesh.roam.signalenable=$(echo "$state" | cut -d, -f10) +uci set mesh.roam.signalid=$(echo "$state" | cut -d, -f11) + +uci commit mesh diff --git a/rooter/0mesh/mesh-mesh/files/usr/lib/mesh/savecfg.sh b/rooter/0mesh/mesh-mesh/files/usr/lib/mesh/savecfg.sh new file mode 100644 index 0000000..bd4bf1f --- /dev/null +++ b/rooter/0mesh/mesh-mesh/files/usr/lib/mesh/savecfg.sh @@ -0,0 +1,16 @@ +#!/bin/sh +. /lib/functions.sh + +log() { + logger -t "Save" "$@" +} + +state=$1 + +PKI_DIR="/www" +cd ${PKI_DIR} +mkdir -p package +cd .. +chmod -R 0777 ${PKI_DIR}/package + +echo "$state" > ${PKI_DIR}/package/meshcfg.meshcfg \ No newline at end of file diff --git a/rooter/0mesh/mesh-mesh/files/usr/lib/mesh/startstop.sh b/rooter/0mesh/mesh-mesh/files/usr/lib/mesh/startstop.sh new file mode 100644 index 0000000..2cd290a --- /dev/null +++ b/rooter/0mesh/mesh-mesh/files/usr/lib/mesh/startstop.sh @@ -0,0 +1,8 @@ +#!/bin/sh +. /lib/functions.sh + +log() { + logger -t "Start Mesh" "$@" +} + +/usr/lib/mesh/checker.sh 1 \ No newline at end of file diff --git a/rooter/0mesh/mesh-mesh/files/www/luci-static/resources/dracula/dracula_graffle.js b/rooter/0mesh/mesh-mesh/files/www/luci-static/resources/dracula/dracula_graffle.js new file mode 100644 index 0000000..9832727 --- /dev/null +++ b/rooter/0mesh/mesh-mesh/files/www/luci-static/resources/dracula/dracula_graffle.js @@ -0,0 +1 @@ +Raphael.fn.connection=function(a,b,c){var d=this,e={draw:function(){for(var f=a.getBBox(),g=b.getBBox(),h=0,i=0,j=[{x:f.x+f.width/2,y:f.y-h},{x:f.x+f.width/2,y:f.y+f.height+h},{x:f.x-h,y:f.y+f.height/2},{x:f.x+f.width+h,y:f.y+f.height/2},{x:g.x+g.width/2,y:g.y-i},{x:g.x+g.width/2,y:g.y+g.height+i},{x:g.x-i,y:g.y+g.height/2},{x:g.x+g.width+i,y:g.y+g.height/2}],k={},l=[],m=0;m<4;m++)for(var n=4;n<8;n++){var o=Math.abs(j[m].x-j[n].x),p=Math.abs(j[m].y-j[n].y);(m==n-4||(3!=m&&6!=n||j[m].xj[n].x)&&(0!=m&&5!=n||j[m].y>j[n].y)&&(1!=m&&4!=n||j[m].ye.width-20?c-e.width+20:0),g=a.clientY-(d<20?d-20:d>e.height-20?d-e.height+20:0);e.isDrag.set.translate(f-Math.round(e.isDrag.dx),g-Math.round(e.isDrag.dy));for(var h in e.graph.edges)e.graph.edges[h].connection&&e.graph.edges[h].connection.draw();e.isDrag.dx=f,e.isDrag.dy=g}},f.onmouseup=function(){e.isDrag&&e.isDrag.set.animate({"fill-opacity":.6},500),e.isDrag=!1},this.draw()},Graph.Renderer.Raphael.prototype={translate:function(a){return[(a[0]-this.graph.layoutMinX)*this.factorX+this.radius,(a[1]-this.graph.layoutMinY)*this.factorY+this.radius]},rotate:function(a,b,c){var d=b*Math.cos(c),e=b*Math.sin(c);return[a[0]+d,a[1]+e]},draw:function(){this.factorX=(this.width-2*this.radius)/(this.graph.layoutMaxX-this.graph.layoutMinX),this.factorY=(this.height-2*this.radius)/(this.graph.layoutMaxY-this.graph.layoutMinY);for(a in this.graph.nodes)this.drawNode(this.graph.nodes[a]);for(var a=0;ab&&(b=e),ed&&(d=f),fk&&(i=k),i<-k&&(i=-k),j>k&&(j=k),j<-k&&(j=-k),h.layoutPosX+=i,h.layoutPosY+=j,h.layoutForceX=0,h.layoutForceY=0}},layoutRepulsive:function(a,b){if("undefined"!=typeof a&&"undefined"!=typeof b){var c=b.layoutPosX-a.layoutPosX,d=b.layoutPosY-a.layoutPosY,e=c*c+d*d;if(e<.01){c=.1*Math.random()+.1,d=.1*Math.random()+.1;var e=c*c+d*d}var f=Math.sqrt(e);if(fthis.maxRepulsiveForceDistance&&(g=this.maxRepulsiveForceDistance,f=g*g);var h=(f-this.k*this.k)/this.k;void 0==a.attraction&&(a.attraction=1),h*=.5*Math.log(a.attraction)+1,c.layoutForceX-=h*d/g,c.layoutForceY-=h*e/g,b.layoutForceX+=h*d/g,b.layoutForceY+=h*e/g}},Graph.Layout.Ordered=function(a,b){this.graph=a,this.order=b,this.layout()},Graph.Layout.Ordered.prototype={layout:function(){this.layoutPrepare(),this.layoutCalcBounds()},layoutPrepare:function(a){for(i in this.graph.nodes){var b=this.graph.nodes[i];b.layoutPosX=0,b.layoutPosY=0}var c=0;for(i in this.order){var b=this.order[i];b.layoutPosX=c,b.layoutPosY=Math.random(),c++}},layoutCalcBounds:function(){var a=1/0,b=-(1/0),c=1/0,d=-(1/0);for(i in this.graph.nodes){var e=this.graph.nodes[i].layoutPosX,f=this.graph.nodes[i].layoutPosY;e>b&&(b=e),ed&&(d=f),f

      ";if(ag.childNodes[m]!=2){return null;}}an.svg=!(an.vml=an.type=="VML");aT[aY]=an[aY];an._id=0;an._oid=0;an.fn={};an.is=function(e,d){d=aZ.call(d);return((d=="object"||d=="undefined")&&typeof e==d)||(e==null&&d=="null")||aZ.call(aw.call(e).slice(8,-1))==d;};an.setWindow=function(d){au=d;L=au.document;};var aD=function(e){if(an.vml){var d=/^\s+|\s+$/g;aD=aj(function(R){var S;R=(R+at)[aP](d,at);try{var a0=new ActiveXObject("htmlfile");a0.write("");a0.close();S=a0.body;}catch(a2){S=createPopup().document.body;}var i=S.createTextRange();try{S.style.color=R;var a1=i.queryCommandValue("ForeColor");a1=((a1&255)<<16)|(a1&65280)|((a1&16711680)>>>16);return"#"+("000000"+a1[aA](16)).slice(-6);}catch(a2){return"none";}});}else{var E=L.createElement("i");E.title="Rapha\xebl Colour Picker";E.style.display="none";L.body[aL](E);aD=aj(function(i){E.style.color=i;return L.defaultView.getComputedStyle(E,at).getPropertyValue("color");});}return aD(e);};an.hsb2rgb=aj(function(a3,a1,a7){if(an.is(a3,"object")&&"h" in a3&&"s" in a3&&"b" in a3){a7=a3.b;a1=a3.s;a3=a3.h;}var R,S,a8;if(a7==0){return{r:0,g:0,b:0,hex:"#000"};}if(a3>1||a1>1||a7>1){a3/=255;a1/=255;a7/=255;}var a0=~~(a3*6),a4=(a3*6)-a0,E=a7*(1-a1),e=a7*(1-(a1*a4)),a9=a7*(1-(a1*(1-a4)));R=[a7,e,E,E,a9,a7,a7][a0];S=[a9,a7,a7,e,E,E,a9][a0];a8=[E,E,a9,a7,a7,e,E][a0];R*=255;S*=255;a8*=255;var a5={r:R,g:S,b:a8},d=(~~R)[aA](16),a2=(~~S)[aA](16),a6=(~~a8)[aA](16);d=d[aP](aU,"0");a2=a2[aP](aU,"0");a6=a6[aP](aU,"0");a5.hex="#"+d+a2+a6;return a5;},an);an.rgb2hsb=aj(function(d,e,a1){if(an.is(d,"object")&&"r" in d&&"g" in d&&"b" in d){a1=d.b;e=d.g;d=d.r;}if(an.is(d,"string")){var a3=an.getRGB(d);d=a3.r;e=a3.g;a1=a3.b;}if(d>1||e>1||a1>1){d/=255;e/=255;a1/=255;}var a0=g(d,e,a1),i=aI(d,e,a1),R,E,S=a0;if(i==a0){return{h:0,s:0,b:a0};}else{var a2=(a0-i);E=a2/a0;if(d==a0){R=(e-a1)/a2;}else{if(e==a0){R=2+((a1-d)/a2);}else{R=4+((d-e)/a2);}}R/=6;R<0&&R++;R>1&&R--;}return{h:R,s:E,b:S};},an);var aE=/,?([achlmqrstvxz]),?/gi;an._path2string=function(){return this.join(",")[aP](aE,"$1");};function aj(E,e,d){function i(){var R=Array[aY].slice.call(arguments,0),a0=R[az]("\u25ba"),S=i.cache=i.cache||{},a1=i.count=i.count||[];if(S[Q](a0)){return d?d(S[a0]):S[a0];}a1[m]>=1000&&delete S[a1.shift()];a1[f](a0);S[a0]=E[aW](e,R);return d?d(S[a0]):S[a0];}return i;}an.getRGB=aj(function(d){if(!d||!!((d=d+at).indexOf("-")+1)){return{r:-1,g:-1,b:-1,hex:"none",error:1};}if(d=="none"){return{r:-1,g:-1,b:-1,hex:"none"};}!(({hs:1,rg:1})[Q](d.substring(0,2))||d.charAt()=="#")&&(d=aD(d));var S,i,E,a2,a3,a0=d.match(x);if(a0){if(a0[2]){a2=G(a0[2].substring(5),16);E=G(a0[2].substring(3,5),16);i=G(a0[2].substring(1,3),16);}if(a0[3]){a2=G((a3=a0[3].charAt(3))+a3,16);E=G((a3=a0[3].charAt(2))+a3,16);i=G((a3=a0[3].charAt(1))+a3,16);}if(a0[4]){a0=a0[4][z](/\s*,\s*/);i=W(a0[0]);E=W(a0[1]);a2=W(a0[2]);}if(a0[5]){a0=a0[5][z](/\s*,\s*/);i=W(a0[0])*2.55;E=W(a0[1])*2.55;a2=W(a0[2])*2.55;}if(a0[6]){a0=a0[6][z](/\s*,\s*/);i=W(a0[0]);E=W(a0[1]);a2=W(a0[2]);return an.hsb2rgb(i,E,a2);}if(a0[7]){a0=a0[7][z](/\s*,\s*/);i=W(a0[0])*2.55;E=W(a0[1])*2.55;a2=W(a0[2])*2.55;return an.hsb2rgb(i,E,a2);}a0={r:i,g:E,b:a2};var e=(~~i)[aA](16),R=(~~E)[aA](16),a1=(~~a2)[aA](16);e=e[aP](aU,"0");R=R[aP](aU,"0");a1=a1[aP](aU,"0");a0.hex="#"+e+R+a1;return a0;}return{r:-1,g:-1,b:-1,hex:"none",error:1};},an);an.getColor=function(e){var i=this.getColor.start=this.getColor.start||{h:0,s:1,b:e||0.75},d=this.hsb2rgb(i.h,i.s,i.b);i.h+=0.075;if(i.h>1){i.h=0;i.s-=0.2;i.s<=0&&(this.getColor.start={h:0,s:1,b:i.b});}return d.hex;};an.getColor.reset=function(){delete this.start;};an.parsePathString=aj(function(d){if(!d){return null;}var i={a:7,c:6,h:1,l:2,m:2,q:4,s:4,t:2,v:1,z:0},e=[];if(an.is(d,"array")&&an.is(d[0],"array")){e=av(d);}if(!e[m]){(d+at)[aP](/([achlmqstvz])[\s,]*((-?\d*\.?\d*(?:e[-+]?\d+)?\s*,?\s*)+)/ig,function(R,E,a1){var a0=[],S=aZ.call(E);a1[aP](/(-?\d*\.?\d*(?:e[-+]?\d+)?)\s*,?\s*/ig,function(a3,a2){a2&&a0[f](+a2);});while(a0[m]>=i[S]){e[f]([E][aS](a0.splice(0,i[S])));if(!i[S]){break;}}});}e[aA]=an._path2string;return e;});an.findDotsAtSegment=function(e,d,be,bc,a0,R,a2,a1,a8){var a6=1-a8,a5=aM(a6,3)*e+aM(a6,2)*3*a8*be+a6*3*a8*a8*a0+aM(a8,3)*a2,a3=aM(a6,3)*d+aM(a6,2)*3*a8*bc+a6*3*a8*a8*R+aM(a8,3)*a1,ba=e+2*a8*(be-e)+a8*a8*(a0-2*be+e),a9=d+2*a8*(bc-d)+a8*a8*(R-2*bc+d),bd=be+2*a8*(a0-be)+a8*a8*(a2-2*a0+be),bb=bc+2*a8*(R-bc)+a8*a8*(a1-2*R+bc),a7=(1-a8)*e+a8*be,a4=(1-a8)*d+a8*bc,E=(1-a8)*a0+a8*a2,i=(1-a8)*R+a8*a1,S=(90-ab.atan((ba-bd)/(a9-bb))*180/ab.PI);(ba>bd||a91){bi=ab.sqrt(by)*bi;bg=ab.sqrt(by)*bg;}var E=bi*bi,br=bg*bg,bt=(a4==S?-1:1)*ab.sqrt(ab.abs((E*br-E*bn*bn-br*bo*bo)/(E*bn*bn+br*bo*bo))),bd=bt*bi*bn/bg+(a9+a8)/2,bc=bt*-bg*bo/bi+(bE+bD)/2,a3=ab.asin(((bE-bc)/bg).toFixed(7)),a2=ab.asin(((bD-bc)/bg).toFixed(7));a3=a9a2){a3=a3-R*2;}if(!S&&a2>a3){a2=a2-R*2;}}else{a3=bb[0];a2=bb[1];bd=bb[2];bc=bb[3];}var a7=a2-a3;if(ab.abs(a7)>bf){var be=a2,bh=a8,a5=bD;a2=a3+bf*(S&&a2>a3?1:-1);a8=bd+bi*ab.cos(a2);bD=bc+bg*ab.sin(a2);bm=K(a8,bD,bi,bg,ba,0,S,bh,a5,[a2,be,bd,bc]);}a7=a2-a3;var a1=ab.cos(a3),bC=ab.sin(a3),a0=ab.cos(a2),bB=ab.sin(a2),bp=ab.tan(a7/4),bs=4/3*bi*bp,bq=4/3*bg*bp,bz=[a9,bE],bx=[a9+bs*bC,bE-bq*a1],bw=[a8+bs*bB,bD-bq*a0],bu=[a8,bD];bx[0]=2*bz[0]-bx[0];bx[1]=2*bz[1]-bx[1];if(bb){return[bx,bw,bu][aS](bm);}else{bm=[bx,bw,bu][aS](bm)[az]()[z](",");var bk=[];for(var bv=0,bl=bm[m];bv1000000000000&&(a0=0.5);ab.abs(S)>1000000000000&&(S=0.5);if(a0>0&&a0<1){e=M(i,d,R,E,a9,a8,a5,a2,a0);a6[f](e.x);a3[f](e.y);}if(S>0&&S<1){e=M(i,d,R,E,a9,a8,a5,a2,S);a6[f](e.x);a3[f](e.y);}a7=(a8-2*E+d)-(a2-2*a8+E);a4=2*(E-d)-2*(a8-E);a1=d-E;a0=(-a4+ab.sqrt(a4*a4-4*a7*a1))/2/a7;S=(-a4-ab.sqrt(a4*a4-4*a7*a1))/2/a7;ab.abs(a0)>1000000000000&&(a0=0.5);ab.abs(S)>1000000000000&&(S=0.5);if(a0>0&&a0<1){e=M(i,d,R,E,a9,a8,a5,a2,a0);a6[f](e.x);a3[f](e.y);}if(S>0&&S<1){e=M(i,d,R,E,a9,a8,a5,a2,S);a6[f](e.x);a3[f](e.y);}return{min:{x:aI[aW](0,a6),y:aI[aW](0,a3)},max:{x:g[aW](0,a6),y:g[aW](0,a3)}};}),H=aj(function(a9,a4){var R=r(a9),a5=a4&&r(a4),a6={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},d={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},a0=function(ba,bb){var i,bc;if(!ba){return["C",bb.x,bb.y,bb.x,bb.y,bb.x,bb.y];}!(ba[0] in {T:1,Q:1})&&(bb.qx=bb.qy=null);switch(ba[0]){case"M":bb.X=ba[1];bb.Y=ba[2];break;case"A":ba=["C"][aS](K[aW](0,[bb.x,bb.y][aS](ba.slice(1))));break;case"S":i=bb.x+(bb.x-(bb.bx||bb.x));bc=bb.y+(bb.y-(bb.by||bb.y));ba=["C",i,bc][aS](ba.slice(1));break;case"T":bb.qx=bb.x+(bb.x-(bb.qx||bb.x));bb.qy=bb.y+(bb.y-(bb.qy||bb.y));ba=["C"][aS](aK(bb.x,bb.y,bb.qx,bb.qy,ba[1],ba[2]));break;case"Q":bb.qx=ba[1];bb.qy=ba[2];ba=["C"][aS](aK(bb.x,bb.y,ba[1],ba[2],ba[3],ba[4]));break;case"L":ba=["C"][aS](aX(bb.x,bb.y,ba[1],ba[2]));break;case"H":ba=["C"][aS](aX(bb.x,bb.y,ba[1],bb.y));break;case"V":ba=["C"][aS](aX(bb.x,bb.y,bb.x,ba[1]));break;case"Z":ba=["C"][aS](aX(bb.x,bb.y,bb.X,bb.Y));break;}return ba;},e=function(ba,bb){if(ba[bb][m]>7){ba[bb].shift();var bc=ba[bb];while(bc[m]){ba.splice(bb++,0,["C"][aS](bc.splice(0,6)));}ba.splice(bb,1);a7=g(R[m],a5&&a5[m]||0);}},E=function(be,bd,bb,ba,bc){if(be&&bd&&be[bc][0]=="M"&&bd[bc][0]!="M"){bd.splice(bc,0,["M",ba.x,ba.y]);bb.bx=0;bb.by=0;bb.x=be[bc][1];bb.y=be[bc][2];a7=g(R[m],a5&&a5[m]||0);}};for(var a2=0,a7=g(R[m],a5&&a5[m]||0);a23){return{container:1,x:arguments[0],y:arguments[1],width:arguments[2],height:arguments[3]};}}},aG=function(d,i){var e=this;for(var E in i){if(i[Q](E)&&!(E in d)){switch(typeof i[E]){case"function":(function(R){d[E]=d===e?R:function(){return R[aW](e,arguments);};})(i[E]);break;case"object":d[E]=d[E]||{};aG.call(this,d[E],i[E]);break;default:d[E]=i[E];break;}}}},ak=function(d,e){d==e.top&&(e.top=d.prev);d==e.bottom&&(e.bottom=d.next);d.next&&(d.next.prev=d.prev);d.prev&&(d.prev.next=d.next);},Y=function(d,e){if(e.top===d){return;}ak(d,e);d.next=null;d.prev=e.top;e.top.next=d;e.top=d;},k=function(d,e){if(e.bottom===d){return;}ak(d,e);d.next=e.bottom;d.prev=null;e.bottom.prev=d;e.bottom=d;},A=function(e,d,i){ak(e,i);d==i.top&&(i.top=e);d.next&&(d.next.prev=e);e.next=d.next;e.prev=d;d.next=e;},aq=function(e,d,i){ak(e,i);d==i.bottom&&(i.bottom=e);d.prev&&(d.prev.next=e);e.prev=d.prev;d.prev=e;e.next=d;},s=function(d){return function(){throw new Error("Rapha\xebl: you are calling to method \u201c"+d+"\u201d of removed object");};},ar=/^r(?:\(([^,]+?)\s*,\s*([^\)]+?)\))?/;if(an.svg){aT[aY].svgns="http://www.w3.org/2000/svg";aT[aY].xlink="http://www.w3.org/1999/xlink";var O=function(d){return +d+(~~d===d)*0.5;},V=function(S){for(var e=0,E=S[m];e0.5)*2-1);aM(a1-0.5,2)+aM(S-0.5,2)>0.25&&(S=ab.sqrt(0.25-aM(a1-0.5,2))*ba+0.5)&&S!=0.5&&(S=S.toFixed(5)-0.00001*ba);}return at;});a7=a7[z](/\s*\-\s*/);if(a4=="linear"){var a0=a7.shift();a0=-W(a0);if(isNaN(a0)){return null;}var R=[0,0,ab.cos(a0*ab.PI/180),ab.sin(a0*ab.PI/180)],a6=1/(g(ab.abs(R[2]),ab.abs(R[3]))||1);R[2]*=a6;R[3]*=a6;if(R[2]<0){R[0]=-R[2];R[2]=0;}if(R[3]<0){R[1]=-R[3];R[3]=0;}}var a3=p(a7);if(!a3){return null;}var e=aJ(a4+"Gradient");e.id="r"+(an._id++)[aA](36);aJ(e,a4=="radial"?{fx:a1,fy:S}:{x1:R[0],y1:R[1],x2:R[2],y2:R[3]});d.defs[aL](e);for(var a2=0,a8=a3[m];a2a1.height)&&(a1.height=a0.y+a0.height-a1.y);(a0.x+a0.width-a1.x>a1.width)&&(a1.width=a0.x+a0.width-a1.x);}}E&&this.hide();return a1;};ax[aY].attr=function(){if(this.removed){return this;}if(arguments[m]==0){var R={};for(var E in this.attrs){if(this.attrs[Q](E)){R[E]=this.attrs[E];}}this._.rt.deg&&(R.rotation=this.rotate());(this._.sx!=1||this._.sy!=1)&&(R.scale=this.scale());R.gradient&&R.fill=="none"&&(R.fill=R.gradient)&&delete R.gradient;return R;}if(arguments[m]==1&&an.is(arguments[0],"string")){if(arguments[0]=="translation"){return t.call(this);}if(arguments[0]=="rotation"){return this.rotate();}if(arguments[0]=="scale"){return this.scale();}if(arguments[0]=="fill"&&this.attrs.fill=="none"&&this.attrs.gradient){return this.attrs.gradient;}return this.attrs[arguments[0]];}if(arguments[m]==1&&an.is(arguments[0],"array")){var d={};for(var e in arguments[0]){if(arguments[0][Q](e)){d[arguments[0][e]]=this.attrs[arguments[0][e]];}}return d;}if(arguments[m]==2){var S={};S[arguments[0]]=arguments[1];aa(this,S);}else{if(arguments[m]==1&&an.is(arguments[0],"object")){aa(this,arguments[0]);}}return this;};ax[aY].toFront=function(){if(this.removed){return this;}this.node.parentNode[aL](this.node);var d=this.paper;d.top!=this&&Y(this,d);return this;};ax[aY].toBack=function(){if(this.removed){return this;}if(this.node.parentNode.firstChild!=this.node){this.node.parentNode.insertBefore(this.node,this.node.parentNode.firstChild);k(this,this.paper);var d=this.paper;}return this;};ax[aY].insertAfter=function(d){if(this.removed){return this;}var e=d.node;if(e.nextSibling){e.parentNode.insertBefore(this.node,e.nextSibling);}else{e.parentNode[aL](this.node);}A(this,d,this.paper);return this;};ax[aY].insertBefore=function(d){if(this.removed){return this;}var e=d.node;e.parentNode.insertBefore(this.node,e);aq(this,d,this.paper);return this;};var P=function(e,d,S,R){d=O(d);S=O(S);var E=aJ("circle");e.canvas&&e.canvas[aL](E);var i=new ax(E,e);i.attrs={cx:d,cy:S,r:R,fill:"none",stroke:"#000"};i.type="circle";aJ(E,i.attrs);return i;};var aF=function(i,d,a1,e,S,a0){d=O(d);a1=O(a1);var R=aJ("rect");i.canvas&&i.canvas[aL](R);var E=new ax(R,i);E.attrs={x:d,y:a1,width:e,height:S,r:a0||0,rx:a0||0,ry:a0||0,fill:"none",stroke:"#000"};E.type="rect";aJ(R,E.attrs);return E;};var ai=function(e,d,a0,S,R){d=O(d);a0=O(a0);var E=aJ("ellipse");e.canvas&&e.canvas[aL](E);var i=new ax(E,e);i.attrs={cx:d,cy:a0,rx:S,ry:R,fill:"none",stroke:"#000"};i.type="ellipse";aJ(E,i.attrs);return i;};var o=function(i,a0,d,a1,e,S){var R=aJ("image");aJ(R,{x:d,y:a1,width:e,height:S,preserveAspectRatio:"none"});R.setAttributeNS(i.xlink,"href",a0);i.canvas&&i.canvas[aL](R);var E=new ax(R,i);E.attrs={x:d,y:a1,width:e,height:S,src:a0};E.type="image";return E;};var X=function(e,d,S,R){var E=aJ("text");aJ(E,{x:d,y:S,"text-anchor":"middle"});e.canvas&&e.canvas[aL](E);var i=new ax(E,e);i.attrs={x:d,y:S,"text-anchor":"middle",text:R,font:j.font,stroke:"none",fill:"#000"};i.type="text";aa(i,i.attrs);return i;};var aV=function(e,d){this.width=e||this.width;this.height=d||this.height;this.canvas[v]("width",this.width);this.canvas[v]("height",this.height);return this;};var w=function(){var E=ao[aW](null,arguments),i=E&&E.container,e=E.x,a0=E.y,R=E.width,d=E.height;if(!i){throw new Error("SVG container not found.");}var S=aJ("svg");R=R||512;d=d||342;aJ(S,{xmlns:"http://www.w3.org/2000/svg",version:1.1,width:R,height:d});if(i==1){S.style.cssText="position:absolute;left:"+e+"px;top:"+a0+"px";L.body[aL](S);}else{if(i.firstChild){i.insertBefore(S,i.firstChild);}else{i[aL](S);}}i=new aT;i.width=R;i.height=d;i.canvas=S;aG.call(i,i,an.fn);i.clear();return i;};aT[aY].clear=function(){var d=this.canvas;while(d.firstChild){d.removeChild(d.firstChild);}this.bottom=this.top=null;(this.desc=aJ("desc"))[aL](L.createTextNode("Created with Rapha\xebl"));d[aL](this.desc);d[aL](this.defs=aJ("defs"));};aT[aY].remove=function(){this.canvas.parentNode&&this.canvas.parentNode.removeChild(this.canvas);for(var d in this){this[d]=s(d);}};}if(an.vml){var aH=function(a8){var a5=/[ahqstv]/ig,a0=r;(a8+at).match(a5)&&(a0=H);a5=/[clmz]/g;if(a0==r&&!(a8+at).match(a5)){var e={M:"m",L:"l",C:"c",Z:"x",m:"t",l:"r",c:"v",z:"x"},R=/([clmz]),?([^clmz]*)/gi,S=/-?[^,\s-]+/g;var a4=(a8+at)[aP](R,function(a9,bb,i){var ba=[];i[aP](S,function(bc){ba[f](O(bc));});return e[bb]+ba;});return a4;}var a6=a0(a8),E,a4=[],d;for(var a2=0,a7=a6[m];a21&&(e=1);a7.opacity=e;}a8.fill&&(a7.on=true);if(a7.on==null||a8.fill=="none"){a7.on=false;}if(a7.on&&a8.fill){var i=a8.fill.match(c);if(i){a7.src=i[1];a7.type="tile";}else{a7.color=an.getRGB(a8.fill).hex;a7.src=at;a7.type="solid";if(an.getRGB(a8.fill).error&&(bd.type in {circle:1,ellipse:1}||(a8.fill+at).charAt()!="r")&&b(bd,a8.fill)){a9.fill="none";a9.gradient=a8.fill;}}}ba&&a6[aL](a7);var R=(a6.getElementsByTagName("stroke")&&a6.getElementsByTagName("stroke")[0]),bb=false;!R&&(bb=R=ah("stroke"));if((a8.stroke&&a8.stroke!="none")||a8["stroke-width"]||a8["stroke-opacity"]!=null||a8["stroke-dasharray"]||a8["stroke-miterlimit"]||a8["stroke-linejoin"]||a8["stroke-linecap"]){R.on=true;}(a8.stroke=="none"||R.on==null||a8.stroke==0||a8["stroke-width"]==0)&&(R.on=false);R.on&&a8.stroke&&(R.color=an.getRGB(a8.stroke).hex);var e=((+a9["stroke-opacity"]+1||2)-1)*((+a9.opacity+1||2)-1),a4=(W(a8["stroke-width"])||1)*0.75;e<0&&(e=0);e>1&&(e=1);a8["stroke-width"]==null&&(a4=a9["stroke-width"]);a8["stroke-width"]&&(R.weight=a4);a4&&a4<1&&(e*=a4)&&(R.weight=1);R.opacity=e;a8["stroke-linejoin"]&&(R.joinstyle=a8["stroke-linejoin"]||"miter");R.miterlimit=a8["stroke-miterlimit"]||8;a8["stroke-linecap"]&&(R.endcap=a8["stroke-linecap"]=="butt"?"flat":a8["stroke-linecap"]=="square"?"square":"round");if(a8["stroke-dasharray"]){var a5={"-":"shortdash",".":"shortdot","-.":"shortdashdot","-..":"shortdashdotdot",". ":"dot","- ":"dash","--":"longdash","- .":"dashdot","--.":"longdashdot","--..":"longdashdotdot"};R.dashstyle=a5[Q](a8["stroke-dasharray"])?a5[a8["stroke-dasharray"]]:at;}bb&&a6[aL](R);}if(bd.type=="text"){var a0=bd.paper.span.style;a9.font&&(a0.font=a9.font);a9["font-family"]&&(a0.fontFamily=a9["font-family"]);a9["font-size"]&&(a0.fontSize=a9["font-size"]);a9["font-weight"]&&(a0.fontWeight=a9["font-weight"]);a9["font-style"]&&(a0.fontStyle=a9["font-style"]);bd.node.string&&(bd.paper.span.innerHTML=(bd.node.string+at)[aP](/"));bd.W=a9.w=bd.paper.span.offsetWidth;bd.H=a9.h=bd.paper.span.offsetHeight;bd.X=a9.x;bd.Y=a9.y+O(bd.H/2);switch(a9["text-anchor"]){case"start":bd.node.style["v-text-align"]="left";bd.bbx=O(bd.W/2);break;case"end":bd.node.style["v-text-align"]="right";bd.bbx=-O(bd.W/2);break;default:bd.node.style["v-text-align"]="center";break;}}};var b=function(d,a1){d.attrs=d.attrs||{};var a2=d.attrs,a4=d.node.getElementsByTagName("fill"),S="linear",a0=".5 .5";d.attrs.gradient=a1;a1=(a1+at)[aP](ar,function(a6,a7,i){S="radial";if(a7&&i){a7=W(a7);i=W(i);aM(a7-0.5,2)+aM(i-0.5,2)>0.25&&(i=ab.sqrt(0.25-aM(a7-0.5,2))*((i>0.5)*2-1)+0.5);a0=a7+am+i;}return at;});a1=a1[z](/\s*\-\s*/);if(S=="linear"){var e=a1.shift();e=-W(e);if(isNaN(e)){return null;}}var R=p(a1);if(!R){return null;}d=d.shape||d.node;a4=a4[0]||ah("fill");if(R[m]){a4.on=true;a4.method="none";a4.type=(S=="radial")?"gradientradial":"gradient";a4.color=R[0].color;a4.color2=R[R[m]-1].color;var a5=[];for(var E=0,a3=R[m];E');};}catch(af){ah=function(d){return L.createElement("<"+d+' xmlns="urn:schemas-microsoft.com:vml" class="rvml">');};}var w=function(){var i=ao[aW](null,arguments),d=i.container,a2=i.height,a3,e=i.width,a1=i.x,a0=i.y;if(!d){throw new Error("VML container not found.");}var R=new aT,S=R.canvas=L.createElement("div"),E=S.style;e=e||512;a2=a2||342;e==+e&&(e+="px");a2==+a2&&(a2+="px");R.width=1000;R.height=1000;R.coordsize="1000 1000";R.coordorigin="0 0";R.span=L.createElement("span");R.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;";S[aL](R.span);E.cssText=an.format("width:{0};height:{1};position:absolute;clip:rect(0 {0} {1} 0);overflow:hidden",e,a2);if(d==1){L.body[aL](S);E.left=a1+"px";E.top=a0+"px";}else{d.style.width=e;d.style.height=a2;if(d.firstChild){d.insertBefore(S,d.firstChild);}else{d[aL](S);}}aG.call(R,R,an.fn);return R;};aT[aY].clear=function(){this.canvas.innerHTML=at;this.span=L.createElement("span");this.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;";this.canvas[aL](this.span);this.bottom=this.top=null;};aT[aY].remove=function(){this.canvas.parentNode.removeChild(this.canvas);for(var d in this){this[d]=s(d);}};}if((/^Apple|^Google/).test(navigator.vendor)&&!(navigator.userAgent.indexOf("Version/4.0")+1)){aT[aY].safari=function(){var d=this.rect(-99,-99,this.width+99,this.height+99);setTimeout(function(){d.remove();});};}else{aT[aY].safari=function(){};}var ae=(function(){if(L.addEventListener){return function(R,i,e,d){var E=function(S){return e.call(d,S);};R.addEventListener(i,E,false);return function(){R.removeEventListener(i,E,false);return true;};};}else{if(L.attachEvent){return function(S,E,i,e){var R=function(a0){return i.call(e,a0||au.event);};S.attachEvent("on"+E,R);var d=function(){S.detachEvent("on"+E,R);return true;};return d;};}}})();for(var ac=F[m];ac--;){(function(d){ax[aY][d]=function(e){if(an.is(e,"function")){this.events=this.events||[];this.events.push({name:d,f:e,unbind:ae(this.shape||this.node,d,e,this)});}return this;};ax[aY]["un"+d]=function(E){var i=this.events,e=i[m];while(e--){if(i[e].name==d&&i[e].f==E){i[e].unbind();i.splice(e,1);!i.length&&delete this.events;return this;}}return this;};})(F[ac]);}ax[aY].hover=function(e,d){return this.mouseover(e).mouseout(d);};ax[aY].unhover=function(e,d){return this.unmouseover(e).unmouseout(d);};aT[aY].circle=function(d,i,e){return P(this,d||0,i||0,e||0);};aT[aY].rect=function(d,R,e,i,E){return aF(this,d||0,R||0,e||0,i||0,E||0);};aT[aY].ellipse=function(d,E,i,e){return ai(this,d||0,E||0,i||0,e||0);};aT[aY].path=function(d){d&&!an.is(d,"string")&&!an.is(d[0],"array")&&(d+=at);return q(an.format[aW](an,arguments),this);};aT[aY].image=function(E,d,R,e,i){return o(this,E||"about:blank",d||0,R||0,e||0,i||0);};aT[aY].text=function(d,i,e){return X(this,d||0,i||0,e||at);};aT[aY].set=function(d){arguments[m]>1&&(d=Array[aY].splice.call(arguments,0,arguments[m]));return new T(d);};aT[aY].setSize=aV;aT[aY].top=aT[aY].bottom=null;aT[aY].raphael=an;function u(){return this.x+am+this.y;}ax[aY].scale=function(a6,a5,E,e){if(a6==null&&a5==null){return{x:this._.sx,y:this._.sy,toString:u};}a5=a5||a6;!+a5&&(a5=a6);var ba,a8,a9,a7,bm=this.attrs;if(a6!=0){var a4=this.getBBox(),a1=a4.x+a4.width/2,R=a4.y+a4.height/2,bl=a6/this._.sx,bk=a5/this._.sy;E=(+E||E==0)?E:a1;e=(+e||e==0)?e:R;var a3=~~(a6/ab.abs(a6)),a0=~~(a5/ab.abs(a5)),be=this.node.style,bo=E+(a1-E)*bl,bn=e+(R-e)*bk;switch(this.type){case"rect":case"image":var a2=bm.width*a3*bl,bd=bm.height*a0*bk;this.attr({height:bd,r:bm.r*aI(a3*bl,a0*bk),width:a2,x:bo-a2/2,y:bn-bd/2});break;case"circle":case"ellipse":this.attr({rx:bm.rx*a3*bl,ry:bm.ry*a0*bk,r:bm.r*aI(a3*bl,a0*bk),cx:bo,cy:bn});break;case"path":var bg=ad(bm.path),bh=true;for(var bj=0,bc=bg[m];bjS){if(e&&!a8.start){a6=an.findDotsAtSegment(a5,a4,E[1],E[2],E[3],E[4],E[5],E[6],(S-a3)/a1);R+=["C",a6.start.x,a6.start.y,a6.m.x,a6.m.y,a6.x,a6.y];if(a0){return R;}a8.start=R;R=["M",a6.x,a6.y+"C",a6.n.x,a6.n.y,a6.end.x,a6.end.y,E[5],E[6]][az]();a3+=a1;a5=+E[5];a4=+E[6];continue;}if(!d&&!e){a6=an.findDotsAtSegment(a5,a4,E[1],E[2],E[3],E[4],E[5],E[6],(S-a3)/a1);return{x:a6.x,y:a6.y,alpha:a6.alpha};}}a3+=a1;a5=+E[5];a4=+E[6];}R+=E;}a8.end=R;a6=d?a3:e?a8:an.findDotsAtSegment(a5,a4,E[1],E[2],E[3],E[4],E[5],E[6],1);a6.alpha&&(a6={x:a6.x,y:a6.y,alpha:a6.alpha});return a6;};},n=aj(function(E,d,a0,S,a6,a5,a4,a3){var R={x:0,y:0},a2=0;for(var a1=0;a1<1.01;a1+=0.01){var e=M(E,d,a0,S,a6,a5,a4,a3,a1);a1&&(a2+=ab.sqrt(aM(R.x-e.x,2)+aM(R.y-e.y,2)));R=e;}return a2;});var ap=aB(1),C=aB(),J=aB(0,1);ax[aY].getTotalLength=function(){if(this.type!="path"){return;}return ap(this.attrs.path);};ax[aY].getPointAtLength=function(d){if(this.type!="path"){return;}return C(this.attrs.path,d);};ax[aY].getSubpath=function(i,e){if(this.type!="path"){return;}if(ab.abs(this.getTotalLength()-e)<0.000001){return J(this.attrs.path,i).end;}var d=J(this.attrs.path,e,1);return i?J(d,i).end:d;};an.easing_formulas={linear:function(d){return d;},"<":function(d){return aM(d,3);},">":function(d){return aM(d-1,3)+1;},"<>":function(d){d=d*2;if(d<1){return aM(d,3)/2;}d-=2;return(aM(d,3)+2)/2;},backIn:function(e){var d=1.70158;return e*e*((d+1)*e-d);},backOut:function(e){e=e-1;var d=1.70158;return e*e*((d+1)*e+d)+1;},elastic:function(i){if(i==0||i==1){return i;}var e=0.3,d=e/4;return aM(2,-10*i)*ab.sin((i-d)*(2*ab.PI)/e)+1;},bounce:function(E){var e=7.5625,i=2.75,d;if(E<(1/i)){d=e*E*E;}else{if(E<(2/i)){E-=(1.5/i);d=e*E*E+0.75;}else{if(E<(2.5/i)){E-=(2.25/i);d=e*E*E+0.9375;}else{E-=(2.625/i);d=e*E*E+0.984375;}}}return d;}};var I={length:0},aR=function(){var a2=+new Date;for(var be in I){if(be!="length"&&I[Q](be)){var bj=I[be];if(bj.stop){delete I[be];I[m]--;continue;}var a0=a2-bj.start,bb=bj.ms,ba=bj.easing,bf=bj.from,a7=bj.diff,E=bj.to,a6=bj.t,a9=bj.prev||0,a1=bj.el,R=bj.callback,a8={},d;if(a0255?255:(d<0?0:d);},t=function(d,i){if(d==null){return{x:this._.tx,y:this._.ty,toString:u};}this._.tx+=+d;this._.ty+=+i;switch(this.type){case"circle":case"ellipse":this.attr({cx:+d+this.attrs.cx,cy:+i+this.attrs.cy});break;case"rect":case"image":case"text":this.attr({x:+d+this.attrs.x,y:+i+this.attrs.y});break;case"path":var e=ad(this.attrs.path);e[0][1]+=+d;e[0][2]+=+i;this.attr({path:e});break;}return this;};ax[aY].animateWith=function(e,i,d,R,E){I[e.id]&&(i.start=I[e.id].start);return this.animate(i,d,R,E);};ax[aY].animateAlong=ay();ax[aY].animateAlongBack=ay(1);function ay(d){return function(E,i,e,S){var R={back:d};an.is(e,"function")?(S=e):(R.rot=e);E&&E.constructor==ax&&(E=E.attrs.path);E&&(R.along=E);return this.animate(R,i,S);};}ax[aY].onAnimation=function(d){this._run=d||0;return this;};ax[aY].animate=function(be,a5,a4,E){if(an.is(a4,"function")||!a4){E=a4||null;}var a9={},e={},a2={};for(var a6 in be){if(be[Q](a6)){if(Z[Q](a6)){a9[a6]=this.attr(a6);(a9[a6]==null)&&(a9[a6]=j[a6]);e[a6]=be[a6];switch(Z[a6]){case"along":var bc=ap(be[a6]),a7=C(be[a6],bc*!!be.back),R=this.getBBox();a2[a6]=bc/a5;a2.tx=R.x;a2.ty=R.y;a2.sx=a7.x;a2.sy=a7.y;e.rot=be.rot;e.back=be.back;e.len=bc;be.rot&&(a2.r=W(this.rotate())||0);break;case"number":a2[a6]=(e[a6]-a9[a6])/a5;break;case"colour":a9[a6]=an.getRGB(a9[a6]);var a8=an.getRGB(e[a6]);a2[a6]={r:(a8.r-a9[a6].r)/a5,g:(a8.g-a9[a6].g)/a5,b:(a8.b-a9[a6].b)/a5};break;case"path":var S=H(a9[a6],e[a6]);a9[a6]=S[0];var a3=S[1];a2[a6]=[];for(var bb=0,a1=a9[a6][m];bb)[^>]*$|^#([\w-]+)$/,Ua=/^.[^:#\[\.,]*$/,Va=/\S/, +Wa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Xa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,R=Array.prototype.slice,ya=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(a==="body"&&!b){this.context=s;this[0]=s.body;this.selector="body";this.length=1;return this}if(typeof a==="string")if((d=Ta.exec(a))&& +(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Xa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=sa([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return c.merge(this,a)}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return T.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a);return c.merge(this, +a)}else return!b||b.jquery?(b||T).find(a):c(b).find(a);else if(c.isFunction(a))return T.ready(a);if(a.selector!==w){this.selector=a.selector;this.context=a.context}return c.makeArray(a,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){var f=c();c.isArray(a)?ba.apply(f,a):c.merge(f,a);f.prevObject=this;f.context=this.context;if(b=== +"find")f.selector=this.selector+(this.selector?" ":"")+d;else if(b)f.selector=this.selector+"."+b+"("+d+")";return f},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this, +function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,j,i,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b
      a"; +var e=d.getElementsByTagName("*"),j=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!j)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(j.getAttribute("style")),hrefNormalized:j.getAttribute("href")==="/a",opacity:/^0.55$/.test(j.style.opacity),cssFloat:!!j.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected, +parentNode:d.removeChild(d.appendChild(s.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(i){}a.insertBefore(b,a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}try{delete b.test}catch(o){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function k(){c.support.noCloneEvent= +false;d.detachEvent("onclick",k)});d.cloneNode(true).fireEvent("onclick")}d=s.createElement("div");d.innerHTML="";a=s.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var k=s.createElement("div");k.style.width=k.style.paddingLeft="1px";s.body.appendChild(k);c.boxModel=c.support.boxModel=k.offsetWidth===2;s.body.removeChild(k).style.display="none"});a=function(k){var n= +s.createElement("div");k="on"+k;var r=k in n;if(!r){n.setAttribute(k,"return;");r=typeof n[k]==="function"}return r};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=j=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ya=0,za={};c.extend({cache:{},expando:G,noData:{embed:true,object:true, +applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var f=a[G],e=c.cache;if(!f&&typeof b==="string"&&d===w)return null;f||(f=++Ya);if(typeof b==="object"){a[G]=f;e[f]=c.extend(true,{},b)}else if(!e[f]){a[G]=f;e[f]={}}a=e[f];if(d!==w)a[b]=d;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{if(c.support.deleteExpando)delete a[c.expando]; +else a.removeAttribute&&a.removeAttribute(c.expando);delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this, +a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b=== +w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var Aa=/[\n\t]/g,ca=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|input|object|select|textarea)/i, +cb=/^(a|area)$/i,Ba=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(n){var r=c(this);r.addClass(a.call(this,n,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var j=b?d:0;for(d=b?d+1:e.length;j=0;else if(c.nodeName(this,"select")){var u=c.makeArray(r);c("option",this).each(function(){this.selected= +c.inArray(c(this).val(),u)>=0});if(!u.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var j=$a.test(b);if(b in a&&f&&!j){if(e){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed"); +a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&j?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var O=/\.(.*)$/,db=function(a){return a.replace(/[^\w\s\.\|`]/g, +function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;var e,j;if(d.handler){e=d;d=e.handler}if(!d.guid)d.guid=c.guid++;if(j=c.data(a)){var i=j.events=j.events||{},o=j.handle;if(!o)j.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,arguments):w};o.elem=a;b=b.split(" ");for(var k,n=0,r;k=b[n++];){j=e?c.extend({},e):{handler:d,data:f};if(k.indexOf(".")>-1){r=k.split("."); +k=r.shift();j.namespace=r.slice(0).sort().join(".")}else{r=[];j.namespace=""}j.type=k;j.guid=d.guid;var u=i[k],z=c.event.special[k]||{};if(!u){u=i[k]=[];if(!z.setup||z.setup.call(a,f,r,o)===false)if(a.addEventListener)a.addEventListener(k,o,false);else a.attachEvent&&a.attachEvent("on"+k,o)}if(z.add){z.add.call(a,j);if(!j.handler.guid)j.handler.guid=d.guid}u.push(j);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){var e,j=0,i,o,k,n,r,u,z=c.data(a), +C=z&&z.events;if(z&&C){if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(e in C)c.event.remove(a,e+b)}else{for(b=b.split(" ");e=b[j++];){n=e;i=e.indexOf(".")<0;o=[];if(!i){o=e.split(".");e=o.shift();k=new RegExp("(^|\\.)"+c.map(o.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(r=C[e])if(d){n=c.event.special[e]||{};for(B=f||0;B=0){a.type= +e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(j){}if(!a.isPropagationStopped()&& +f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){f=a.target;var i,o=c.nodeName(f,"a")&&e==="click",k=c.event.special[e]||{};if((!k._default||k._default.call(d,a)===false)&&!o&&!(f&&f.nodeName&&c.noData[f.nodeName.toLowerCase()])){try{if(f[e]){if(i=f["on"+e])f["on"+e]=null;c.event.triggered=true;f[e]()}}catch(n){}if(i)f["on"+e]=i;c.event.triggered=false}}},handle:function(a){var b,d,f,e;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive; +if(!b){d=a.type.split(".");a.type=d.shift();f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}e=c.data(this,"events");d=e[a.type];if(e&&d){d=d.slice(0);e=0;for(var j=d.length;e-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},fa=function(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Fa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data", +e);if(!(f===w||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:fa,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return fa.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return fa.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a, +"_change_data",Fa(a))}},setup:function(){if(this.type==="file")return false;for(var a in ea)c.event.add(this,a+".specialChange",ea[a]);return da.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return da.test(this.nodeName)}};ea=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a, +d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var j in d)this[b](j,f,d[j],e);return this}if(c.isFunction(f)){e=f;f=w}var i=b==="one"?c.proxy(e,function(k){c(this).unbind(k,i);return e.apply(this,arguments)}):e;if(d==="unload"&&b!=="one")this.one(d,f,e);else{j=0;for(var o=this.length;j0){y=t;break}}t=t[g]}m[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, +e=0,j=Object.prototype.toString,i=false,o=true;[0,0].sort(function(){o=false;return 0});var k=function(g,h,l,m){l=l||[];var q=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return l;for(var p=[],v,t,y,S,H=true,M=x(h),I=g;(f.exec(""),v=f.exec(I))!==null;){I=v[3];p.push(v[1]);if(v[2]){S=v[3];break}}if(p.length>1&&r.exec(g))if(p.length===2&&n.relative[p[0]])t=ga(p[0]+p[1],h);else for(t=n.relative[p[0]]?[h]:k(p.shift(),h);p.length;){g=p.shift();if(n.relative[g])g+=p.shift(); +t=ga(g,t)}else{if(!m&&p.length>1&&h.nodeType===9&&!M&&n.match.ID.test(p[0])&&!n.match.ID.test(p[p.length-1])){v=k.find(p.shift(),h,M);h=v.expr?k.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:p.pop(),set:z(m)}:k.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=v.expr?k.filter(v.expr,v.set):v.set;if(p.length>0)y=z(t);else H=false;for(;p.length;){var D=p.pop();v=D;if(n.relative[D])v=p.pop();else D="";if(v==null)v=h;n.relative[D](y,v,M)}}else y=[]}y||(y=t);y||k.error(D|| +g);if(j.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))l.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&l.push(t[g]);else l.push.apply(l,y);else z(y,l);if(S){k(S,q,l,m);k.uniqueSort(l)}return l};k.uniqueSort=function(g){if(B){i=o;g.sort(B);if(i)for(var h=1;h":function(g,h){var l=typeof h==="string";if(l&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,q=g.length;m=0))l||m.push(v);else if(l)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()}, +CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||m.push.apply(m, +g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,l){return!!k(l[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)}, +text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}}, +setFilters:{first:function(g,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return hl[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h= +h[3];l=0;for(m=h.length;l=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m=== +"="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+)/g,function(g, +h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!=="undefined"&& +q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTML=""; +if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="

      ";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l];h=null}}(); +(function(){var g=s.createElement("div");g.innerHTML="
      ";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPosition(h)&16)}: +function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f0)for(var j=d;j0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,j= +{},i;if(f&&a.length){e=0;for(var o=a.length;e-1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},index:function(a){if(!a||typeof a=== +"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode", +d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")? +a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeType!==1||!c(a).is(d));){a.nodeType=== +1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/"},F={option:[1,""],legend:[1,"
      ","
      "],thead:[1,"","
      "],tr:[2,"","
      "],td:[3,"","
      "],col:[2,"","
      "],area:[1,"",""],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div
      ","
      "];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d= +c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this}, +wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})}, +prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b, +this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild); +return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Ja, +""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length===1){d[b](this[0]); +return this}else{e=0;for(var j=d.length;e0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec(i)||["", +""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]===""&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.push(i);else e= +c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b.events)e[k]? +c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styleFloat",ja= +function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter= +Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a, +"border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f= +a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b= +a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=//gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ka=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!== +"string")return zb.call(this,a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}var j=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(i,o){if(o==="success"||o==="notmodified")j.html(e?c("
      ").append(i.responseText.replace(tb,"")).find(e):i.responseText);d&&j.each(d,[i.responseText,o,i])}});return this}, +serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ub.test(this.nodeName)||vb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), +function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href, +global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&& +e.success.call(k,o,i,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(k,x,i);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),j,i,o,k=a&&a.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(n==="GET")N.test(e.url)||(e.url+=(ka.test(e.url)? +"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||N.test(e.url))){j=e.jsonpCallback||"jsonp"+sb++;if(e.data)e.data=(e.data+"").replace(N,"="+j+"$1");e.url=e.url.replace(N,"="+j+"$1");e.dataType="script";A[j]=A[j]||function(q){o=q;b();d();A[j]=w;try{delete A[j]}catch(p){}z&&z.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache=== +false&&n==="GET"){var r=J(),u=e.url.replace(wb,"$1_="+r+"$2");e.url=u+(u===e.url?(ka.test(e.url)?"&":"?")+"_="+r:"")}if(e.data&&n==="GET")e.url+=(ka.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");r=(r=xb.exec(e.url))&&(r[1]&&r[1]!==location.protocol||r[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&r){var z=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!j){var B= +false;C.onload=C.onreadystatechange=function(){if(!B&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){B=true;b();d();C.onload=C.onreadystatechange=null;z&&C.parentNode&&z.removeChild(C)}}}z.insertBefore(C,z.firstChild);return w}var E=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since", +c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}r||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ga){}if(e.beforeSend&&e.beforeSend.call(k,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",[x,e]);var g=x.onreadystatechange=function(q){if(!x||x.readyState===0||q==="abort"){E|| +d();E=true;if(x)x.onreadystatechange=c.noop}else if(!E&&x&&(x.readyState===4||q==="timeout")){E=true;x.onreadystatechange=c.noop;i=q==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";var p;if(i==="success")try{o=c.httpData(x,e.dataType,e)}catch(v){i="parsererror";p=v}if(i==="success"||i==="notmodified")j||b();else c.handleError(e,x,i,p);d();q==="timeout"&&x.abort();if(e.async)x=null}};try{var h=x.abort;x.abort=function(){x&&h.call(x); +g("abort")}}catch(l){}e.async&&e.timeout>0&&setTimeout(function(){x&&!E&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status=== +1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b=== +"json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(i,o){if(c.isArray(o))c.each(o,function(k,n){b||/\[\]$/.test(i)?f(i,n):d(i+"["+(typeof n==="object"||c.isArray(n)?k:"")+"]",n)});else!b&&o!=null&&typeof o==="object"?c.each(o,function(k,n){d(i+"["+k+"]",n)}):f(i,o)}function f(i,o){o=c.isFunction(o)?o():o;e[e.length]=encodeURIComponent(i)+"="+encodeURIComponent(o)}var e=[];if(b===w)b=c.ajaxSettings.traditional; +if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var j in a)d(j,a[j]);return e.join("&").replace(yb,"+")}});var la={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,W,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();la[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration=== +"number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]|| +c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(j){return e.step(j)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start; +this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now= +this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem, +e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b
      "; +a.insertBefore(b,a.firstChild);d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==j;a.removeChild(b); +c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),j=parseInt(c.curCSS(a,"top",true),10)||0,i=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a, +d,e);d={top:b.top-e.top+j,left:b.left-e.left+i};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top- +f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],j;if(!e)return null;if(f!==w)return this.each(function(){if(j=wa(this))j.scrollTo(!a?f:c(j).scrollLeft(),a?f:c(j).scrollTop());else this[d]=f});else return(j=wa(e))?"pageXOffset"in j?j[a?"pageYOffset": +"pageXOffset"]:c.support.boxModel&&j.document.documentElement[d]||j.document.body[d]:e[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(j){var i=c(this);i[d](f.call(this,j,i[d]()))});return"scrollTo"in +e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window); diff --git a/rooter/0mesh/mesh-mesh/files/www/luci-static/resources/protocol/batadv.js b/rooter/0mesh/mesh-mesh/files/www/luci-static/resources/protocol/batadv.js new file mode 100644 index 0000000..837ba18 --- /dev/null +++ b/rooter/0mesh/mesh-mesh/files/www/luci-static/resources/protocol/batadv.js @@ -0,0 +1,8 @@ +'use strict'; +'require network'; + +return network.registerProtocol('batadv', { + getI18n: function() { + return _('Batman'); + } +}); diff --git a/rooter/0mesh/mesh-mesh/files/www/luci-static/resources/protocol/batadv_hardif.js b/rooter/0mesh/mesh-mesh/files/www/luci-static/resources/protocol/batadv_hardif.js new file mode 100644 index 0000000..545e63d --- /dev/null +++ b/rooter/0mesh/mesh-mesh/files/www/luci-static/resources/protocol/batadv_hardif.js @@ -0,0 +1,8 @@ +'use strict'; +'require network'; + +return network.registerProtocol('batadv_hardif', { + getI18n: function() { + return _('Mesh'); + } +}); diff --git a/rooter/0mesh/mesh-wpad/Makefile b/rooter/0mesh/mesh-wpad/Makefile new file mode 100644 index 0000000..dcb961e --- /dev/null +++ b/rooter/0mesh/mesh-wpad/Makefile @@ -0,0 +1,29 @@ +#Owned by DairyMan@Whirlpool +# +#Copyright GNU act. +include $(TOPDIR)/rules.mk + +PKG_NAME:=mesh-wpad +PKG_VERSION:=1.000 +PKG_RELEASE:=1 + +PKG_MAINTAINER:=Created by DM/makefile by Cobia@whirlpool +include $(INCLUDE_DIR)/package.mk + +define Package/mesh-wpad + SECTION:=utils + CATEGORY:=ROOter + SUBMENU:=Mesh Support + DEPENDS:=+wpad-mesh-openssl + TITLE:=Support for Mesh routing + PKGARCH:=all +endef + +define Package/mesh-wpad/description + Helper scripts to install Meshing +endef + +define Build/Compile +endef + +$(eval $(call BuildPackage,mesh-wpad)) diff --git a/rooter/0optionalapps/bwallocate/files/usr/lib/lua/luci/model/cbi/fullmenu/bwmenu.lua b/rooter/0optionalapps/bwallocate/files/usr/lib/lua/luci/model/cbi/fullmenu/bwmenu.lua index 9fcc8d9..4b4d4ab 100644 --- a/rooter/0optionalapps/bwallocate/files/usr/lib/lua/luci/model/cbi/fullmenu/bwmenu.lua +++ b/rooter/0optionalapps/bwallocate/files/usr/lib/lua/luci/model/cbi/fullmenu/bwmenu.lua @@ -238,7 +238,7 @@ btn.inputtitle = translate("Send Test of Text or Email") btn.inputstyle = "apply" btn:depends("text", "1") function btn.write() - luci.sys.call("/usr/lib/bwmon/dotext.sh &") + luci.sys.call("/usr/lib/bwmon/dotext.sh") end b4 = s:option(DummyValue, "blank", " "); diff --git a/rooter/0optionalapps/bwmon/files/etc/init.d/bwmon b/rooter/0optionalapps/bwmon/files/etc/init.d/bwmon index 0dc2498..925a8ea 100644 --- a/rooter/0optionalapps/bwmon/files/etc/init.d/bwmon +++ b/rooter/0optionalapps/bwmon/files/etc/init.d/bwmon @@ -6,7 +6,7 @@ START=60 start() { WX=$(uci -q get custom.bwallocate.lock) if [ "$WX" = "1" ]; then - uci set bwmon.general.enabled=1 + uci set bwmon.general.enabled=$enable uci commit bwmon fi /usr/lib/bwmon/wrtbwmon.sh & diff --git a/rooter/0optionalapps/bwmon/files/usr/lib/bwmon/amtleft.lua b/rooter/0optionalapps/bwmon/files/usr/lib/bwmon/amtleft.lua index f2f8a17..ee530db 100644 --- a/rooter/0optionalapps/bwmon/files/usr/lib/bwmon/amtleft.lua +++ b/rooter/0optionalapps/bwmon/files/usr/lib/bwmon/amtleft.lua @@ -23,14 +23,8 @@ end aamt = arg[1] uamt = arg[2] -if uamt > aamt then - amt = uamt - aamt - amts = calc(amt) - amts = "-" .. amts -else - amt = aamt - uamt - amts = calc(math.abs(amt)) -end +amt = aamt - uamt +amts = calc(amt) tfile = io.open("/tmp/amtleft", "w") tfile:write(amts, "\n") tfile:close() \ No newline at end of file diff --git a/rooter/0optionalapps/bwmon/files/usr/lib/bwmon/dataper.lua b/rooter/0optionalapps/bwmon/files/usr/lib/bwmon/dataper.lua index a287094..d5d0527 100644 --- a/rooter/0optionalapps/bwmon/files/usr/lib/bwmon/dataper.lua +++ b/rooter/0optionalapps/bwmon/files/usr/lib/bwmon/dataper.lua @@ -4,11 +4,10 @@ alloc = arg[1] -- allocate increment in GB per = arg[2] -- fixed percentage in GB used = arg[3] -- amt used in Kb ---used = used / 10000 -- used in GB -percent = (used / alloc) * 100 - +used = used / 10000 -- used in GB +percent = used / alloc running = "0" -if percent >= tonumber(per) then +if percent >= per then running = "1" end diff --git a/rooter/0optionalapps/bwmon/files/usr/lib/bwmon/textbw.sh b/rooter/0optionalapps/bwmon/files/usr/lib/bwmon/textbw.sh index ed85caa..5d9d589 100644 --- a/rooter/0optionalapps/bwmon/files/usr/lib/bwmon/textbw.sh +++ b/rooter/0optionalapps/bwmon/files/usr/lib/bwmon/textbw.sh @@ -2,7 +2,7 @@ . /lib/functions.sh log() { - modlog "TEXTING" "$@" + logger -t "TEXTING" "$@" } checktime() { @@ -96,7 +96,7 @@ checkper() { istime=$(checktime) if [ $istime = '1' ]; then prev=$(uci -q get custom.texting.used) - per=$(uci -q get custom.texting.percent) + per=$(uci -q get custom.bwallocate.percent) persent=$(uci -q get custom.bwallocate.persent) if [ "$persent" != "1" ]; then getbw @@ -141,7 +141,7 @@ do if [ $running = "1" ]; then EN=$(uci -q get custom.texting.text) if [ $EN = "1" ]; then - /usr/lib/bwmon/dotext.sh & + /usr/lib/bwmon/dotext.sh sleep $delay fi else diff --git a/rooter/0optionalapps/ext-blacklist/files/usr/lib/lua/luci/controller/blacklist.lua b/rooter/0optionalapps/ext-blacklist/files/usr/lib/lua/luci/controller/blacklist.lua index 5797a2d..d132021 100644 --- a/rooter/0optionalapps/ext-blacklist/files/usr/lib/lua/luci/controller/blacklist.lua +++ b/rooter/0optionalapps/ext-blacklist/files/usr/lib/lua/luci/controller/blacklist.lua @@ -1,10 +1,13 @@ module("luci.controller.blacklist", package.seeall) +I18N = require "luci.i18n" +translate = I18N.translate + function index() local page local lock = luci.model.uci.cursor():get("custom", "menu", "full") - if lock == "1" then - page = entry({"admin", "adminmenu", "blacklist"}, cbi("blacklist"), "---Blacklist by Mac", 10) + --if lock == "1" then + page = entry({"admin", "adminmenu", "blacklist"}, cbi("blacklist"), translate("Blacklist by Mac"), 10) page.dependent = true - end + --end end diff --git a/rooter/0optionalapps/ext-domain/Makefile b/rooter/0optionalapps/ext-domain/Makefile index 103fa98..66e3d59 100644 --- a/rooter/0optionalapps/ext-domain/Makefile +++ b/rooter/0optionalapps/ext-domain/Makefile @@ -3,33 +3,34 @@ #Copyright GNU act. include $(TOPDIR)/rules.mk -PKG_NAME:=ext-blockport +PKG_NAME:=ext-domain PKG_VERSION:=1.000 PKG_RELEASE:=1 PKG_MAINTAINER:=Created by DM/makefile by Cobia@whirlpool include $(INCLUDE_DIR)/package.mk -define Package/ext-blockport +define Package/ext-domain SECTION:=utils CATEGORY:=ROOter SUBMENU:=Optional Applications - TITLE:=Install Port Blocking + DEPENDS:=+dnsmasq-full +ipset + TITLE:=Domain Filter PKGARCH:=all endef -define Package/ext-blockport/description - Helper scripts to install Port Blocking +define Package/ext-domain/description + Helper scripts to install Domain Filter on ROOter endef define Build/Compile endef -define Package/ext-blockport/install +define Package/ext-domain/install $(CP) ./files/* $(1)/ endef -$(eval $(call BuildPackage,ext-blockport)) +$(eval $(call BuildPackage,ext-domain)) diff --git a/rooter/0optionalapps/ext-domain/files/etc/config/blockport b/rooter/0optionalapps/ext-domain/files/etc/config/blockport deleted file mode 100644 index 8e69716..0000000 --- a/rooter/0optionalapps/ext-domain/files/etc/config/blockport +++ /dev/null @@ -1,4 +0,0 @@ - -config port 'port' - - diff --git a/rooter/0optionalapps/ext-domain/files/etc/config/filter b/rooter/0optionalapps/ext-domain/files/etc/config/filter new file mode 100644 index 0000000..5eb7a3b --- /dev/null +++ b/rooter/0optionalapps/ext-domain/files/etc/config/filter @@ -0,0 +1 @@ +config filter filter diff --git a/rooter/0optionalapps/ext-domain/files/etc/init.d/domain b/rooter/0optionalapps/ext-domain/files/etc/init.d/domain new file mode 100644 index 0000000..2e99572 --- /dev/null +++ b/rooter/0optionalapps/ext-domain/files/etc/init.d/domain @@ -0,0 +1,46 @@ +#!/bin/sh /etc/rc.common + +START=99 + +log() { + logger -t "Domain Filter " "$@" +} + +start() +{ + ff=$(uci -q get firewall.filter) + if [ -z $ff ]; then + uci set firewall.filter="ipset" + uci set firewall.filter.name="filter" + uci set firewall.filter.family="ipv4" + uci set firewall.filter.storage="hash" + uci set firewall.filter.match="ip" + uci set firewall.filter6="ipset" + uci set firewall.filter6.name="filter6" + uci set firewall.filter6.family="ipv6" + uci set firewall.filter6.storage="hash" + uci set firewall.filter6.match="ip" + + # Filter LAN client traffic with IP sets + uci set firewall.filter_fwd="rule" + uci set firewall.filter_fwd.name="Filter-IPset-DNS-Forward" + uci set firewall.filter_fwd.src="lan" + uci set firewall.filter_fwd.dest="wan" + uci set firewall.filter_fwd.ipset="filter dest" + uci set firewall.filter_fwd.family="ipv4" + uci set firewall.filter_fwd.proto="all" + uci set firewall.filter_fwd.target="REJECT" + uci set firewall.filter6_fwd="rule" + uci set firewall.filter6_fwd.name="Filter6-IPset-DNS-Forward" + uci set firewall.filter6_fwd.src="lan" + uci set firewall.filter6_fwd.dest="wan" + uci set firewall.filter6_fwd.ipset="filter6 dest" + uci set firewall.filter6_fwd.family="ipv6" + uci set firewall.filter6_fwd.proto="all" + uci set firewall.filter6_fwd.target="REJECT" + + uci commit firewall + /etc/init.d/firewall restart + fi + /usr/lib/domain/filter.sh +} \ No newline at end of file diff --git a/rooter/0optionalapps/ext-domain/files/usr/lib/blockport/blockport.sh b/rooter/0optionalapps/ext-domain/files/usr/lib/blockport/blockport.sh deleted file mode 100644 index 6965bc0..0000000 --- a/rooter/0optionalapps/ext-domain/files/usr/lib/blockport/blockport.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/sh -. /lib/functions.sh - -config="firewall" - -do_block_remove() { - config_get name $1 name - if [ "$name" = "Block_src" ]; then - uci delete $config".""$1" - fi -} - -handle_port() { - echo $1 - uci add $config rule - uci set $config.@rule[-1].src='lan' - uci set $config.@rule[-1].family='ipv4' - uci set $config.@rule[-1].dest='wan' - uci set $config.@rule[-1].target='DROP' - uci set $config.@rule[-1].proto='tcp' - uci set $config.@rule[-1].src_port="$1" - uci set $config.@rule[-1].name='Block_src' -} - -do_port() { - config_list_foreach "$1" block handle_port -} - -sleep 8 -config_load $config -config_foreach do_block_remove rule - -config_load blockport -config_foreach do_port port -uci commit $config -/etc/init.d/firewall restart 2>/dev/null - diff --git a/rooter/0optionalapps/ext-domain/files/usr/lib/domain/filter.sh b/rooter/0optionalapps/ext-domain/files/usr/lib/domain/filter.sh new file mode 100644 index 0000000..1bb349c --- /dev/null +++ b/rooter/0optionalapps/ext-domain/files/usr/lib/domain/filter.sh @@ -0,0 +1,26 @@ +#!/bin/sh +. /lib/functions.sh + +log() { + logger -t "Domain Filter " "$@" +} + +handle_ipset() { + local ips=$1 + uci add_list dhcp.@dnsmasq[0].ipset='/'$ips'/filter,filter6' +} + +do_ipset() { + local config=$1 + local ipset + + config_list_foreach "$config" ipset handle_ipset +} + +sleep 3 + +uci -q delete dhcp.@dnsmasq[0].ipset +config_load filter +config_foreach do_ipset filter +uci commit dhcp +/etc/init.d/dnsmasq restart \ No newline at end of file diff --git a/rooter/0optionalapps/ext-domain/files/usr/lib/lua/luci/controller/blockport.lua b/rooter/0optionalapps/ext-domain/files/usr/lib/lua/luci/controller/blockport.lua deleted file mode 100644 index fca343d..0000000 --- a/rooter/0optionalapps/ext-domain/files/usr/lib/lua/luci/controller/blockport.lua +++ /dev/null @@ -1,12 +0,0 @@ --- Licensed to the public under the Apache License 2.0. - -module("luci.controller.blockport", package.seeall) - -function index() - local lock = luci.model.uci.cursor():get("custom", "menu", "full") - if lock == "1" then - local page - page = entry({"admin", "adminmenu", "blockport"}, cbi("portblk"), _("---Port Blocking"), 10) - page.dependent = true - end -end diff --git a/rooter/0optionalapps/ext-domain/files/usr/lib/lua/luci/controller/domain.lua b/rooter/0optionalapps/ext-domain/files/usr/lib/lua/luci/controller/domain.lua new file mode 100644 index 0000000..5bca115 --- /dev/null +++ b/rooter/0optionalapps/ext-domain/files/usr/lib/lua/luci/controller/domain.lua @@ -0,0 +1,15 @@ +-- Licensed to the public under the Apache License 2.0. + +module("luci.controller.domain", package.seeall) + +I18N = require "luci.i18n" +translate = I18N.translate + +function index() + local lock = luci.model.uci.cursor():get("custom", "menu", "full") + --if lock == "1" then + local page + page = entry({"admin", "adminmenu", "domain"}, cbi("domainfltr"), _(translate("Domain Filter")), 9) + page.dependent = true + --end +end diff --git a/rooter/0optionalapps/ext-domain/files/usr/lib/lua/luci/model/cbi/portblk.lua b/rooter/0optionalapps/ext-domain/files/usr/lib/lua/luci/model/cbi/domainfltr.lua similarity index 50% rename from rooter/0optionalapps/ext-domain/files/usr/lib/lua/luci/model/cbi/portblk.lua rename to rooter/0optionalapps/ext-domain/files/usr/lib/lua/luci/model/cbi/domainfltr.lua index 73cd1ea..9c898e5 100644 --- a/rooter/0optionalapps/ext-domain/files/usr/lib/lua/luci/model/cbi/portblk.lua +++ b/rooter/0optionalapps/ext-domain/files/usr/lib/lua/luci/model/cbi/domainfltr.lua @@ -5,17 +5,17 @@ local zones = require "luci.sys.zoneinfo" local fs = require "nixio.fs" local conf = require "luci.config" -m = Map("blockport", translate("Port Blocking"), translate("Block traffic using specific ports")) +m = Map("filter", translate("Domain Filter"), translate("Block traffic to specified URLs")) m.on_after_save = function(self) - luci.sys.call("/usr/lib/blockport/blockport.sh &") + luci.sys.call("/usr/lib/domain/filter.sh &") end -s = m:section(TypedSection, "port", translate("Block Port List")) +s = m:section(TypedSection, "filter", translate("Block List")) s.anonymous = true s.addremove = false -s:option(DynamicList, "block", translate("Ports")) +s:option(DynamicList, "ipset", translate("Domain URLs")) return m \ No newline at end of file diff --git a/rooter/0optionalapps/ext-menu/Makefile b/rooter/0optionalapps/ext-menu/Makefile new file mode 100644 index 0000000..0dee3f0 --- /dev/null +++ b/rooter/0optionalapps/ext-menu/Makefile @@ -0,0 +1,35 @@ +#Owned by DairyMan@Whirlpool +# +#Copyright GNU act. +include $(TOPDIR)/rules.mk + +PKG_NAME:=ext-menu +PKG_VERSION:=1.000 +PKG_RELEASE:=1 + +PKG_MAINTAINER:=Created by DM/makefile by Cobia@whirlpool +include $(INCLUDE_DIR)/package.mk + +define Package/ext-menu + SECTION:=utils + CATEGORY:=ROOter + SUBMENU:=Optional Applications + TITLE:=Menu Selection + PKGARCH:=all +endef + +define Package/ext-menu/description + Helper scripts to install Menu Selection on ROOter +endef + + +define Build/Compile +endef + +define Package/ext-menu/install + $(CP) ./files/* $(1)/ + + +endef + +$(eval $(call BuildPackage,ext-menu)) diff --git a/rooter/0optionalapps/ext-menu/files/etc/uci-defaults/63-menu b/rooter/0optionalapps/ext-menu/files/etc/uci-defaults/63-menu new file mode 100644 index 0000000..d5375bd --- /dev/null +++ b/rooter/0optionalapps/ext-menu/files/etc/uci-defaults/63-menu @@ -0,0 +1,10 @@ +#!/bin/sh + +fv=$(uci -q get custom.menu.full) +if [ $fv = "0" ]; then + fv="1" +else + fv="0" +fi + +/usr/lib/fullmenu/setmenu.sh $fv diff --git a/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/full19/firewall.lua b/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/full19/firewall.lua new file mode 100644 index 0000000..d761109 --- /dev/null +++ b/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/full19/firewall.lua @@ -0,0 +1,28 @@ +module("luci.controller.firewall", package.seeall) + +function index() + entry({"admin", "network", "firewall"}, + alias("admin", "network", "firewall", "zones"), + _("Firewall"), 60) + + entry({"admin", "network", "firewall", "zones"}, + view("firewall/zones"), _("General Settings"), 10) + + entry({"admin", "network", "firewall", "forwards"}, + view("firewall/forwards"), _("Port Forwards"), 20) + + entry({"admin", "network", "firewall", "rules"}, + view("firewall/rules"), _("Traffic Rules"), 30) + + entry({"admin", "network", "firewall", "snats"}, + view("firewall/snats"), _("NAT Rules"), 40) + + entry({"admin", "network", "firewall", "custom"}, + view("firewall/custom"), _("Custom Rules"), 45).leaf = true + + if nixio.fs.access("/etc/config/modem") then + entry({"admin", "network", "firewall", "ttl"}, + cbi("firewall/ttlx"), + _("Custom TTL Settings"), 50).leaf = true + end +end diff --git a/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/full19/luci-mod-status.json b/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/full19/luci-mod-status.json new file mode 100644 index 0000000..0dcf6e8 --- /dev/null +++ b/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/full19/luci-mod-status.json @@ -0,0 +1,103 @@ +{ + "admin/status/overview": { + "title": "Overview", + "order": 1, + "action": { + "type": "template", + "path": "admin_status/index" + } + }, + + "admin/status/iptables": { + "title": "Firewall", + "order": 2, + "action": { + "type": "view", + "path": "status/iptables" + } + }, + + "admin/status/routes": { + "title": "Routes", + "order": 3, + "action": { + "type": "view", + "path": "status/routes" + } + }, + + "admin/status/syslog": { + "title": "System Log", + "order": 4, + "action": { + "type": "view", + "path": "status/syslog" + } + }, + + "admin/status/dmesg": { + "title": "Kernel Log", + "order": 5, + "action": { + "type": "view", + "path": "status/dmesg" + } + }, + + "admin/status/processes": { + "title": "Processes", + "order": 6, + "action": { + "type": "view", + "path": "status/processes" + } + }, + + "admin/status/realtime": { + "title": "Realtime Graphs", + "order": 7, + "action": { + "type": "alias", + "path": "admin/status/realtime/load" + } + }, + + "admin/status/realtime/load": { + "title": "Load", + "order": 1, + "action": { + "type": "view", + "path": "status/load" + } + }, + + "admin/status/realtime/bandwidth": { + "title": "Traffic", + "order": 2, + "action": { + "type": "view", + "path": "status/bandwidth" + } + }, + + "admin/status/realtime/wireless": { + "title": "Wireless", + "order": 3, + "action": { + "type": "view", + "path": "status/wireless" + }, + "depends": { + "uci": { "wireless": { "@wifi-device": true } } + } + }, + + "admin/status/realtime/connections": { + "title": "Connections", + "order": 4, + "action": { + "type": "view", + "path": "status/connections" + } + } +} diff --git a/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/full19/luci-mod-system.json b/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/full19/luci-mod-system.json new file mode 100644 index 0000000..ef21d6e --- /dev/null +++ b/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/full19/luci-mod-system.json @@ -0,0 +1,111 @@ +{ + "admin/system/system": { + "title": "System", + "order": 1, + "action": { + "type": "view", + "path": "system/system" + } + }, + + "admin/system/admin": { + "title": "Administration", + "order": 2, + "action": { + "type": "firstchild" + } + }, + + "admin/system/admin/password": { + "title": "Router Password", + "order": 1, + "action": { + "type": "view", + "path": "system/password" + } + }, + + "admin/system/admin/dropbear": { + "title": "SSH Access", + "order": 2, + "action": { + "type": "view", + "path": "system/dropbear" + }, + "depends": { + "fs": { "/usr/sbin/dropbear": "executable" } + } + }, + + "admin/system/admin/sshkeys": { + "title": "SSH-Keys", + "order": 3, + "action": { + "type": "view", + "path": "system/sshkeys" + }, + "depends": { + "fs": { "/usr/sbin/dropbear": "executable" } + } + }, + + "admin/system/startup": { + "title": "Startup", + "order": 45, + "action": { + "type": "view", + "path": "system/startup" + } + }, + + "admin/system/crontab": { + "title": "Scheduled Tasks", + "order": 46, + "action": { + "type": "view", + "path": "system/crontab" + } + }, + + "admin/system/mounts": { + "title": "Mount Points", + "order": 50, + "action": { + "type": "view", + "path": "system/mounts" + }, + "depends": { + "fs": { "/sbin/block": "executable" } + } + }, + + "admin/system/leds": { + "title": "LED Configuration", + "order": 60, + "action": { + "type": "view", + "path": "system/leds" + }, + "depends": { + "fs": { "/sys/class/leds": "directory" } + } + }, + + "admin/system/flash": { + "title": "Backup / Flash Firmware", + "order": 70, + "action": { + "type": "view", + "path": "system/flash" + } + }, + + "admin/system/reboot": { + "title": "Reboot", + "order": 90, + "action": { + "type": "view", + "path": "system/reboot" + } + } +} diff --git a/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/full19/network.lua b/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/full19/network.lua new file mode 100644 index 0000000..b34ec4f --- /dev/null +++ b/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/full19/network.lua @@ -0,0 +1,44 @@ +-- Copyright 2008 Steven Barth +-- Copyright 2011-2018 Jo-Philipp Wich +-- Licensed to the public under the Apache License 2.0. + +module("luci.controller.admin.network", package.seeall) + +function index() + local page + +-- if page.inreq then + page = entry({"admin", "network", "switch"}, view("network/switch"), _("Switch"), 20) + page.uci_depends = { network = { ["@switch[0]"] = "switch" } } + + page = entry({"admin", "network", "wireless"}, view("network/wireless"), _('Wireless'), 15) + page.uci_depends = { wireless = { ["@wifi-device[0]"] = "wifi-device" } } + page.leaf = true + + page = entry({"admin", "network", "network"}, view("network/interfaces"), _("Interfaces"), 10) + page.leaf = true + page.subindex = true + + page = node("admin", "network", "dhcp") + page.uci_depends = { dhcp = true } + page.target = view("network/dhcp") + page.title = _("DHCP and DNS") + page.order = 30 + + page = node("admin", "network", "hosts") + page.uci_depends = { dhcp = true } + page.target = view("network/hosts") + page.title = _("Hostnames") + page.order = 40 + + page = node("admin", "network", "routes") + page.target = view("network/routes") + page.title = _("Static Routes") + page.order = 50 + + page = node("admin", "network", "diagnostics") + page.target = view("network/diagnostics") + page.title = _("Diagnostics") + page.order = 60 +-- end +end diff --git a/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/full19/opkg.lua b/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/full19/opkg.lua new file mode 100644 index 0000000..29c9a08 --- /dev/null +++ b/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/full19/opkg.lua @@ -0,0 +1,117 @@ +-- Copyright 2018 Jo-Philipp Wich +-- Licensed to the public under the Apache License 2.0. + +module("luci.controller.opkg", package.seeall) + +function index() + entry({"admin", "system", "opkg"}, template("opkg"), _("Software"), 30) + entry({"admin", "system", "opkg", "list"}, call("action_list")).leaf = true + entry({"admin", "system", "opkg", "exec"}, post("action_exec")).leaf = true + entry({"admin", "system", "opkg", "statvfs"}, call("action_statvfs")).leaf = true + entry({"admin", "system", "opkg", "config"}, post_on({ data = true }, "action_config")).leaf = true +end + +function action_list(mode) + local util = require "luci.util" + local cmd + + if mode == "installed" then + cmd = { "/bin/cat", "/usr/lib/opkg/status" } + else + local lists_dir = nil + + local fd = io.popen([[sed -rne 's#^lists_dir \S+ (\S+)#\1#p' /etc/opkg.conf /etc/opkg/*.conf 2>/dev/null]], "r") + if fd then + lists_dir = fd:read("*l") + fd:close() + end + + if not lists_dir or #lists_dir == "" then + lists_dir = "/tmp/opkg-lists" + end + + cmd = { "/bin/sh", "-c", [[find %s -type f '!' -name '*.sig' | xargs -r gzip -cd]] % util.shellquote(lists_dir) } + end + + luci.http.prepare_content("text/plain; charset=utf-8") + luci.sys.process.exec(cmd, luci.http.write) +end + +function action_exec(command, package) + local sys = require "luci.sys" + local cmd = { "/bin/opkg", "--force-removal-of-dependent-packages" } + local pkg = luci.http.formvalue("package") + + if luci.http.formvalue("autoremove") == "true" then + cmd[#cmd + 1] = "--autoremove" + end + + if luci.http.formvalue("overwrite") == "true" then + cmd[#cmd + 1] = "--force-overwrite" + end + + cmd[#cmd + 1] = command + + if pkg then + cmd[#cmd + 1] = pkg + end + + luci.http.prepare_content("application/json") + luci.http.write_json(sys.process.exec(cmd, true, true)) +end + +function action_statvfs() + local fs = require "nixio.fs" + + luci.http.prepare_content("application/json") + luci.http.write_json(fs.statvfs("/") or {}) +end + +function action_config() + local fs = require "nixio.fs" + local js = require "luci.jsonc" + local data = luci.http.formvalue("data") + + if data then + data = js.parse(data) + + if not data then + luci.http.status(400, "Bad Request") + return + end + + local file, content + for file, content in pairs(data) do + if type(content) ~= "string" or + (file ~= "opkg.conf" and not file:match("^opkg/[^/]+%.conf$")) + then + luci.http.status(400, "Bad Request") + return + end + + local path = "/etc/%s" % file + if not fs.access(path, "w") then + luci.http.status(403, "Permission denied") + return + end + + fs.writefile(path, content:gsub("\r\n", "\n")) + end + + luci.http.status(204, "Saved") + else + local rv = { ["opkg.conf"] = fs.readfile("/etc/opkg.conf") } + local entries = fs.dir("/etc/opkg") + if entries then + local entry + for entry in entries do + if entry:match("%.conf$") then + rv["opkg/%s" % entry] = fs.readfile("/etc/opkg/%s" % entry) + end + end + end + + luci.http.prepare_content("application/json") + luci.http.write_json(rv) + end +end diff --git a/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/full21/luci-app-firewall.json b/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/full21/luci-app-firewall.json new file mode 100644 index 0000000..4672a27 --- /dev/null +++ b/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/full21/luci-app-firewall.json @@ -0,0 +1,70 @@ +{ + "admin/network/firewall": { + "title": "Firewall", + "order": 60, + "action": { + "type": "alias", + "path": "admin/network/firewall/zones" + }, + "depends": { + "acl": [ "luci-app-firewall" ], + "fs": { "/sbin/fw3": "executable" }, + "uci": { "firewall": true } + } + }, + + "admin/network/firewall/zones": { + "title": "General Settings", + "order": 10, + "action": { + "type": "view", + "path": "firewall/zones" + } + }, + + "admin/network/firewall/forwards": { + "title": "Port Forwards", + "order": 20, + "action": { + "type": "view", + "path": "firewall/forwards" + } + }, + + "admin/network/firewall/rules": { + "title": "Traffic Rules", + "order": 30, + "action": { + "type": "view", + "path": "firewall/rules" + } + }, + + "admin/network/firewall/snats": { + "title": "NAT Rules", + "order": 40, + "action": { + "type": "view", + "path": "firewall/snats" + } + }, + + + "admin/network/firewall/custom": { + "title": "Custom Rules", + "order": 50, + "action": { + "type": "view", + "path": "firewall/custom" + } + }, + + "admin/network/firewall/customttl": { + "title": "Custom TTL Settings", + "order": 55, + "action": { + "type": "cbi", + "path": "firewall/ttlx" + } + } +} diff --git a/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/full21/luci-app-opkg.json b/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/full21/luci-app-opkg.json new file mode 100644 index 0000000..3d06a25 --- /dev/null +++ b/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/full21/luci-app-opkg.json @@ -0,0 +1,13 @@ +{ + "admin/system/opkg": { + "title": "Software", + "order": 30, + "action": { + "type": "view", + "path": "opkg" + }, + "depends": { + "acl": [ "luci-app-opkg" ] + } + } +} diff --git a/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/full21/luci-mod-network.json b/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/full21/luci-mod-network.json new file mode 100644 index 0000000..188c695 --- /dev/null +++ b/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/full21/luci-mod-network.json @@ -0,0 +1,98 @@ +{ + "admin/network/switch": { + "title": "Switch", + "order": 20, + "action": { + "type": "view", + "path": "network/switch" + }, + "depends": { + "acl": [ "luci-mod-network-config" ], + "fs": { "/sbin/swconfig": "executable" }, + "uci": { "network": { "@switch": true } } + } + }, + + "admin/network/wireless": { + "title": "Wireless", + "order": 15, + "action": { + "type": "view", + "path": "network/wireless" + }, + "depends": { + "acl": [ "luci-mod-network-config" ], + "uci": { "wireless": { "@wifi-device": true } } + } + }, + + "admin/network/remote_addr/*": { + "action": { + "type": "call", + "module": "luci.controller.admin.network", + "function": "remote_addr" + } + }, + + "admin/network/network": { + "title": "Interfaces", + "order": 10, + "action": { + "type": "view", + "path": "network/interfaces" + }, + "depends": { + "acl": [ "luci-mod-network-config" ] + } + }, + + "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, + "action": { + "type": "view", + "path": "network/routes" + }, + "depends": { + "acl": [ "luci-mod-network-config" ] + } + }, + + "admin/network/diagnostics": { + "title": "Diagnostics", + "order": 60, + "action": { + "type": "view", + "path": "network/diagnostics" + }, + "depends": { + "acl": [ "luci-mod-network-diagnostics" ] + } + } +} diff --git a/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/full21/luci-mod-status.json b/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/full21/luci-mod-status.json new file mode 100644 index 0000000..0f066e6 --- /dev/null +++ b/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/full21/luci-mod-status.json @@ -0,0 +1,137 @@ +{ + "admin/status/overview": { + "title": "Overview", + "order": 1, + "action": { + "type": "template", + "path": "admin_status/index" + }, + "depends": { + "acl": [ "luci-mod-status-index" ] + } + }, + + "admin/status/iptables": { + "title": "Firewall", + "order": 2, + "action": { + "type": "view", + "path": "status/iptables" + }, + "depends": { + "acl": [ "luci-mod-status-firewall" ] + } + }, + + "admin/status/routes": { + "title": "Routes", + "order": 3, + "action": { + "type": "view", + "path": "status/routes" + }, + "depends": { + "acl": [ "luci-mod-status-routes" ] + } + }, + + "admin/status/syslog": { + "title": "System Log", + "order": 4, + "action": { + "type": "view", + "path": "status/syslog" + }, + "depends": { + "acl": [ "luci-mod-status-logs" ] + } + }, + + "admin/status/dmesg": { + "title": "Kernel Log", + "order": 5, + "action": { + "type": "view", + "path": "status/dmesg" + }, + "depends": { + "acl": [ "luci-mod-status-logs" ] + } + }, + + "admin/status/processes": { + "title": "Processes", + "order": 6, + "action": { + "type": "view", + "path": "status/processes" + }, + "depends": { + "acl": [ "luci-mod-status-processes" ] + } + }, + + "admin/status/channel_analysis": { + "title": "Channel Analysis", + "order": 7, + "action": { + "type": "view", + "path": "status/channel_analysis" + }, + "depends": { + "acl": [ "luci-mod-status-channel_analysis" ], + "uci": { "wireless": { "@wifi-device": true } } + } + }, + + "admin/status/realtime": { + "title": "Realtime Graphs", + "order": 7, + "action": { + "type": "alias", + "path": "admin/status/realtime/load" + }, + "depends": { + "acl": [ "luci-mod-status-realtime" ] + } + }, + + "admin/status/realtime/load": { + "title": "Load", + "order": 1, + "action": { + "type": "view", + "path": "status/load" + } + }, + + "admin/status/realtime/bandwidth": { + "title": "Traffic", + "order": 2, + "action": { + "type": "view", + "path": "status/bandwidth" + } + }, + + "admin/status/realtime/wireless": { + "title": "Wireless", + "order": 3, + "action": { + "type": "view", + "path": "status/wireless" + }, + "depends": { + "uci": { "wireless": { "@wifi-device": true } } + } + }, + + "admin/status/realtime/connections": { + "title": "Connections", + "order": 4, + "action": { + "type": "view", + "path": "status/connections" + } + } +} diff --git a/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/full21/luci-mod-system.json b/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/full21/luci-mod-system.json new file mode 100644 index 0000000..4022e0c --- /dev/null +++ b/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/full21/luci-mod-system.json @@ -0,0 +1,136 @@ +{ + "admin/system/system": { + "title": "System", + "order": 1, + "action": { + "type": "view", + "path": "system/system" + }, + "depends": { + "acl": [ "luci-mod-system-config" ] + } + }, + + "admin/system/admin": { + "title": "Administration", + "order": 2, + "action": { + "type": "firstchild" + }, + "depends": { + "acl": [ "luci-mod-system-config", "luci-mod-system-ssh" ] + } + }, + + "admin/system/admin/password": { + "title": "Router Password", + "order": 1, + "action": { + "type": "view", + "path": "system/password" + }, + "depends": { + "acl": [ "luci-mod-system-config" ] + } + }, + + "admin/system/admin/dropbear": { + "title": "SSH Access", + "order": 2, + "action": { + "type": "view", + "path": "system/dropbear" + }, + "depends": { + "acl": [ "luci-mod-system-ssh" ], + "fs": { "/usr/sbin/dropbear": "executable" } + } + }, + + "admin/system/admin/sshkeys": { + "title": "SSH-Keys", + "order": 3, + "action": { + "type": "view", + "path": "system/sshkeys" + }, + "depends": { + "acl": [ "luci-mod-system-ssh" ], + "fs": { "/usr/sbin/dropbear": "executable" } + } + }, + + "admin/system/startup": { + "title": "Startup", + "order": 45, + "action": { + "type": "view", + "path": "system/startup" + }, + "depends": { + "acl": [ "luci-mod-system-init" ] + } + }, + + "admin/system/crontab": { + "title": "Scheduled Tasks", + "order": 46, + "action": { + "type": "view", + "path": "system/crontab" + }, + "depends": { + "acl": [ "luci-mod-system-cron" ] + } + }, + + "admin/system/mounts": { + "title": "Mount Points", + "order": 50, + "action": { + "type": "view", + "path": "system/mounts" + }, + "depends": { + "acl": [ "luci-mod-system-mounts" ], + "fs": { "/sbin/block": "executable" } + } + }, + + "admin/system/leds": { + "title": "LED Configuration", + "order": 60, + "action": { + "type": "view", + "path": "system/leds" + }, + "depends": { + "acl": [ "luci-mod-system-config" ], + "fs": { "/sys/class/leds": "directory" } + } + }, + + "admin/system/flash": { + "title": "Backup / Flash Firmware", + "order": 70, + "action": { + "type": "view", + "path": "system/flash" + }, + "depends": { + "acl": [ "luci-mod-system-flash" ] + } + }, + + "admin/system/reboot": { + "title": "Reboot", + "order": 90, + "action": { + "type": "view", + "path": "system/reboot" + }, + "depends": { + "acl": [ "luci-mod-system-reboot" ] + } + } +} diff --git a/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/limited19/firewall.lua b/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/limited19/firewall.lua new file mode 100644 index 0000000..d761109 --- /dev/null +++ b/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/limited19/firewall.lua @@ -0,0 +1,28 @@ +module("luci.controller.firewall", package.seeall) + +function index() + entry({"admin", "network", "firewall"}, + alias("admin", "network", "firewall", "zones"), + _("Firewall"), 60) + + entry({"admin", "network", "firewall", "zones"}, + view("firewall/zones"), _("General Settings"), 10) + + entry({"admin", "network", "firewall", "forwards"}, + view("firewall/forwards"), _("Port Forwards"), 20) + + entry({"admin", "network", "firewall", "rules"}, + view("firewall/rules"), _("Traffic Rules"), 30) + + entry({"admin", "network", "firewall", "snats"}, + view("firewall/snats"), _("NAT Rules"), 40) + + entry({"admin", "network", "firewall", "custom"}, + view("firewall/custom"), _("Custom Rules"), 45).leaf = true + + if nixio.fs.access("/etc/config/modem") then + entry({"admin", "network", "firewall", "ttl"}, + cbi("firewall/ttlx"), + _("Custom TTL Settings"), 50).leaf = true + end +end diff --git a/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/limited19/luci-mod-status.json b/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/limited19/luci-mod-status.json new file mode 100644 index 0000000..7e664bf --- /dev/null +++ b/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/limited19/luci-mod-status.json @@ -0,0 +1,19 @@ +{ + "admin/status/overview": { + "title": "Overview", + "order": 1, + "action": { + "type": "template", + "path": "admin_status/index" + } + }, + + "admin/status/syslog": { + "title": "System Log", + "order": 4, + "action": { + "type": "view", + "path": "status/syslog" + } + } +} diff --git a/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/limited19/luci-mod-system.json b/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/limited19/luci-mod-system.json new file mode 100644 index 0000000..f220775 --- /dev/null +++ b/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/limited19/luci-mod-system.json @@ -0,0 +1,45 @@ +{ + "admin/system/system": { + "title": "System", + "order": 1, + "action": { + "type": "view", + "path": "system/system" + } + }, + + "admin/system/admin": { + "title": "Administration", + "order": 2, + "action": { + "type": "firstchild" + } + }, + + "admin/system/admin/password": { + "title": "Router Password", + "order": 1, + "action": { + "type": "view", + "path": "system/password" + } + }, + + "admin/system/flash": { + "title": "Flash Firmware", + "order": 70, + "action": { + "type": "view", + "path": "system/flash" + } + }, + + "admin/system/reboot": { + "title": "Reboot", + "order": 90, + "action": { + "type": "view", + "path": "system/reboot" + } + } +} diff --git a/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/limited19/network.lua b/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/limited19/network.lua new file mode 100644 index 0000000..b34ec4f --- /dev/null +++ b/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/limited19/network.lua @@ -0,0 +1,44 @@ +-- Copyright 2008 Steven Barth +-- Copyright 2011-2018 Jo-Philipp Wich +-- Licensed to the public under the Apache License 2.0. + +module("luci.controller.admin.network", package.seeall) + +function index() + local page + +-- if page.inreq then + page = entry({"admin", "network", "switch"}, view("network/switch"), _("Switch"), 20) + page.uci_depends = { network = { ["@switch[0]"] = "switch" } } + + page = entry({"admin", "network", "wireless"}, view("network/wireless"), _('Wireless'), 15) + page.uci_depends = { wireless = { ["@wifi-device[0]"] = "wifi-device" } } + page.leaf = true + + page = entry({"admin", "network", "network"}, view("network/interfaces"), _("Interfaces"), 10) + page.leaf = true + page.subindex = true + + page = node("admin", "network", "dhcp") + page.uci_depends = { dhcp = true } + page.target = view("network/dhcp") + page.title = _("DHCP and DNS") + page.order = 30 + + page = node("admin", "network", "hosts") + page.uci_depends = { dhcp = true } + page.target = view("network/hosts") + page.title = _("Hostnames") + page.order = 40 + + page = node("admin", "network", "routes") + page.target = view("network/routes") + page.title = _("Static Routes") + page.order = 50 + + page = node("admin", "network", "diagnostics") + page.target = view("network/diagnostics") + page.title = _("Diagnostics") + page.order = 60 +-- end +end diff --git a/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/limited19/opkg.lua b/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/limited19/opkg.lua new file mode 100644 index 0000000..29c9a08 --- /dev/null +++ b/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/limited19/opkg.lua @@ -0,0 +1,117 @@ +-- Copyright 2018 Jo-Philipp Wich +-- Licensed to the public under the Apache License 2.0. + +module("luci.controller.opkg", package.seeall) + +function index() + entry({"admin", "system", "opkg"}, template("opkg"), _("Software"), 30) + entry({"admin", "system", "opkg", "list"}, call("action_list")).leaf = true + entry({"admin", "system", "opkg", "exec"}, post("action_exec")).leaf = true + entry({"admin", "system", "opkg", "statvfs"}, call("action_statvfs")).leaf = true + entry({"admin", "system", "opkg", "config"}, post_on({ data = true }, "action_config")).leaf = true +end + +function action_list(mode) + local util = require "luci.util" + local cmd + + if mode == "installed" then + cmd = { "/bin/cat", "/usr/lib/opkg/status" } + else + local lists_dir = nil + + local fd = io.popen([[sed -rne 's#^lists_dir \S+ (\S+)#\1#p' /etc/opkg.conf /etc/opkg/*.conf 2>/dev/null]], "r") + if fd then + lists_dir = fd:read("*l") + fd:close() + end + + if not lists_dir or #lists_dir == "" then + lists_dir = "/tmp/opkg-lists" + end + + cmd = { "/bin/sh", "-c", [[find %s -type f '!' -name '*.sig' | xargs -r gzip -cd]] % util.shellquote(lists_dir) } + end + + luci.http.prepare_content("text/plain; charset=utf-8") + luci.sys.process.exec(cmd, luci.http.write) +end + +function action_exec(command, package) + local sys = require "luci.sys" + local cmd = { "/bin/opkg", "--force-removal-of-dependent-packages" } + local pkg = luci.http.formvalue("package") + + if luci.http.formvalue("autoremove") == "true" then + cmd[#cmd + 1] = "--autoremove" + end + + if luci.http.formvalue("overwrite") == "true" then + cmd[#cmd + 1] = "--force-overwrite" + end + + cmd[#cmd + 1] = command + + if pkg then + cmd[#cmd + 1] = pkg + end + + luci.http.prepare_content("application/json") + luci.http.write_json(sys.process.exec(cmd, true, true)) +end + +function action_statvfs() + local fs = require "nixio.fs" + + luci.http.prepare_content("application/json") + luci.http.write_json(fs.statvfs("/") or {}) +end + +function action_config() + local fs = require "nixio.fs" + local js = require "luci.jsonc" + local data = luci.http.formvalue("data") + + if data then + data = js.parse(data) + + if not data then + luci.http.status(400, "Bad Request") + return + end + + local file, content + for file, content in pairs(data) do + if type(content) ~= "string" or + (file ~= "opkg.conf" and not file:match("^opkg/[^/]+%.conf$")) + then + luci.http.status(400, "Bad Request") + return + end + + local path = "/etc/%s" % file + if not fs.access(path, "w") then + luci.http.status(403, "Permission denied") + return + end + + fs.writefile(path, content:gsub("\r\n", "\n")) + end + + luci.http.status(204, "Saved") + else + local rv = { ["opkg.conf"] = fs.readfile("/etc/opkg.conf") } + local entries = fs.dir("/etc/opkg") + if entries then + local entry + for entry in entries do + if entry:match("%.conf$") then + rv["opkg/%s" % entry] = fs.readfile("/etc/opkg/%s" % entry) + end + end + end + + luci.http.prepare_content("application/json") + luci.http.write_json(rv) + end +end diff --git a/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/limited21/luci-app-firewall.json b/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/limited21/luci-app-firewall.json new file mode 100644 index 0000000..4672a27 --- /dev/null +++ b/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/limited21/luci-app-firewall.json @@ -0,0 +1,70 @@ +{ + "admin/network/firewall": { + "title": "Firewall", + "order": 60, + "action": { + "type": "alias", + "path": "admin/network/firewall/zones" + }, + "depends": { + "acl": [ "luci-app-firewall" ], + "fs": { "/sbin/fw3": "executable" }, + "uci": { "firewall": true } + } + }, + + "admin/network/firewall/zones": { + "title": "General Settings", + "order": 10, + "action": { + "type": "view", + "path": "firewall/zones" + } + }, + + "admin/network/firewall/forwards": { + "title": "Port Forwards", + "order": 20, + "action": { + "type": "view", + "path": "firewall/forwards" + } + }, + + "admin/network/firewall/rules": { + "title": "Traffic Rules", + "order": 30, + "action": { + "type": "view", + "path": "firewall/rules" + } + }, + + "admin/network/firewall/snats": { + "title": "NAT Rules", + "order": 40, + "action": { + "type": "view", + "path": "firewall/snats" + } + }, + + + "admin/network/firewall/custom": { + "title": "Custom Rules", + "order": 50, + "action": { + "type": "view", + "path": "firewall/custom" + } + }, + + "admin/network/firewall/customttl": { + "title": "Custom TTL Settings", + "order": 55, + "action": { + "type": "cbi", + "path": "firewall/ttlx" + } + } +} diff --git a/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/limited21/luci-mod-network.json b/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/limited21/luci-mod-network.json new file mode 100644 index 0000000..188c695 --- /dev/null +++ b/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/limited21/luci-mod-network.json @@ -0,0 +1,98 @@ +{ + "admin/network/switch": { + "title": "Switch", + "order": 20, + "action": { + "type": "view", + "path": "network/switch" + }, + "depends": { + "acl": [ "luci-mod-network-config" ], + "fs": { "/sbin/swconfig": "executable" }, + "uci": { "network": { "@switch": true } } + } + }, + + "admin/network/wireless": { + "title": "Wireless", + "order": 15, + "action": { + "type": "view", + "path": "network/wireless" + }, + "depends": { + "acl": [ "luci-mod-network-config" ], + "uci": { "wireless": { "@wifi-device": true } } + } + }, + + "admin/network/remote_addr/*": { + "action": { + "type": "call", + "module": "luci.controller.admin.network", + "function": "remote_addr" + } + }, + + "admin/network/network": { + "title": "Interfaces", + "order": 10, + "action": { + "type": "view", + "path": "network/interfaces" + }, + "depends": { + "acl": [ "luci-mod-network-config" ] + } + }, + + "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, + "action": { + "type": "view", + "path": "network/routes" + }, + "depends": { + "acl": [ "luci-mod-network-config" ] + } + }, + + "admin/network/diagnostics": { + "title": "Diagnostics", + "order": 60, + "action": { + "type": "view", + "path": "network/diagnostics" + }, + "depends": { + "acl": [ "luci-mod-network-diagnostics" ] + } + } +} diff --git a/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/limited21/luci-mod-status.json b/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/limited21/luci-mod-status.json new file mode 100644 index 0000000..5beffdd --- /dev/null +++ b/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/limited21/luci-mod-status.json @@ -0,0 +1,38 @@ +{ + "admin/status/overview": { + "title": "Overview", + "order": 1, + "action": { + "type": "template", + "path": "admin_status/index" + }, + "depends": { + "acl": [ "luci-mod-status-index" ] + } + }, + + "admin/status/syslog": { + "title": "System Log", + "order": 4, + "action": { + "type": "view", + "path": "status/syslog" + }, + "depends": { + "acl": [ "luci-mod-status-logs" ] + } + }, + + "admin/status/channel_analysis": { + "title": "Wifi Channel Analysis", + "order": 7, + "action": { + "type": "view", + "path": "status/channel_analysis" + }, + "depends": { + "acl": [ "luci-mod-status-channel_analysis" ], + "uci": { "wireless": { "@wifi-device": true } } + } + }, +} diff --git a/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/limited21/luci-mod-system.json b/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/limited21/luci-mod-system.json new file mode 100644 index 0000000..7ab8bed --- /dev/null +++ b/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/limited21/luci-mod-system.json @@ -0,0 +1,60 @@ +{ + "admin/system/system": { + "title": "System", + "order": 1, + "action": { + "type": "view", + "path": "system/system" + }, + "depends": { + "acl": [ "luci-mod-system-config" ] + } + }, + + "admin/system/admin": { + "title": "Administration", + "order": 2, + "action": { + "type": "firstchild" + }, + "depends": { + "acl": [ "luci-mod-system-config", "luci-mod-system-ssh" ] + } + }, + + "admin/system/admin/password": { + "title": "Router Password", + "order": 1, + "action": { + "type": "view", + "path": "system/password" + }, + "depends": { + "acl": [ "luci-mod-system-config" ] + } + }, + + "admin/system/flash": { + "title": "Flash Firmware", + "order": 70, + "action": { + "type": "view", + "path": "system/flash" + }, + "depends": { + "acl": [ "luci-mod-system-flash" ] + } + }, + + "admin/system/reboot": { + "title": "Reboot", + "order": 90, + "action": { + "type": "view", + "path": "system/reboot" + }, + "depends": { + "acl": [ "luci-mod-system-reboot" ] + } + } +} diff --git a/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/setmenu.sh b/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/setmenu.sh new file mode 100644 index 0000000..fd5bc31 --- /dev/null +++ b/rooter/0optionalapps/ext-menu/files/usr/lib/fullmenu/setmenu.sh @@ -0,0 +1,34 @@ +#!/bin/sh +. /lib/functions.sh + +log() { + logger -t "Menu Change" "$@" +} + +full=$1 +source /etc/openwrt_release +twone=$(echo "$DISTRIB_RELEASE" | grep "21.02") + +if [ $full = "0" ]; then + fv="1" + if [ ! -z "$twone" ]; then # 21.02 + cp /usr/lib/fullmenu/full21/luci-mod-status.json /usr/share/luci/menu.d + cp /usr/lib/fullmenu/full21/luci-mod-system.json /usr/share/luci/menu.d + cp /usr/lib/fullmenu/full21/luci-app-opkg.json /usr/share/luci/menu.d + else # 19.07.6 + cp /usr/lib/fullmenu/full19/luci-mod-status.json /usr/share/luci/menu.d + cp /usr/lib/fullmenu/full19/luci-mod-system.json /usr/share/luci/menu.d + fi +else + fv="0" + if [ ! -z "$twone" ]; then # 21.02 + cp /usr/lib/fullmenu/limited21/luci-mod-status.json /usr/share/luci/menu.d + cp /usr/lib/fullmenu/limited21/luci-mod-system.json /usr/share/luci/menu.d + rm -f /usr/share/luci/menu.d/luci-app-opkg.json + else # 19.07.6 + cp /usr/lib/fullmenu/limited19/luci-mod-status.json /usr/share/luci/menu.d + cp /usr/lib/fullmenu/limited19/luci-mod-system.json /usr/share/luci/menu.d + fi +fi +uci set custom.menu.full=$fv +uci commit custom \ No newline at end of file diff --git a/rooter/0optionalapps/ext-menu/files/usr/lib/lua/luci/controller/fullmenu.lua b/rooter/0optionalapps/ext-menu/files/usr/lib/lua/luci/controller/fullmenu.lua new file mode 100644 index 0000000..20d1494 --- /dev/null +++ b/rooter/0optionalapps/ext-menu/files/usr/lib/lua/luci/controller/fullmenu.lua @@ -0,0 +1,28 @@ +module("luci.controller.fullmenu", package.seeall) +function index() + local fs = require "nixio.fs" + local page + page = entry({"admin", "system", "fullmenu"}, template("fullmenu/fullmenu"), "Menu Selection", 96) + page.dependent = true + + entry({"admin", "system", "getmenu"}, call("action_getmenu")) + entry({"admin", "system", "setmenu"}, call("action_setmenu")) + +end + +function action_getmenu() + local rv = {} + id = luci.model.uci.cursor():get("custom", "menu", "full") + rv["full"] = id + password = luci.model.uci.cursor():get("custom", "menu", "password") + rv["password"] = password + + luci.http.prepare_content("application/json") + luci.http.write_json(rv) +end + +function action_setmenu() + local set = luci.http.formvalue("set") + os.execute("/usr/lib/fullmenu/setmenu.sh " .. set) + +end \ No newline at end of file diff --git a/rooter/0optionalapps/ext-menu/files/usr/lib/lua/luci/view/fullmenu/fullmenu.htm b/rooter/0optionalapps/ext-menu/files/usr/lib/lua/luci/view/fullmenu/fullmenu.htm new file mode 100644 index 0000000..a08e06d --- /dev/null +++ b/rooter/0optionalapps/ext-menu/files/usr/lib/lua/luci/view/fullmenu/fullmenu.htm @@ -0,0 +1,166 @@ +<%+header%> +<% +local sys = require "luci.sys" +local utl = require "luci.util" +local fs = require "nixio.fs" + +function showicon(lck) + if lck == 0 then + return resource .. "/icons/unlock1.png" + else + return resource .. "/icons/lock1.png" + end +end + +-%> + + + +
      +
      +

      <%:Menu Selection%>

      +
      + + + + +
      + + + + + + + + + + + + + + + + + + + + + + +
      <%:Current Menu is Limited.%>
      <%:You must enter a password to change to the full Menu.%>
      + + + + + + + + + + + + + + +
      <%:Current Menu is Full.%>
      <%:You must enter a password to change to the limited Menu.%>
      + +
      + +
      +
      +<%+footer%> \ No newline at end of file diff --git a/rooter/0optionalapps/ext-speedtest/files/usr/lib/lua/luci/controller/speedtest.lua b/rooter/0optionalapps/ext-speedtest/files/usr/lib/lua/luci/controller/speedtest.lua index 0a70363..2c78f99 100644 --- a/rooter/0optionalapps/ext-speedtest/files/usr/lib/lua/luci/controller/speedtest.lua +++ b/rooter/0optionalapps/ext-speedtest/files/usr/lib/lua/luci/controller/speedtest.lua @@ -1,7 +1,11 @@ module("luci.controller.speedtest", package.seeall) + +I18N = require "luci.i18n" +translate = I18N.translate + function index() local page - entry({"admin", "speed"}, firstchild(), "Speed Test", 81).dependent=false - page = entry({"admin", "speed", "speedtest"}, template("speedtest/speedtest"), "OpenSpeedTest", 71) + entry({"admin", "speed"}, firstchild(), translate("Speed Test"), 95).dependent=false + page = entry({"admin", "speed", "speedtest"}, template("speedtest/speedtest"), translate("OpenSpeedTest"), 71) page.dependent = true end diff --git a/rooter/0optionalapps/ext-speedtest/files/usr/lib/lua/luci/view/speedtest/speedtest.htm b/rooter/0optionalapps/ext-speedtest/files/usr/lib/lua/luci/view/speedtest/speedtest.htm index 53317d1..8f731de 100644 --- a/rooter/0optionalapps/ext-speedtest/files/usr/lib/lua/luci/view/speedtest/speedtest.htm +++ b/rooter/0optionalapps/ext-speedtest/files/usr/lib/lua/luci/view/speedtest/speedtest.htm @@ -17,8 +17,8 @@
      -

      Browser Speed Test

      -
      A Speed Test using OpenSpeedTest that runs in the browser
      +

      <%:Browser Speed Test%>

      +
      <%:A Speed Test using OpenSpeedTest that runs in the browser%>
      diff --git a/rooter/0optionalapps/ext-texting/files/usr/lib/lua/luci/controller/texting.lua b/rooter/0optionalapps/ext-texting/files/usr/lib/lua/luci/controller/texting.lua index c0c5585..a729365 100644 --- a/rooter/0optionalapps/ext-texting/files/usr/lib/lua/luci/controller/texting.lua +++ b/rooter/0optionalapps/ext-texting/files/usr/lib/lua/luci/controller/texting.lua @@ -1,8 +1,16 @@ module("luci.controller.texting", package.seeall) function index() local lock = luci.model.uci.cursor():get("custom", "menu", "full") - if lock == "1" then - entry({"admin", "adminmenu", "texting"}, cbi("fullmenu/texting"), "---Random Texting", 8) + local multilock = luci.model.uci.cursor():get("custom", "multiuser", "multi") or "0" + local rootlock = luci.model.uci.cursor():get("custom", "multiuser", "root") or "0" + if (multilock == "0") or (multilock == "1" and rootlock == "1") then + if lock == "1" then + if (multilock == "1" and rootlock == "1") then + entry({"admin", "adminmenu", "texting"}, cbi("fullmenu/texting"), "Random Texting", 9) + else + entry({"admin", "adminmenu", "texting"}, cbi("fullmenu/texting"), "---Random Texting", 9) + end + end end entry({"admin", "services", "chksms"}, call("action_chksms")) diff --git a/rooter/0optionalapps/ext-throttle/Makefile b/rooter/0optionalapps/ext-throttle/Makefile new file mode 100644 index 0000000..cf731cc --- /dev/null +++ b/rooter/0optionalapps/ext-throttle/Makefile @@ -0,0 +1,36 @@ +#Owned by DairyMan@Whirlpool +# +#Copyright GNU act. +include $(TOPDIR)/rules.mk + +PKG_NAME:=ext-throttle +PKG_VERSION:=1.000 +PKG_RELEASE:=1 + +PKG_MAINTAINER:=Created by DM/makefile by Cobia@whirlpool +include $(INCLUDE_DIR)/package.mk + +define Package/ext-throttle + SECTION:=utils + CATEGORY:=ROOter + SUBMENU:=Optional Applications + DEPENDS:=+tc +kmod-sched-core +kmod-ifb +iptables \ + +iptables-mod-ipopt +iptables-mod-conntrack-extra \ + +kmod-sched-cake + TITLE:=support for Throttle + PKGARCH:=all +endef + +define Package/ext-throttle/description + Helper scripts to enable Throttle +endef + + +define Build/Compile +endef + +define Package/ext-throttle/install + $(CP) ./files/* $(1)/ +endef + +$(eval $(call BuildPackage,ext-throttle)) diff --git a/rooter/0optionalapps/ext-throttle/files/etc/config/sqm b/rooter/0optionalapps/ext-throttle/files/etc/config/sqm new file mode 100644 index 0000000..67f58de --- /dev/null +++ b/rooter/0optionalapps/ext-throttle/files/etc/config/sqm @@ -0,0 +1,34 @@ + +config queue 'wan' + option enabled '0' + option download '85000' + option upload '10000' + option qdisc 'cake' + option script 'piece_of_cake.qos' + option linklayer 'none' + option interface '0' + option debug_logging '0' + option verbosity '5' + +config queue 'wan1' + option enabled '0' + option download '85000' + option upload '10000' + option qdisc 'cake' + option script 'piece_of_cake.qos' + option linklayer 'none' + option debug_logging '0' + option verbosity '5' + option interface '0' + +config queue 'wan2' + option enabled '0' + option download '85000' + option upload '10000' + option qdisc 'cake' + option script 'piece_of_cake.qos' + option linklayer 'none' + option interface '0' + option debug_logging '0' + option verbosity '5' + diff --git a/rooter/0optionalapps/ext-throttle/files/etc/hotplug.d/iface/11-sqm b/rooter/0optionalapps/ext-throttle/files/etc/hotplug.d/iface/11-sqm new file mode 100644 index 0000000..75ff4ea --- /dev/null +++ b/rooter/0optionalapps/ext-throttle/files/etc/hotplug.d/iface/11-sqm @@ -0,0 +1,27 @@ +#!/bin/sh + +if [ "$ACTION" = ifdown ]; then + if [ $INTERFACE = "wan" -o $INTERFACE = "wan1" -o $INTERFACE = "wan2" ]; then + uci set sqm.$INTERFACE.interface='0' + uci commit sqm + logger -t THROTTLE-DEBUG "$ACTION $INTERFACE" + fi +fi + +[ -n "$DEVICE" ] || exit 0 + +restart_sqm() { + /usr/lib/sqm/run.sh stop ${DEVICE} + /usr/lib/sqm/run.sh start ${DEVICE} +} + +if [ "$ACTION" = ifup ]; then + if [ $INTERFACE = "wan" -o $INTERFACE = "wan1" -o $INTERFACE = "wan2" ]; then + uci set sqm.$INTERFACE.interface=$DEVICE + uci commit sqm + /etc/init.d/sqm enabled + restart_sqm + logger -t THROTTLE-DEBUG "$DEVICE $ACTION $INTERFACE" + fi +fi + diff --git a/rooter/0optionalapps/ext-throttle/files/etc/init.d/sqm b/rooter/0optionalapps/ext-throttle/files/etc/init.d/sqm new file mode 100644 index 0000000..3badb62 --- /dev/null +++ b/rooter/0optionalapps/ext-throttle/files/etc/init.d/sqm @@ -0,0 +1,31 @@ +#!/bin/sh /etc/rc.common + +START=50 +USE_PROCD=1 + +service_triggers() +{ + procd_add_reload_trigger "sqm" +} + +reload_service() +{ + stop "$@" + start "$@" +} + +start_service() +{ + /usr/lib/sqm/run.sh start "$@" +} + +stop_service() +{ + /usr/lib/sqm/run.sh stop "$@" +} + +boot() +{ + export SQM_VERBOSITY_MIN=5 # Silence errors + start "$@" +} diff --git a/rooter/0optionalapps/ext-throttle/files/etc/sqm/sqm.conf b/rooter/0optionalapps/ext-throttle/files/etc/sqm/sqm.conf new file mode 100644 index 0000000..b9a98b4 --- /dev/null +++ b/rooter/0optionalapps/ext-throttle/files/etc/sqm/sqm.conf @@ -0,0 +1,5 @@ +SQM_LIB_DIR=/usr/lib/sqm +SQM_STATE_DIR=/var/run/sqm +SQM_QDISC_STATE_DIR=${SQM_STATE_DIR}/available_qdiscs +SQM_CHECK_QDISCS="fq_codel codel pie sfq cake" +SQM_SYSLOG=1 diff --git a/rooter/0optionalapps/ext-throttle/files/etc/uci-defaults/50-luci-sqm b/rooter/0optionalapps/ext-throttle/files/etc/uci-defaults/50-luci-sqm new file mode 100644 index 0000000..b3aa47c --- /dev/null +++ b/rooter/0optionalapps/ext-throttle/files/etc/uci-defaults/50-luci-sqm @@ -0,0 +1,12 @@ +#!/bin/sh + +uci -q batch <<-EOF >/dev/null + delete ucitrack.@sqm[-1] + add ucitrack sqm + set ucitrack.@sqm[-1].init=sqm + del_list ucitrack.@firewall[0].affects=sqm + add_list ucitrack.@firewall[0].affects=sqm + commit ucitrack +EOF + +exit 0 diff --git a/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/defaults.sh b/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/defaults.sh new file mode 100644 index 0000000..009cfc6 --- /dev/null +++ b/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/defaults.sh @@ -0,0 +1,109 @@ +# You need to jiggle these parameters. Note limits are tuned towards a <10Mbit uplink <60Mbup down + +[ -z "$SCRIPT" ] && SCRIPT= +[ -z "$UPLINK" ] && UPLINK=2302 +[ -z "$DOWNLINK" ] && DOWNLINK=14698 +[ -z "$IFACE" ] && IFACE=eth0 +[ -z "$QDISC" ] && QDISC=fq_codel +[ -z "$LLAM" ] && LLAM="default" +[ -z "$LINKLAYER" ] && LINKLAYER="none" +[ -z "$OVERHEAD" ] && OVERHEAD=0 +[ -z "$STAB_MTU" ] && STAB_MTU=2047 +[ -z "$STAB_MPU" ] && STAB_MPU=0 +[ -z "$STAB_TSIZE" ] && STAB_TSIZE=512 +[ -z "$AUTOFLOW" ] && AUTOFLOW=0 +[ -z "$LIMIT" ] && LIMIT=1001 # sane global default for *LIMIT for fq_codel on a small memory device +[ -z "$ILIMIT" ] && ILIMIT= +[ -z "$ELIMIT" ] && ELIMIT= +[ -z "$ITARGET" ] && ITARGET= +[ -z "$ETARGET" ] && ETARGET= +[ -z "$IECN" ] && IECN="ECN" +[ -z "$EECN" ] && EECN="ECN" +# These two used to be called something else; preserve backwards compatibility +[ -z "$ZERO_DSCP_INGRESS" ] && ZERO_DSCP_INGRESS="${ZERO_DSCP:-${SQUASH_DSCP:-1}}" +[ -z "$IGNORE_DSCP_INGRESS" ] && IGNORE_DSCP_INGRESS="${IGNORE_DSCP:-${SQUASH_INGRESS:-1}}" + +[ -z "$IQDISC_OPTS" ] && IQDISC_OPTS="" +[ -z "$EQDISC_OPTS" ] && EQDISC_OPTS="" + +# handling of specific important binaries +[ -z "$TC" ] && TC=tc_wrapper +[ -z "$TC_BINARY" ] && TC_BINARY=$(command -v tc) +[ -z "$IP" ] && IP=ip_wrapper +[ -z "$IP_BINARY" ] && IP_BINARY=$(command -v ip) +[ -z "$IPTABLES" ] && IPTABLES=iptables_wrapper +[ -z "$IPTABLES_BINARY" ] && IPTABLES_BINARY=$(command -v iptables) +[ -z "$IP6TABLES" ] && IP6TABLES=ip6tables_wrapper +[ -z "$IP6TABLES_BINARY" ] && IP6TABLES_BINARY=$(command -v ip6tables) +[ -z "$IPTABLES_ARGS" ] && IPTABLES_ARGS="-w 1" + + +# Try modprobe first, fall back to insmod +if [ -z "$INSMOD" ]; then + INSMOD=$(command -v modprobe) + if [ -n "$INSMOD" ]; then + INSMOD="${INSMOD} -q" + else + INSMOD=$(command -v insmod) + fi +fi + +[ -z "$TARGET" ] && TARGET="5ms" +[ -z "$IPT_MASK" ] && IPT_MASK="0xff" # to disable: set mask to 0xffffffff +#sm: we need the functions above before trying to set the ingress IFB device +#sm: *_CAKE_OPTS should contain the diffserv keyword for cake +[ -z "$INGRESS_CAKE_OPTS" ] && INGRESS_CAKE_OPTS="diffserv3" +[ -z "$EGRESS_CAKE_OPTS" ] && EGRESS_CAKE_OPTS="diffserv3" + +[ -z "$CUR_DIRECTION" ] && CUR_DIRECTION="NONE" + + +# HTB without a sufficiently large burst/cburst value is a bit CPU hungry +# so allow to specify the permitted burst in the time domain (microseconds) +# so the user has a feeling for the associated worst case latency cost +# set to zero to use htb default butst of one MTU +[ -z "$SHAPER_BURST_DUR_US" ] && SHAPER_BURST_DUR_US=1000 +[ -z "$ISHAPER_BURST_DUR_US" ] && ISHAPER_BURST_DUR_US=$SHAPER_BURST_DUR_US +[ -z "$ESHAPER_BURST_DUR_US" ] && ESHAPER_BURST_DUR_US=$SHAPER_BURST_DUR_US + +# use the same logic for the calculation of htb's quantum +# quantum controlls how many bytes htb tries to deque from the current tier +# before switching tiers. +[ -z "$SHAPER_QUANTUM_DUR_US" ] && SHAPER_QUANTUM_DUR_US=$SHAPER_BURST_DUR_US +[ -z "$ISHAPER_QUANTUM_DUR_US" ] && ISHAPER_QUANTUM_DUR_US=$SHAPER_QUANTUM_DUR_US +[ -z "$ESHAPER_QUANTUM_DUR_US" ] && ESHAPER_QUANTUM_DUR_US=$SHAPER_QUANTUM_DUR_US + + +# Logging verbosity +VERBOSITY_SILENT=0 +VERBOSITY_ERROR=1 +VERBOSITY_WARNING=2 +VERBOSITY_INFO=5 +VERBOSITY_DEBUG=8 +VERBOSITY_TRACE=10 +[ -z "$SQM_VERBOSITY_MAX" ] && SQM_VERBOSITY_MAX=$VERBOSITY_INFO +# For silencing only errors +[ -z "$SQM_VERBOSITY_MIN" ] && SQM_VERBOSITY_MIN=$VERBOSITY_SILENT + +[ -z "$SQM_DEBUG" ] && SQM_DEBUG=0 +if [ "$SQM_DEBUG" -eq "1" ] +then + SQM_DEBUG_STEM="${SQM_STATE_DIR}/${IFACE}" + SQM_START_LOG="${SQM_DEBUG_STEM}.start-sqm.log" + SQM_STOP_LOG="${SQM_DEBUG_STEM}.stop-sqm.log" + [ -z "SQM_DEBUG_LOG" ] && SQM_DEBUG_LOG="${SQM_DEBUG_STEM}.debug.log" + OUTPUT_TARGET="${SQM_DEBUG_LOG}" +else + OUTPUT_TARGET="/dev/null" +fi + + +# Can be overridden by callers that want to silence error output for a +# particular command +SILENT=0 + +# Transaction log for unwinding ipt rules +IPT_TRANS_LOG="${SQM_STATE_DIR}/${IFACE}.iptables.log" + +# These are the modules that do_modules() will attempt to load +ALL_MODULES="act_ipt sch_$QDISC sch_ingress act_mirred cls_fw cls_flow cls_u32 sch_htb sch_hfsc" diff --git a/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/functions.sh b/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/functions.sh new file mode 100644 index 0000000..c61edfa --- /dev/null +++ b/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/functions.sh @@ -0,0 +1,923 @@ +################################################################################ +# (sqm) functions.sh +# +# These are all helper functions for various parts of SQM scripts. If you want +# to play around with your own shaper-qdisc-filter configuration look here for +# ready made tools, or examples start of on your own. +# +# Please note the SQM logger function is broken down into levels of logging. +# Use only levels appropriate to touch points in your script and realize the +# potential to overflow SYSLOG. +# +################################################################################ +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# Copyright (C) 2012-2019 +# Michael D. Taht, Toke Høiland-Jørgensen, Sebastian Moeller +# Eric Luehrsen +# +################################################################################ + +# Logging verbosity +VERBOSITY_SILENT=0 +VERBOSITY_ERROR=1 +VERBOSITY_WARNING=2 +VERBOSITY_INFO=5 +VERBOSITY_DEBUG=8 +VERBOSITY_TRACE=10 + +sqm_logger() { + local level_min + local level_max + local debug + + case $1 in + ''|*[!0-9]*) LEVEL=$VERBOSITY_INFO ;; # empty or non-numbers + *) LEVEL=$1; shift ;; + esac + + level_min=${SQM_VERBOSITY_MIN:-$VERBOSITY_SILENT} + level_max=${SQM_VERBOSITY_MAX:-$VERBOSITY_INFO} + debug=${SQM_DEBUG:-0} + + if [ "$level_max" -ge "$LEVEL" ] && [ "$level_min" -le "$LEVEL" ] ; then + if [ "$SQM_SYSLOG" -eq "1" ]; then + logger -t SQM -s "$*" + else + echo "$@" >&2 + fi + fi + + # this writes into SQM_START_LOG or SQM_STOP_LOG, log files are trucated in + # start-sqm/stop-sqm respectively and should only take little space + if [ "$debug" -eq "1" ]; then + echo "$@" >> "${SQM_DEBUG_LOG}" + fi +} + +sqm_error() { sqm_logger $VERBOSITY_ERROR ERROR: "$@"; } +sqm_warn() { sqm_logger $VERBOSITY_WARNING WARNING: "$@"; } +sqm_log() { sqm_logger $VERBOSITY_INFO "$@"; } +sqm_debug() { sqm_logger $VERBOSITY_DEBUG "$@"; } +sqm_trace() { sqm_logger $VERBOSITY_TRACE "$@"; } + + +# Inspired from https://stackoverflow.com/questions/85880/determine-if-a-function-exists-in-bash +#fn_exists() { LC_ALL=C type $1 | grep -q 'is a function'; } +fn_exists() { + local FN_CANDIDATE + local CUR_LC_ALL + local TYPE_OUTPUT + local RET + FN_CANDIDATE=$1 + # check that a candidate nme was given + if [ -z "${FN_CANDIDATE}" ]; then + sqm_error "fn_exists: no function name specified as first argument." + return 1 + fi + sqm_debug "fn_exists: function candidate name: ${FN_CANDIDATE}" + + # extract the textual type description + TYPE_OUTPUT=$( LC_ALL=C type $1 2>&1 ) + sqm_debug "fn_exists: TYPE_OUTPUT: $TYPE_OUTPUT" + + # OpenWrt (2019) returns 'is a function' + # Debian Buster/raspbian returns 'is a shell function' + # let's just hope no Linux system reurn 'is a shell builtin function' + echo ${TYPE_OUTPUT} | grep -q 'is .*function' + RET=$? + + sqm_debug "fn_exists: return value: ${RET}" + return ${RET} +} + + +# Transaction logging for ipt rules to allow for gracefull final teardown +ipt_log_restart() { + [ -f "$IPT_TRANS_LOG" ] && rm -f "$IPT_TRANS_LOG" +} + + +# Function to negate iptables commands. Turns addition and insertion into +# deletion, and creation of new chains into deletion +# Its output has quotes around all parameters so we can preserve arguments +# containing whitespace across log file write & re-read +ipt_negate() +{ + for var in "$@"; do + case "$var" in + "-A"|"-I") echo -n '"-D" ' ;; + "-N") echo -n '"-X" ' ;; + *) echo -n "\"$var\" " ;; + esac + done + echo "" +} + +ipt_log() +{ + echo "$@" >> $IPT_TRANS_LOG +} + +# Split a string containing an iptables command line parameter invocation, then +# run it through ipt(). This is used to turn lines read from the log file, or +# output from ipt_negate() back into proper parameters contained in $@ +ipt_run_split() +{ + eval "set -- $1" + ipt "$@" +} + +# Read the transaction log in reverse and execute using ipt to undo changes. +# Since we logged only ipt '-D' commands, ipt won't add them again to the +# transaction log, but will include them in the syslog/debug log. +ipt_log_rewind() { + [ -f "$IPT_TRANS_LOG" ] || return 0 + sed -n '1!G;h;$p' "$IPT_TRANS_LOG" | + while read line; do + [ -n "$line" ] || continue + ipt_run_split "$line" + done +} + +ipt() { + local neg + + for var in "$@"; do + case "$var" in + "-A"|"-I"|"-N") + # If the rule is an addition rule, we first run its negation, + # then log that negation to be used by ipt_log_rewind() on + # shutdown + neg="$(ipt_negate "$@")" + ipt_run_split "$neg" + ipt_log "$neg" + ;; + esac + done + + SILENT=1 ${IPTABLES} $IPTABLES_ARGS "$@" + SILENT=1 ${IP6TABLES} $IPTABLES_ARGS "$@" +} + + +# wrapper to call iptables to allow debug logging +iptables_wrapper(){ + cmd_wrapper iptables ${IPTABLES_BINARY} "$@" +} + +# wrapper to call ip6tables to allow debug logging +ip6tables_wrapper(){ + cmd_wrapper ip6tables ${IP6TABLES_BINARY} "$@" +} + +# wrapper to call tc to allow debug logging +tc_wrapper(){ + cmd_wrapper tc ${TC_BINARY} "$@" +} + +# wrapper to call ip to allow debug logging +ip_wrapper(){ + cmd_wrapper ip ${IP_BINARY} "$@" +} + +# the actual command execution wrapper +cmd_wrapper(){ + # $1: the symbolic name of the command for informative output + # $2: the name of the binary to call (potentially including the full path) + # $3-$end: the actual arguments for $2 + local CALLERID + local CMD_BINARY + local LAST_ERROR + local RET + local ERRLOG + + CALLERID=$1 ; shift 1 # extract and remove the id string + CMD_BINARY=$1 ; shift 1 # extract and remove the binary + + # Handle silencing of errors from callers + ERRLOG="sqm_error" + if [ "$SILENT" -eq "1" ]; then + ERRLOG="sqm_debug" + sqm_debug "cmd_wrapper: ${CALLERID}: invocation silenced by request, FAILURE either expected or acceptable." + # The busybox shell doesn't understand the concept of an inline variable + # only applying to a single command, so we need to reset SILENT + # afterwards. Ugly, but it works... + SILENT=0 + fi + + sqm_trace "cmd_wrapper: COMMAND: ${CMD_BINARY} $@" + LAST_ERROR=$( ${CMD_BINARY} "$@" 2>&1 ) + RET=$? + + if [ "$RET" -eq "0" ] ; then + sqm_debug "cmd_wrapper: ${CALLERID}: SUCCESS: ${CMD_BINARY} $@" + else + # this went south, try to capture & report more detail + $ERRLOG "cmd_wrapper: ${CALLERID}: FAILURE (${RET}): ${CMD_BINARY} $@" + $ERRLOG "cmd_wrapper: ${CALLERID}: LAST ERROR: ${LAST_ERROR}" + fi + + return $RET +} + + +do_modules() { + for m in $ALL_MODULES; do + [ -d /sys/module/${m} ] || ${INSMOD} $m 2>>${OUTPUT_TARGET} + done +} + +# Write a state file to the filename given as $1. This version will extract all +# variable names defined in defaults.sh and since defaults.sh should contain all +# used variables this should be the complete set. +write_state_file() { + local filename + local awkscript + awkscript='match($0, /[A-Z0-9_]+=/) {print substr($0, RSTART, RLENGTH-1)}' + filename=$1 + shift + awk "$awkscript" ${SQM_LIB_DIR}/defaults.sh | sort -u | while read var; do + val=$(eval echo '$'$var) + echo "$var=\"$val\"" + done > $filename +} + +check_state_dir() { + local PERM + local OWNER + + if [ -z "${SQM_STATE_DIR}" ]; then + SQM_DEBUG=0 sqm_error '$SQM_STATE_DIR is unset - check your config!' + exit 1 + fi + [ -d "${SQM_STATE_DIR}" ] || ( umask 077; mkdir -p "$SQM_STATE_DIR" ) || exit 1 + + if [ ! -w "${SQM_STATE_DIR}" ] || [ ! -x "${SQM_STATE_DIR}" ]; then + SQM_DEBUG=0 sqm_error "Cannot write to state dir '$SQM_STATE_DIR'" + exit 1 + fi + + # OpenWrt doesn't have stat; for now just skip the remaining tests if it's + # not available + command -v stat >/dev/null 2>&1 || return 0 + + PERM="0$(stat -L -c '%a' "${SQM_STATE_DIR}")" + if [ "$((PERM & 0002))" -ne 0 ]; then + SQM_DEBUG=0 sqm_error "State dir '$SQM_STATE_DIR' is world writable; this is unsafe, please fix" + exit 1 + fi + OWNER="$(stat -L -c '%u' "${SQM_STATE_DIR}")" + if [ "$OWNER" -ne "$(id -u)" ]; then + SQM_DEBUG=0 sqm_error "State dir '$SQM_STATE_DIR' is owned by a different user; this is unsafe, please fix" + exit 1 + fi +} + + +# find the ifb device associated with a specific interface, return nothing of no +# ifb is associated with IF +get_ifb_associated_with_if() { + local CUR_IF + local CUR_IFB + local TMP + CUR_IF=$1 + # Stray ' in the comment is a fix for broken editor syntax highlighting + CUR_IFB=$( $TC_BINARY -p filter show parent ffff: dev ${CUR_IF} | grep -o -E ifb'[^)\ ]+' ) # ' + sqm_debug "ifb associated with interface ${CUR_IF}: ${CUR_IFB}" + + # we could not detect an associated IFB for CUR_IF + if [ -z "${CUR_IFB}" ]; then + TMP=$( $TC_BINARY -p filter show parent ffff: dev ${CUR_IF} ) + if [ ! -z "${TMP}" ]; then + # oops, there is output but we failed to properly parse it? Ask for a user report + sqm_error "#---- CUT HERE ----#" + sqm_error "get_ifb_associated_with_if failed to extrect the ifb name from:" + sqm_error $( $TC_BINARY -p filter show parent ffff: dev ${CUR_IF} ) + sqm_error "Please report this as an issue at https://github.com/tohojo/sqm-scripts" + sqm_error "Please copy and paste everything below the cut-here line into your issue report, thanks." + else + sqm_debug "Currently no ifb is associated with ${CUR_IF}, this is normal during starting of the sqm system." + fi + fi + echo ${CUR_IFB} +} + +ifb_name() { + local CUR_IF + local MAX_IF_NAME_LENGTH + local IFB_PREFIX + local NEW_IFB + CUR_IF=$1 + MAX_IF_NAME_LENGTH=15 + IFB_PREFIX="ifb4" + NEW_IFB=$( echo -n "${IFB_PREFIX}${CUR_IF}" | head -c $MAX_IF_NAME_LENGTH ) + + echo ${NEW_IFB} +} + +# if required +create_new_ifb_for_if() { + local NEW_IFB + NEW_IFB=$(ifb_name $1) + create_ifb ${NEW_IFB} + RET=$? + echo $NEW_IFB + return $RET +} + + +# TODO: report failures +create_ifb() { + local CUR_IFB + CUR_IFB=${1} + $IP link add name ${CUR_IFB} type ifb +} + +delete_ifb() { + local CUR_IFB + CUR_IFB=${1} + $IP link set dev ${CUR_IFB} down + $IP link delete ${CUR_IFB} type ifb +} + + +# the best match is either the IFB already associated with the current interface +# or a new named IFB +get_ifb_for_if() { + local CUR_IF + local CUR_IFB + CUR_IF=$1 + # if an ifb is already associated return that + CUR_IFB=$( get_ifb_associated_with_if ${CUR_IF} ) + [ -z "$CUR_IFB" ] && CUR_IFB=$( create_new_ifb_for_if ${CUR_IF} ) + [ -z "$CUR_IFB" ] && sqm_warn "Could not find existing IFB for ${CUR_IF}, nor create a new IFB instead..." + echo ${CUR_IFB} +} + + +# Verify that a qdisc works, and optionally that it is part of a set of +# supported qdiscs. If passed a $2, this function will first check if $1 is in +# that (space-separated) list and return an error if it's not. +# +# note the ingress qdisc is different in that it requires tc qdisc replace dev +# tmp_ifb ingress instead of "root ingress" +verify_qdisc() { + local qdisc + local supported + local ifb + local root_string + local args + local IFB_MTU + local found + local randnum + qdisc=$1 + supported="$2" + randnum=$(tr -cd 0-9a-f < /dev/urandom 2>/dev/null | head -c 5) + ifb=SQM_IFB_$randnum + root_string="root" # this works for most qdiscs + args="" + IFB_MTU=1514 + + if [ -n "$supported" ]; then + found=0 + for q in $supported; do + [ "$qdisc" = "$q" ] && found=1 + done + [ "$found" -eq "1" ] || return 1 + fi + create_ifb $ifb || return 1 + + + case $qdisc in + #ingress is special + ingress) root_string="" ;; + #cannot instantiate tbf without args + tbf) + IFB_MTU=$( get_mtu $ifb ) + IFB_MTU=$(( ${IFB_MTU} + 14 )) # TBF's warning is confused, it says MTU but it checks MTU + 14 + args="limit 1 burst ${IFB_MTU} rate 1kbps" + ;; + esac + + $TC qdisc replace dev $ifb $root_string $qdisc $args + res=$? + if [ "$res" = "0" ] ; then + sqm_debug "QDISC $qdisc is useable." + else + sqm_error "QDISC $qdisc is NOT useable." + fi + delete_ifb $ifb + return $res +} + + +get_htb_adsll_string() { + ADSLL="" + if [ "$LLAM" = "htb_private" -a "$LINKLAYER" != "none" ]; then + # HTB defaults to MTU 1600 and an implicit fixed TSIZE of 256, but HTB + # as of around 3.10.0 does not actually use a table in the kernel + ADSLL="mpu ${STAB_MPU} linklayer ${LINKLAYER} overhead ${OVERHEAD} mtu ${STAB_MTU}" + sqm_debug "ADSLL: ${ADSLL}" + fi + echo ${ADSLL} +} + +get_stab_string() { + local STABSTRING + local TMP_LLAM + STABSTRING="" + TMP_LLAM=${LLAM} + if [ "${LLAM}" = "default" -a "$QDISC" != "cake" ]; then + sqm_debug "LLA: default link layer adjustment method for !cake is tc_stab" + TMP_LLAM="tc_stab" + fi + + if [ "${TMP_LLAM}" = "tc_stab" -a "$LINKLAYER" != "none" ]; then + STABSTRING="stab mtu ${STAB_MTU} tsize ${STAB_TSIZE} mpu ${STAB_MPU} overhead ${OVERHEAD} linklayer ${LINKLAYER}" + sqm_debug "STAB: ${STABSTRING}" + fi + echo ${STABSTRING} +} + +# cake knows how to handle ATM and per packet overhead, so expose and use this... +get_cake_lla_string() { + local STABSTRING + local TMP_LLAM + STABSTRING="" + TMP_LLAM=${LLAM} + if [ "${LLAM}" = "default" -a "$QDISC" = "cake" ]; then + sqm_debug "LLA: default link layer adjustment method for cake is cake" + TMP_LLAM="cake" + fi + + if [ "${TMP_LLAM}" = "cake" -a "${LINKLAYER}" != "none" ]; then + if [ "${LINKLAYER}" = "atm" ]; then + STABSTRING="atm" + fi + + STABSTRING="${STABSTRING} overhead ${OVERHEAD} mpu ${STAB_MPU}" + + sqm_debug "cake link layer adjustments: ${STABSTRING}" + fi + echo ${STABSTRING} +} + + +# centralize the implementation for the default sqm_start sqeuence +# the individual sqm_start function only need to do the individually +# necessary checking. +# This expects the calling script to supply both an egress() and ingress() function +# and will warn if they are missing +sqm_start_default() { + #sqm_error "sqm_start_default" + [ -n "$IFACE" ] || return 1 + + # reset the iptables trace log + ipt_log_restart + + if fn_exists sqm_prepare_script ; then + sqm_debug "sqm_start_default: starting sqm_prepare_script" + sqm_prepare_script + else + sqm_debug "sqm_start_default: no sqm_prepare_script function found, proceeding without." + fi + + do_modules + verify_qdisc $QDISC || return 1 + sqm_debug "sqm_start_default: Starting ${SCRIPT}" + + [ -z "$DEV" ] && DEV=$( get_ifb_for_if ${IFACE} ) + + if [ "${UPLINK}" -ne 0 ]; + then + CUR_DIRECTION="egress" + fn_exists egress && egress || sqm_warn "sqm_start_default: ${SCRIPT} lacks an egress() function" + #egress + sqm_debug "sqm_start_default: egress shaping activated" + else + sqm_debug "sqm_start_default: egress shaping deactivated" + SILENT=1 $TC qdisc del dev ${IFACE} root + fi + if [ "${DOWNLINK}" -ne 0 ]; + then + CUR_DIRECTION="ingress" + verify_qdisc ingress "ingress" || return 1 + fn_exists ingress && ingress || sqm_warn "sqm_start_default: ${SCRIPT} lacks an ingress() function" + #ingress + sqm_debug "sqm_start_default: ingress shaping activated" + else + sqm_debug "sqm_start_default: ingress shaping deactivated" + SILENT=1 $TC qdisc del dev ${DEV} root + SILENT=1 $TC qdisc del dev ${IFACE} ingress + fi + + return 0 +} + + +sqm_stop() { + if [ "${DOWNLINK}" -ne 0 ]; then + $TC qdisc del dev $IFACE ingress + $TC qdisc del dev $IFACE root + [ -n "$CUR_IFB" ] && $TC qdisc del dev $CUR_IFB root + [ -n "$CUR_IFB" ] && sqm_debug "${0}: ${CUR_IFB} shaper deleted" + fi + + # undo accumulated ipt commands during shutdown + ipt_log_rewind + # reset the iptables trace log + ipt_log_restart + + [ -n "$CUR_IFB" ] && $IP link set dev ${CUR_IFB} down + [ -n "$CUR_IFB" ] && $IP link delete ${CUR_IFB} type ifb + [ -n "$CUR_IFB" ] && sqm_debug "${0}: ${CUR_IFB} interface deleted" +} + +# Note this has side effects on the prio variable +# and depends on the interface global too +fc() { + $TC filter add dev $interface protocol ip parent $1 prio $prio u32 match ip tos $2 0xfc classid $3 + prio=$(($prio + 1)) + $TC filter add dev $interface protocol ipv6 parent $1 prio $prio u32 match ip6 priority $2 0xfc classid $3 + prio=$(($prio + 1)) +} + + +# allow better control over HTB's quantum variable +# this controlls how many bytes htb ties to deque from the current tier before +# switching to the next, if this is large mixing between pririty tiers will be +# lumpy, but at a lower CPU cost. In first approximation quantum should not be +# larger than burst. +get_htb_quantum() { + local HTB_MTU + local BANDWIDTH + local DURATION_US + local MIN_QUANTUM + local QUANTUM + HTB_MTU=$( get_mtu $1 ) + BANDWIDTH=$2 + DURATION_US=$3 + + sqm_debug "get_htb_quantum: 1: ${1}, 2: ${2}, 3: ${3}" + + if [ -z "${DURATION_US}" ] ; then + DURATION_US=${SHAPER_QUANTUM_DUR_US} # the duration of the burst in microseconds + sqm_warn "get_htb_quantum (by duration): Defaulting to ${DURATION_US} microseconds." + fi + + if [ -n "${HTB_MTU}" -a "${DURATION_US}" -gt "0" ] ; then + QUANTUM=$( get_burst ${HTB_MTU} ${BANDWIDTH} ${DURATION_US} ) + fi + + if [ -z "$QUANTUM" ]; then + MIN_QUANTUM=$(( ${MTU} + 48 )) # add 48 bytes to MTU for the ovehead + MIN_QUANTUM=$(( ${MIN_QUANTUM} + 47 )) # now do ceil(Min_BURST / 48) * 53 in shell integer arithmic + MIN_QUANTUM=$(( ${MIN_QUANTUM} / 48 )) + MIN_QUANTUM=$(( ${MIN_QUANTUM} * 53 )) # for MTU 1489 to 1536 this will result in MIN_BURST = 1749 Bytes + sqm_warn "get_htb_quantum: 0 bytes quantum will not work, defaulting to one ATM/AAL5 expanded MTU packet with overhead: ${MIN_QUANTUM}" + echo ${MIN_QUANTUM} + else + echo ${QUANTUM} + fi +} + + + + +# try to define the burst parameter in the duration required to transmit a burst +# at the configured bandwidth conceptuallly the matching quantum for this burst +# should be BURST/number_of_tiers to give each htb tier a chance to dequeue into +# each burst, but that most likely will end up with a somewhat too small quantum +# note: to get htb to report the configured burst/cburt one needs to issue the +# following command (for ifbpppoe-wan): +# tc -d class show dev ifb4pppoe-wan +get_burst() { + local MTU + local BANDWIDTH + local SHAPER_BURST_US + local MIN_BURST + local BURST + MTU=$1 + BANDWIDTH=$2 # note bandwidth is always given in kbps + SHAPER_BURST_US=$3 + + sqm_debug "get_burst: 1: ${1}, 2: ${2}, 3: ${3}" + + if [ -z "${SHAPER_BURST_US}" ] ; then + SHAPER_BURST_US=1000 # the duration of the burst in microseconds + sqm_warn "get_burst (by duration): Defaulting to ${SHAPER_BURST_US} microseconds bursts." + fi + + # let's assume ATM/AAL5 to be the worst case encapsulation + # and 48 Bytes a reasonable worst case per packet overhead + MIN_BURST=$(( ${MTU} + 48 )) # add 48 bytes to MTU for the ovehead + MIN_BURST=$(( ${MIN_BURST} + 47 )) # now do ceil(Min_BURST / 48) * 53 in shell integer arithmic + MIN_BURST=$(( ${MIN_BURST} / 48 )) + MIN_BURST=$(( ${MIN_BURST} * 53 )) # for MTU 1489 to 1536 this will result in MIN_BURST = 1749 Bytes + + # htb/tbf expect burst to be specified in bytes, while bandwidth is in kbps + BURST=$(( ((${SHAPER_BURST_US} * ${BANDWIDTH}) / 8000) )) + + if [ ${BURST} -lt ${MIN_BURST} ] ; then + sqm_log "get_burst (by duration): the calculated burst/quantum size of ${BURST} bytes was below the minimum of ${MIN_BURST} bytes." + BURST=${MIN_BURST} + fi + + sqm_debug "get_burst (by duration): BURST [Byte]: ${BURST}, BANDWIDTH [Kbps]: ${BANDWIDTH}, DURATION [us]: ${SHAPER_BURST_US}" + + echo ${BURST} +} + + +# Create optional burst parameters to leap over CPU interupts when the CPU is +# severly loaded. We need to be conservative though. +get_htb_burst() { + local HTB_MTU + local BANDWIDTH + local DURATION_US + local BURST + HTB_MTU=$( get_mtu $1 ) + BANDWIDTH=$2 + DURATION_US=$3 + + sqm_debug "get_htb_burst: 1: ${1}, 2: ${2}, 3: ${3}" + + if [ -z "${DURATION_US}" ] ; then + DURATION_US=${SHAPER_BURST_DUR_US} # the duration of the burst in microseconds + sqm_warn "get_htb_burst (by duration): Defaulting to ${SHAPER_BURST_DUR_US} microseconds." + fi + + if [ -n "${HTB_MTU}" -a "${DURATION_US}" -gt "0" ] ; then + BURST=$( get_burst ${HTB_MTU} ${BANDWIDTH} ${DURATION_US} ) + fi + + if [ -z "$BURST" ]; then + sqm_debug "get_htb_burst: Default Burst, HTB will use MTU plus shipping and handling" + else + echo burst $BURST cburst $BURST + fi +} + +# For a default PPPoE link this returns 1492 just as expected but I fear we +# actually need the wire size of the whole thing not so much the MTU +get_mtu() { + CUR_MTU=$(cat /sys/class/net/$1/mtu) + sqm_debug "IFACE: ${1} MTU: ${CUR_MTU}" + echo ${CUR_MTU} +} + +# Set the autoflow variable to 1 if you want to limit the number of flows +# otherwise the default of 1024 will be used for all Xfq_codel qdiscs. + +get_flows() { + case $QDISC in + codel|ns2_codel|pie|*fifo|pfifo_fast) ;; + fq_codel|*fq_codel|sfq) echo flows $( get_flows_count ${1} ) ;; + esac +} + +get_flows_count() { + if [ "${AUTOFLOW}" -eq "1" ]; then + FLOWS=8 + [ $1 -gt 999 ] && FLOWS=16 + [ $1 -gt 2999 ] && FLOWS=32 + [ $1 -gt 7999 ] && FLOWS=48 + [ $1 -gt 9999 ] && FLOWS=64 + [ $1 -gt 19999 ] && FLOWS=128 + [ $1 -gt 39999 ] && FLOWS=256 + [ $1 -gt 69999 ] && FLOWS=512 + [ $1 -gt 99999 ] && FLOWS=1024 + case $QDISC in + codel|ns2_codel|pie|*fifo|pfifo_fast) ;; + fq_codel|*fq_codel|sfq) echo $FLOWS ;; + esac + else + case $QDISC in + codel|ns2_codel|pie|*fifo|pfifo_fast) ;; + fq_codel|*fq_codel|sfq) echo 1024 ;; + esac + fi +} + +# set the target parameter, also try to only take well formed inputs +# Note, the link bandwidth in the current direction (ingress or egress) +# is required to adjust the target for slow links +get_target() { + local CUR_TARGET + local CUR_LINK_KBPS + CUR_TARGET=${1} + CUR_LINK_KBPS=${2} + [ ! -z "$CUR_TARGET" ] && sqm_debug "cur_target: ${CUR_TARGET} cur_bandwidth: ${CUR_LINK_KBPS}" + CUR_TARGET_STRING= + # either e.g. 100ms or auto + CUR_TARGET_VALUE=$( echo ${CUR_TARGET} | grep -o -e \^'[[:digit:]]\+' ) + CUR_TARGET_UNIT=$( echo ${CUR_TARGET} | grep -o -e '[[:alpha:]]\+'\$ ) + + AUTO_TARGET= + UNIT_VALID= + + case $QDISC in + *codel|*pie) + if [ ! -z "${CUR_TARGET_VALUE}" -a ! -z "${CUR_TARGET_UNIT}" ]; + then + case ${CUR_TARGET_UNIT} in + # permissible units taken from: tc_util.c get_time() + s|sec|secs|ms|msec|msecs|us|usec|usecs) + CUR_TARGET_STRING="target ${CUR_TARGET_VALUE}${CUR_TARGET_UNIT}" + UNIT_VALID="1" + ;; + esac + fi + # empty field in GUI or undefined GUI variable now defaults to auto + if [ -z "${CUR_TARGET_VALUE}" -a -z "${CUR_TARGET_UNIT}" ]; + then + if [ ! -z "${CUR_LINK_KBPS}" ]; then + TMP_TARGET_US=$( adapt_target_to_slow_link $CUR_LINK_KBPS ) + TMP_INTERVAL_STRING=$( adapt_interval_to_slow_link $TMP_TARGET_US ) + CUR_TARGET_STRING="target ${TMP_TARGET_US}us ${TMP_INTERVAL_STRING}" + AUTO_TARGET="1" + sqm_debug "get_target defaulting to auto." + else + sqm_warn "required link bandwidth in kbps not passed to get_target()." + fi + fi + # but still allow explicit use of the keyword auto for backward compatibility + case ${CUR_TARGET_UNIT} in + auto|Auto|AUTO) + if [ ! -z "${CUR_LINK_KBPS}" ]; then + TMP_TARGET_US=$( adapt_target_to_slow_link $CUR_LINK_KBPS ) + TMP_INTERVAL_STRING=$( adapt_interval_to_slow_link $TMP_TARGET_US ) + CUR_TARGET_STRING="target ${TMP_TARGET_US}us ${TMP_INTERVAL_STRING}" + AUTO_TARGET="1" + else + sqm_warn "required link bandwidth in kbps not passed to get_target()." + fi + ;; + esac + + case ${CUR_TARGET_UNIT} in + default|Default|DEFAULT) + if [ ! -z "${CUR_LINK_KBPS}" ]; then + CUR_TARGET_STRING="" # return nothing so the default target is not over-ridden... + AUTO_TARGET="1" + sqm_debug "get_target using qdisc default, no explicit target string passed." + else + sqm_warn "required link bandwidth in kbps not passed to get_target()." + fi + ;; + esac + if [ ! -z "${CUR_TARGET}" ]; then + if [ -z "${CUR_TARGET_VALUE}" -o -z "${UNIT_VALID}" ]; then + [ -z "$AUTO_TARGET" ] && sqm_warn "${CUR_TARGET} is not a well formed tc target specifier; e.g.: 5ms (or s, us), or one of the strings auto or default." + fi + fi + ;; + esac + echo $CUR_TARGET_STRING +} + +# for low bandwidth links fq_codels default target of 5ms does not work too well +# so increase target for slow links (note below roughly 2500kbps a single packet +# will take more than 5 ms to be tansfered over the wire) +adapt_target_to_slow_link() { + LINK_BW=$1 + # for ATM the worst case expansion including overhead seems to be 33 clls of + # 53 bytes each + MAX_DELAY=$(( 1000 * 1000 * 33 * 53 * 8 / 1000 )) # Max delay in us at 1kbps + TARGET=$(( ${MAX_DELAY} / ${LINK_BW} )) # note this truncates the decimals + + # do not change anything for fast links + [ "$TARGET" -lt 5000 ] && TARGET=5000 + case ${QDISC} in + *codel|pie) + echo "${TARGET}" + ;; + esac +} + +# codel looks at a whole interval to figure out wether observed latency stayed +# below target if target >= interval that will not work well, so increase +# interval by the same amonut that target got increased +adapt_interval_to_slow_link() { + TARGET=$1 + case ${QDISC} in + *codel) + # Note this is not following codel theory to well as target should + # be 5-10% of interval and the simple addition does not conserve + # that relationship + INTERVAL=$(( (100 - 5) * 1000 + ${TARGET} )) + echo "interval ${INTERVAL}us" + ;; + pie) + ## not sure if pie needs this, probably not + #TUPDATE=$(( (30 - 20) * 1000 + ${TARGET} )) + #echo "tupdate ${TUPDATE}us" + ;; + esac +} + + +# set quantum parameter if available for this qdisc +get_quantum() { + case $QDISC in + *fq_codel|fq_pie|drr) echo quantum $1 ;; + *) ;; + esac +} + +# only show limits to qdiscs that can handle them... +# Note that $LIMIT contains the default limit +get_limit() { + CURLIMIT=$1 + case $QDISC in + *codel|*pie|pfifo_fast|sfq|pfifo) [ -z ${CURLIMIT} ] && CURLIMIT=${LIMIT} # global default limit + ;; + bfifo) [ -z "$CURLIMIT" ] && [ ! -z "$LIMIT" ] && CURLIMIT=$(( ${LIMIT} * $( cat /sys/class/net/${IFACE}/mtu ) )) # bfifo defaults to txquelength * MTU, + ;; + *) sqm_warn "qdisc ${QDISC} does not support a limit" + ;; + esac + sqm_debug "get_limit: $1 CURLIMIT: ${CURLIMIT}" + + if [ ! -z "$CURLIMIT" ]; then + echo "limit ${CURLIMIT}" + fi +} + +get_ecn() { + CURECN=$1 + case ${CURECN} in + ECN) + case $QDISC in + *codel|*pie|*red) + CURECN=ecn + ;; + *) + CURECN="" + ;; + esac + ;; + NOECN) + case $QDISC in + *codel|*pie|*red) + CURECN=noecn + ;; + *) + CURECN="" + ;; + esac + ;; + *) + sqm_warn "ecn value $1 not handled" + ;; + esac + sqm_debug "get_ECN: $1 CURECN: ${CURECN} IECN: ${IECN} EECN: ${EECN}" + echo ${CURECN} + +} + +# This could be a complete diffserv implementation + +diffserv() { + + interface=$1 + prio=1 + + # Catchall + + $TC filter add dev $interface parent 1:0 protocol all prio 999 u32 \ + match ip protocol 0 0x00 flowid 1:12 + + # Find the most common matches fast + + fc 1:0 0x00 1:12 # BE + fc 1:0 0x20 1:13 # CS1 + fc 1:0 0x10 1:11 # IMM + fc 1:0 0xb8 1:11 # EF + fc 1:0 0xc0 1:11 # CS3 + fc 1:0 0xe0 1:11 # CS6 + fc 1:0 0x90 1:11 # AF42 (mosh) + + # Arp traffic + $TC filter add dev $interface protocol arp parent 1:0 prio $prio handle 500 fw flowid 1:11 + + prio=$(($prio + 1)) +} + +eth_setup() { + ethtool -K $IFACE gso off + ethtool -K $IFACE tso off + ethtool -K $IFACE ufo off + ethtool -K $IFACE gro off + + if [ -e /sys/class/net/$IFACE/queues/tx-0/byte_queue_limits ]; then + for i in /sys/class/net/$IFACE/queues/tx-*/byte_queue_limits + do + echo $(( 4 * $( get_mtu ${IFACE} ) )) > $i/limit_max + done + fi +} diff --git a/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/layer_cake.qos b/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/layer_cake.qos new file mode 100644 index 0000000..27d8163 --- /dev/null +++ b/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/layer_cake.qos @@ -0,0 +1,52 @@ +# Cero3 Shaper +# A cake shaper and AQM solution that allows several diffserv marking schemes +# for ethernet gateways + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# Copyright (C) 2012-5 Michael D. Taht, Toke Høiland-Jørgensen, Sebastian Moeller + + +#sm: TODO pass in the cake diffserv keyword + +. ${SQM_LIB_DIR}/defaults.sh +QDISC=cake + +# Default traffic classication is passed in INGRESS_CAKE_OPTS and EGRESS_CAKE_OPTS, defined in defaults.sh now + + +egress() { + SILENT=1 $TC qdisc del dev $IFACE root + $TC qdisc add dev $IFACE root $( get_stab_string ) cake \ + bandwidth ${UPLINK}kbit $( get_cake_lla_string ) ${EGRESS_CAKE_OPTS} ${EQDISC_OPTS} + +} + + +ingress() { + + SILENT=1 $TC qdisc del dev $IFACE handle ffff: ingress + $TC qdisc add dev $IFACE handle ffff: ingress + + SILENT=1 $TC qdisc del dev $DEV root + + [ "$IGNORE_DSCP_INGRESS" -eq "1" ] && INGRESS_CAKE_OPTS="$INGRESS_CAKE_OPTS besteffort" + [ "$ZERO_DSCP_INGRESS" -eq "1" ] && INGRESS_CAKE_OPTS="$INGRESS_CAKE_OPTS wash" + + $TC qdisc add dev $DEV root $( get_stab_string ) cake \ + bandwidth ${DOWNLINK}kbit $( get_cake_lla_string ) ${INGRESS_CAKE_OPTS} ${IQDISC_OPTS} + + $IP link set dev $DEV up + + # redirect all IP packets arriving in $IFACE to ifb0 + + $TC filter add dev $IFACE parent ffff: protocol all prio 10 u32 \ + match u32 0 0 flowid 1:1 action mirred egress redirect dev $DEV +} + +sqm_prepare_script() { + do_modules + verify_qdisc $QDISC "cake" || return 1 +} diff --git a/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/layer_cake.qos.help b/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/layer_cake.qos.help new file mode 100644 index 0000000..1cab3ed --- /dev/null +++ b/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/layer_cake.qos.help @@ -0,0 +1,4 @@ +This uses the cake qdisc as a replacement for both htb as shaper and fq_codel as leaf qdisc. +This exercises cake's diffserv profile(s) as different "layers" of priority. +This script requires that cake is selected as qdisc, and forces its usage. +See: http://www.bufferbloat.net/projects/codel/wiki/Cake for more information diff --git a/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/piece_of_cake.qos b/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/piece_of_cake.qos new file mode 100644 index 0000000..ac65eda --- /dev/null +++ b/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/piece_of_cake.qos @@ -0,0 +1,52 @@ +# Cero3 Simple Shaper +# A 1 tin cake shaper for +# ethernet gateways. This is nearly the simplest possible + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# Copyright (C) 2012-5 Michael D. Taht, Toke Høiland-Jørgensen, Sebastian Moeller + + +. ${SQM_LIB_DIR}/defaults.sh +QDISC=cake + + +# to keep this as simple as possible we ignore the *_CAKE_OPTS from defaults.sh +INGRESS_CAKE_OPTS="besteffort" +EGRESS_CAKE_OPTS="besteffort" + + +egress() { + sqm_debug "egress" + SILENT=1 $TC qdisc del dev $IFACE root + $TC qdisc add dev $IFACE root $( get_stab_string ) cake \ + bandwidth ${UPLINK}kbit $( get_cake_lla_string ) ${EGRESS_CAKE_OPTS} ${EQDISC_OPTS} +} + + +ingress() { + sqm_debug "ingress" + + SILENT=1 $TC qdisc del dev $IFACE handle ffff: ingress + $TC qdisc add dev $IFACE handle ffff: ingress + SILENT=1 $TC qdisc del dev $DEV root + + [ "$ZERO_DSCP_INGRESS" -eq "1" ] && INGRESS_CAKE_OPTS="$INGRESS_CAKE_OPTS wash" + + $TC qdisc add dev $DEV root $( get_stab_string ) cake \ + bandwidth ${DOWNLINK}kbit $( get_cake_lla_string ) ${INGRESS_CAKE_OPTS} ${IQDISC_OPTS} + + $IP link set dev $DEV up + + # redirect all IP packets arriving in $IFACE to ifb0 + + $TC filter add dev $IFACE parent ffff: protocol all prio 10 u32 \ + match u32 0 0 flowid 1:1 action mirred egress redirect dev $DEV +} + +sqm_prepare_script() { + do_modules + verify_qdisc $QDISC "cake" || return 1 +} diff --git a/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/piece_of_cake.qos.help b/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/piece_of_cake.qos.help new file mode 100644 index 0000000..b95e9be --- /dev/null +++ b/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/piece_of_cake.qos.help @@ -0,0 +1,4 @@ +This just uses the cake qdisc as a replacement for both htb as shaper and fq_codel as leaf qdisc. +It just does not come any simpler than this, in other words it truely is a "piece of cake". +This script requires that cake is selected as qdisc, and forces its usage. +See: http://www.bufferbloat.net/projects/codel/wiki/Cake for more information diff --git a/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/run.sh b/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/run.sh new file mode 100644 index 0000000..6f55ca7 --- /dev/null +++ b/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/run.sh @@ -0,0 +1,130 @@ +#!/bin/sh + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# Copyright (C) 2012-4 Michael D. Taht, Toke Høiland-Jørgensen, Sebastian Moeller + + +. /lib/functions.sh + +. /etc/sqm/sqm.conf +. ${SQM_LIB_DIR}/functions.sh + +ACTION="${1:-start}" +RUN_IFACE="$2" +LOCKDIR="${SQM_STATE_DIR}/sqm-run.lock" + +check_state_dir +[ -d "${SQM_QDISC_STATE_DIR}" ] || ${SQM_LIB_DIR}/update-available-qdiscs + +stop_statefile() { + local f + f="$1" + # Source the state file prior to stopping; we need the variables saved in + # there. + [ -f "$f" ] && ( . "$f"; + IFACE=$IFACE SCRIPT=$SCRIPT SQM_DEBUG=$SQM_DEBUG \ + SQM_DEBUG_LOG=$SQM_DEBUG_LOG \ + SQM_VERBOSITY_MAX=$SQM_VERBOSITY_MAX \ + SQM_VERBOSITY_MIN=$SQM_VERBOSITY_MIN \ + OUTPUT_TARGET=$OUTPUT_TARGET ${SQM_LIB_DIR}/stop-sqm ) +} + +start_sqm_section() { + local section + section="$1" + export IFACE=$(config_get "$section" interface) + + [ -z "$RUN_IFACE" -o "$RUN_IFACE" = "$IFACE" ] || return + [ "$(config_get "$section" enabled)" -eq 1 ] || return 0 + [ -f "${SQM_STATE_DIR}/${IFACE}.state" ] && return + + export UPLINK=$(config_get "$section" upload) + export DOWNLINK=$(config_get "$section" download) + export LLAM=$(config_get "$section" linklayer_adaptation_mechanism) + export LINKLAYER=$(config_get "$section" linklayer) + export OVERHEAD=$(config_get "$section" overhead) + export STAB_MTU=$(config_get "$section" tcMTU) + export STAB_TSIZE=$(config_get "$section" tcTSIZE) + export STAB_MPU=$(config_get "$section" tcMPU) + export ILIMIT=$(config_get "$section" ilimit) + export ELIMIT=$(config_get "$section" elimit) + export ITARGET=$(config_get "$section" itarget) + export ETARGET=$(config_get "$section" etarget) + export IECN=$(config_get "$section" ingress_ecn) + export EECN=$(config_get "$section" egress_ecn) + export IQDISC_OPTS=$(config_get "$section" iqdisc_opts) + export EQDISC_OPTS=$(config_get "$section" eqdisc_opts) + export TARGET=$(config_get "$section" target) + export QDISC=$(config_get "$section" qdisc) + export SCRIPT=$(config_get "$section" script) + + # The UCI names for these two variables are confusing and should have been + # changed ages ago. For now, keep the bad UCI names but use meaningful + # variable names in the scripts to not break user configs. + export ZERO_DSCP_INGRESS=$(config_get "$section" squash_dscp) + export IGNORE_DSCP_INGRESS=$(config_get "$section" squash_ingress) + + # If SQM_DEBUG or SQM_VERBOSITY_* were passed in via the command line make + # them available to the other scripts this allows to override sqm's log + # level as set in the GUI for quick debugging without GUI accesss. + export SQM_DEBUG=${SQM_DEBUG:-$(config_get "$section" debug_logging)} + export SQM_VERBOSITY_MAX=${SQM_VERBOSITY_MAX:-$(config_get "$section" verbosity)} + export SQM_VERBOSITY_MIN + + "${SQM_LIB_DIR}/start-sqm" +} + +release_lock() { + PID=$(cat "$LOCKDIR/pid") + if [ "$PID" -ne "$$" ]; then + sqm_error "Trying to release lock with wrong PID $PID != $$" + return 1 + fi + + rm -rf "$LOCKDIR" + return 0 +} + +take_lock() { + + if mkdir "$LOCKDIR" 2>/dev/null; then + sqm_trace "Acquired run lock" + echo $$ > "$LOCKDIR/pid" + + trap release_lock 0 + return 0 + fi + PID=$(cat "$LOCKDIR/pid") + sqm_warn "Unable to get run lock - already held by $PID" + return 1 +} + +MAX_TRIES=10 +tries=$MAX_TRIES +while ! take_lock; do + sleep 1 + tries=$((tries - 1)) + if [ "$tries" -eq 0 ]; then + sqm_error "Giving up on getting lock after $MAX_TRIES attempts" + sqm_error "This is a bug; please report it at https://github.com/tohojo/sqm-scripts/issues" + sqm_error "Then, to re-enable sqm-scripts, manually remove $LOCKDIR" + exit 1 + fi +done + +if [ "$ACTION" = "stop" ]; then + if [ -z "$RUN_IFACE" ]; then + # Stopping all active interfaces + for f in ${SQM_STATE_DIR}/*.state; do + stop_statefile "$f" + done + else + stop_statefile "${SQM_STATE_DIR}/${RUN_IFACE}.state" + fi +else + config_load sqm + config_foreach start_sqm_section +fi diff --git a/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/simple.qos b/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/simple.qos new file mode 100644 index 0000000..55f3cdf --- /dev/null +++ b/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/simple.qos @@ -0,0 +1,234 @@ +################################################################################ +# simple.qos (Cero3 Shaper) +# +# Abstract: +# This is a three band fq_codel and ipv6 enabled shaping script for Ethernet +# gateways. Compared to the complexity that debloat had become this cleanly +# shows a means of going from diffserv marking to prioritization using the +# current tools ip(6)tables and tc. We should note that the complexity of +# debloat exists for a reason, and it is expected that script is run first to +# setup various other parameters such as BQL and ethtool. +# +# (Assume the debloat script has setup the other interfaces.) +# +# Notes: +# This does the right thing with ipv6 traffic. It also tries to leverage +# diffserv to some sane extent. In particular, the 'priority' queue is limited +# to 33% of the total, so EF, and IMM traffic cannot starve other types. The +# rfc suggested 30%. 30% is probably a lot in today's world. +# +# References: +# This alternate shaper attempts to go for 1/u performance in a clever way +# http://git.coverfire.com/?p=linux-qos-scripts.git;a=blob;f=src-3tos.sh;hb=HEAD +# +################################################################################ +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# Copyright (C) 2012-2016 +# Michael D. Taht, Toke Høiland-Jørgensen, Sebastian Moeller +# +################################################################################ + +. ${SQM_LIB_DIR}/defaults.sh + +################################################################################ + +ipt_setup() { + + ipt -t mangle -N QOS_MARK_${IFACE} + + case $QDISC in + cake*) + sqm_debug "cake does all the diffserv work - no need for iptables rules" + ;; + *) + ipt -t mangle -A QOS_MARK_${IFACE} -j MARK --set-mark 0x2/${IPT_MASK} + # You can go further with classification but... + ipt -t mangle -A QOS_MARK_${IFACE} -m dscp --dscp-class CS1 -j MARK --set-mark 0x3/${IPT_MASK} + ipt -t mangle -A QOS_MARK_${IFACE} -m dscp --dscp-class CS6 -j MARK --set-mark 0x1/${IPT_MASK} + ipt -t mangle -A QOS_MARK_${IFACE} -m dscp --dscp-class EF -j MARK --set-mark 0x1/${IPT_MASK} + ipt -t mangle -A QOS_MARK_${IFACE} -m dscp --dscp-class AF42 -j MARK --set-mark 0x1/${IPT_MASK} + ipt -t mangle -A QOS_MARK_${IFACE} -m tos --tos Minimize-Delay -j MARK --set-mark 0x1/${IPT_MASK} + ;; + esac + + # Turn it on. Preserve classification if already performed + # + #sm: is it correct to do this in $IFACE? Should ingress not be on $DEV? since HTB acts on $DEV? + # + # ZERO also does not work on $DEV (that is the IFB will still see the + # incoming ToS bits whether we squash or not) + # + # ZERO is still useful to protect internal machines... + if [ "$ZERO_DSCP_INGRESS" = "1" ]; then + sqm_debug "Squashing differentiated services code points (DSCP) from ingress." + ipt -t mangle -I PREROUTING -i $IFACE -m dscp ! --dscp 0 -j DSCP --set-dscp-class be + else + sqm_debug "Keeping differentiated services code points (DSCP) from ingress." + ipt -t mangle -A PREROUTING -i $IFACE -m mark --mark 0x00/${IPT_MASK} -g QOS_MARK_${IFACE} + fi + + ipt -t mangle -A POSTROUTING -o $IFACE -m mark --mark 0x00/${IPT_MASK} -g QOS_MARK_${IFACE} + + # The Syn optimization was nice but fq_codel does it for us + # ipt -t mangle -A PREROUTING -i s+ -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j MARK --set-mark 0x01 + # Not sure if this will work. Encapsulation is a problem period + + ipt -t mangle -I PREROUTING -i vtun+ -p tcp -j MARK --set-mark 0x2/${IPT_MASK} # tcp tunnels need ordering + + # Emanating from router, do a little more optimization + # but don't bother with it too much. + + ipt -t mangle -A OUTPUT -p udp -m multiport --ports 123,53 -j DSCP --set-dscp-class AF42 + + #Not clear if the second line is needed + #ipt -t mangle -A OUTPUT -o $IFACE -g QOS_MARK_${IFACE} + +} + + + +cake_egress() +{ + $TC qdisc add dev $IFACE root `get_stab_string` $QDISC bandwidth ${CEIL}kbit `get_cake_lla_string` ${EQDISC_OPTS} +} + +egress() { + + CEIL=${UPLINK} + PRIO_RATE=`expr $CEIL / 3` # Ceiling for prioirty + BE_RATE=`expr $CEIL / 6` # Min for best effort + BK_RATE=`expr $CEIL / 6` # Min for background + BE_CEIL=`expr $CEIL - 16` # A little slop at the top + + LQ="quantum `get_htb_quantum $IFACE $CEIL ${ESHAPER_QUANTUM_DUR_US}`" + BURST="`get_htb_burst $IFACE $CEIL ${ESHAPER_BURST_DUR_US}`" + + SILENT=1 $TC qdisc del dev $IFACE root + + case $QDISC in + cake*) cake_egress; return;; + esac + + $TC qdisc add dev $IFACE root handle 1: `get_stab_string` htb default 12 + $TC class add dev $IFACE parent 1: classid 1:1 htb $LQ rate ${CEIL}kbit ceil ${CEIL}kbit $BURST `get_htb_adsll_string` + $TC class add dev $IFACE parent 1:1 classid 1:11 htb $LQ rate 128kbit ceil ${PRIO_RATE}kbit prio 1 `get_htb_adsll_string` + $TC class add dev $IFACE parent 1:1 classid 1:12 htb $LQ rate ${BE_RATE}kbit ceil ${BE_CEIL}kbit $BURST prio 2 `get_htb_adsll_string` + $TC class add dev $IFACE parent 1:1 classid 1:13 htb $LQ rate ${BK_RATE}kbit ceil ${BE_CEIL}kbit $BURST prio 3 `get_htb_adsll_string` + + $TC qdisc add dev $IFACE parent 1:11 handle 110: $QDISC \ + `get_limit ${ELIMIT}` `get_target "${ETARGET}" ${UPLINK}` `get_ecn ${EECN}` `get_quantum 300` `get_flows ${PRIO_RATE}` ${EQDISC_OPTS} + $TC qdisc add dev $IFACE parent 1:12 handle 120: $QDISC \ + `get_limit ${ELIMIT}` `get_target "${ETARGET}" ${UPLINK}` `get_ecn ${EECN}` `get_quantum 300` `get_flows ${BE_RATE}` ${EQDISC_OPTS} + $TC qdisc add dev $IFACE parent 1:13 handle 130: $QDISC \ + `get_limit ${ELIMIT}` `get_target "${ETARGET}" ${UPLINK}` `get_ecn ${EECN}` `get_quantum 300` `get_flows ${BK_RATE}` ${EQDISC_OPTS} + + # Need a catchall rule + + $TC filter add dev $IFACE parent 1:0 protocol all prio 999 u32 \ + match ip protocol 0 0x00 flowid 1:12 + + # FIXME should probably change the filter here to do pre-nat + + $TC filter add dev $IFACE parent 1:0 protocol ip prio 1 handle 1/${IPT_MASK} fw classid 1:11 + $TC filter add dev $IFACE parent 1:0 protocol ip prio 2 handle 2/${IPT_MASK} fw classid 1:12 + $TC filter add dev $IFACE parent 1:0 protocol ip prio 3 handle 3/${IPT_MASK} fw classid 1:13 + + # ipv6 support. Note that the handle indicates the fw mark bucket that is looked for + + $TC filter add dev $IFACE parent 1:0 protocol ipv6 prio 4 handle 1/${IPT_MASK} fw classid 1:11 + $TC filter add dev $IFACE parent 1:0 protocol ipv6 prio 5 handle 2/${IPT_MASK} fw classid 1:12 + $TC filter add dev $IFACE parent 1:0 protocol ipv6 prio 6 handle 3/${IPT_MASK} fw classid 1:13 + + # Arp traffic + + $TC filter add dev $IFACE parent 1:0 protocol arp prio 7 handle 1/${IPT_MASK} fw classid 1:11 + + # ICMP traffic - Don't impress your friends. Deoptimize to manage ping floods + # better instead + + $TC filter add dev $IFACE parent 1:0 protocol ip prio 8 \ + u32 match ip protocol 1 0xff flowid 1:13 + + $TC filter add dev $IFACE parent 1:0 protocol ipv6 prio 9 \ + u32 match ip protocol 1 0xff flowid 1:13 +} + + +cake_ingress() +{ + CAKEARGS= + [ "$IGNORE_DSCP_INGRESS" = "1" ] && CAKEARGS="$CAKEARGS besteffort" + $TC qdisc add dev $DEV root `get_stab_string` $QDISC bandwidth ${DOWNLINK}kbit \ + $CAKEARGS `get_cake_lla_string` ${IQDISC_OPTS} + + $IP link set dev $DEV up + + # redirect all IP packets arriving in $IFACE to $DEV + + $TC filter add dev $IFACE parent ffff: protocol all prio 10 u32 \ + match u32 0 0 flowid 1:1 action mirred egress redirect dev $DEV +} + +ingress() { + + CEIL=$DOWNLINK + PRIO_RATE=`expr $CEIL / 3` # Ceiling for prioirty + BE_RATE=`expr $CEIL / 6` # Min for best effort + BK_RATE=`expr $CEIL / 6` # Min for background + BE_CEIL=`expr $CEIL - 16` # A little slop at the top + + LQ="quantum `get_htb_quantum $IFACE $CEIL ${ISHAPER_QUANTUM_DUR_US}`" + BURST="`get_htb_burst $IFACE $CEIL ${ISHAPER_BURST_DUR_US}`" + + SILENT=1 $TC qdisc del dev $IFACE handle ffff: ingress + $TC qdisc add dev $IFACE handle ffff: ingress + + SILENT=1 $TC qdisc del dev $DEV root + + case $QDISC in + cake*) cake_ingress; return ;; + esac + + if [ "$IGNORE_DSCP_INGRESS" = "1" ]; then + sqm_debug "Do not perform DSCP based filtering on ingress. (1-tier classification)" + $TC qdisc add dev $DEV root handle 1: `get_stab_string` htb default 10 + $TC class add dev $DEV parent 1: classid 1:1 htb $LQ rate ${DOWNLINK}kbit ceil ${DOWNLINK}kbit $BURST `get_htb_adsll_string` + $TC class add dev $DEV parent 1:1 classid 1:10 htb $LQ rate ${DOWNLINK}kbit ceil ${DOWNLINK}kbit $BURST prio 0 `get_htb_adsll_string` + $TC qdisc add dev $DEV parent 1:10 handle 110: $QDISC \ + `get_limit ${ILIMIT}` `get_target "${ITARGET}" ${DOWNLINK}` `get_ecn ${IECN}` `get_flows ${DOWNLINK}` ${IQDISC_OPTS} + else + sqm_debug "Perform DSCP based filtering on ingress. (3-tier classification)" + $TC qdisc add dev $DEV root handle 1: `get_stab_string` htb default 12 + $TC class add dev $DEV parent 1: classid 1:1 htb $LQ rate ${CEIL}kbit ceil ${CEIL}kbit $BURST `get_htb_adsll_string` + $TC class add dev $DEV parent 1:1 classid 1:11 htb $LQ rate 32kbit ceil ${PRIO_RATE}kbit prio 1 `get_htb_adsll_string` + $TC class add dev $DEV parent 1:1 classid 1:12 htb $LQ rate ${BE_RATE}kbit ceil ${BE_CEIL}kbit $BURST prio 2 `get_htb_adsll_string` + $TC class add dev $DEV parent 1:1 classid 1:13 htb $LQ rate ${BK_RATE}kbit ceil ${BE_CEIL}kbit $BURST prio 3 `get_htb_adsll_string` + + $TC qdisc add dev $DEV parent 1:11 handle 110: $QDISC \ + `get_limit ${ILIMIT}` `get_target "${ITARGET}" ${DOWNLINK}` `get_ecn ${IECN}` `get_quantum 500` `get_flows ${PRIO_RATE}` ${IQDISC_OPTS} + $TC qdisc add dev $DEV parent 1:12 handle 120: $QDISC \ + `get_limit ${ILIMIT}` `get_target "${ITARGET}" ${DOWNLINK}` `get_ecn ${IECN}` `get_quantum 1500` `get_flows ${BE_RATE}` ${IQDISC_OPTS} + $TC qdisc add dev $DEV parent 1:13 handle 130: $QDISC \ + `get_limit ${ILIMIT}` `get_target "${ITARGET}" ${DOWNLINK}` `get_ecn ${IECN}` `get_quantum 300` `get_flows ${BK_RATE}` ${IQDISC_OPTS} + + diffserv $DEV + fi + + $IP link set dev $DEV up + + # redirect all IP packets arriving in $IFACE to $DEV + + $TC filter add dev $IFACE parent ffff: protocol all prio 10 u32 \ + match u32 0 0 flowid 1:1 action mirred egress redirect dev $DEV + +} + +sqm_prepare_script() { + do_modules + verify_qdisc "htb" || return 1 + ipt_setup +} diff --git a/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/simple.qos.help b/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/simple.qos.help new file mode 100644 index 0000000..b3c0096 --- /dev/null +++ b/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/simple.qos.help @@ -0,0 +1 @@ +BW-limited three-tier prioritisation scheme with your qdisc on each queue. (default) diff --git a/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/simplest.qos b/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/simplest.qos new file mode 100644 index 0000000..80fe208 --- /dev/null +++ b/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/simplest.qos @@ -0,0 +1,104 @@ +################################################################################ +# simplest.qos (Cero3 Simple Shaper) +# +# Abstract: +# This is a single band fq_codel and ipv6 enabled shaping script for Ethernet +# gateways. This is nearly the simplest possible. With FQ_CODEL, the sparseness +# priority will work pretty well for a casual network. Flow-hashes should not +# overlap much with only a few users. +# +# References: +# This alternate shaper attempts to go for 1/u performance in a clever way +# http://git.coverfire.com/?p=linux-qos-scripts.git;a=blob;f=src-3tos.sh;hb=HEAD +# +################################################################################ +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# Copyright (C) 2012-2016 +# Michael D. Taht, Toke Høiland-Jørgensen, Sebastian Moeller +# +################################################################################ + +. ${SQM_LIB_DIR}/defaults.sh + +################################################################################ + +cake_egress() +{ + $TC qdisc add dev $IFACE root `get_stab_string` cake bandwidth ${UPLINK}kbit besteffort `get_cake_lla_string` ${EQDISC_OPTS} +} + +egress() { + + LQ="quantum `get_htb_quantum $IFACE ${UPLINK} ${ESHAPER_QUANTUM_DUR_US}`" + BURST="`get_htb_burst $IFACE ${UPLINK} ${ESHAPER_BURST_DUR_US}`" + + SILENT=1 $TC qdisc del dev $IFACE root + + case $QDISC in + cake*) cake_egress; return ;; + esac + + $TC qdisc add dev $IFACE root handle 1: `get_stab_string` htb default 10 + $TC class add dev $IFACE parent 1: classid 1:1 htb $LQ rate ${UPLINK}kbit ceil ${UPLINK}kbit $BURST `get_htb_adsll_string` + $TC class add dev $IFACE parent 1:1 classid 1:10 htb $LQ rate ${UPLINK}kbit ceil ${UPLINK}kbit $BURST prio 0 `get_htb_adsll_string` + $TC qdisc add dev $IFACE parent 1:10 handle 110: $QDISC \ + `get_limit ${ELIMIT}` `get_target "${ETARGET}" ${UPLINK}` `get_ecn ${EECN}` `get_flows ${UPLINK}` ${EQDISC_OPTS} + +} + +cake_ingress() +{ + $TC qdisc add dev $DEV root `get_stab_string` cake bandwidth ${DOWNLINK}kbit besteffort `get_cake_lla_string` ${IQDISC_OPTS} + $IP link set dev $DEV up + + # redirect all IP packets arriving in $IFACE to $DEV + + $TC filter add dev $IFACE parent ffff: protocol all prio 10 u32 \ + match u32 0 0 flowid 1:1 action mirred egress redirect dev $DEV +} + +ingress() { + sqm_debug "ingress" + SILENT=1 $TC qdisc del dev $IFACE handle ffff: ingress + $TC qdisc add dev $IFACE handle ffff: ingress + + LQ="quantum `get_htb_quantum $IFACE ${DOWNLINK} ${ISHAPER_QUANTUM_DUR_US}`" + BURST="`get_htb_burst $IFACE ${DOWNLINK} ${ISHAPER_BURST_DUR_US}`" + + SILENT=1 $TC qdisc del dev $DEV root + + case $QDISC in + cake*) cake_ingress; return ;; + esac + + $TC qdisc add dev $DEV root handle 1: `get_stab_string` htb default 10 + $TC class add dev $DEV parent 1: classid 1:1 htb $LQ rate ${DOWNLINK}kbit ceil ${DOWNLINK}kbit $BURST `get_htb_adsll_string` + $TC class add dev $DEV parent 1:1 classid 1:10 htb $LQ rate ${DOWNLINK}kbit ceil ${DOWNLINK}kbit $BURST prio 0 `get_htb_adsll_string` + + # FIXME: I'd prefer to use a pre-nat filter but we need to detect if nat is on this interface + # AND we need to permute by a random number which we can't do from userspace filters + + # Most high rate flows are REALLY close. This stomps on those harder, but hurts on high rate long distance + #$TC qdisc add dev $DEV parent 1:10 handle 110: $QDISC limit $LIMIT $ECN interval 20ms target 3ms `get_flows ${DOWNLINK}` + $TC qdisc add dev $DEV parent 1:10 handle 110: $QDISC \ + `get_limit ${ILIMIT}` `get_target "${ITARGET}" ${DOWNLINK}` `get_ecn ${IECN}` `get_flows ${DOWNLINK}` ${IQDISC_OPTS} + + $IP link set dev $DEV up + + # redirect all IP packets arriving in $IFACE to ifb0 + + $TC filter add dev $IFACE parent ffff: protocol all prio 10 u32 \ + match u32 0 0 flowid 1:1 action mirred egress redirect dev $DEV + +} + +sqm_prepare_script() { + do_modules + verify_qdisc "htb" || return 1 +} + +################################################################################ diff --git a/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/simplest.qos.help b/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/simplest.qos.help new file mode 100644 index 0000000..c359256 --- /dev/null +++ b/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/simplest.qos.help @@ -0,0 +1 @@ +Simplest possible configuration: HTB rate limiter with your qdisc attached. diff --git a/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/simplest_tbf.qos b/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/simplest_tbf.qos new file mode 100644 index 0000000..3f7a1c3 --- /dev/null +++ b/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/simplest_tbf.qos @@ -0,0 +1,85 @@ +################################################################################ +# simplest_tbf.qos (Simple TBF shaper) +# +# Abstract: +# This is a single band fq_codel and ipv6 enabled shaping script for Ethernet +# gateways. This is nearly the simplest possible. With FQ_CODEL, the sparseness +# priority will work pretty well for a casual network. Flow-hashes should not +# overlap much with only a few users. +# +# Uses TBF instead of HTB as that may give better performance on some +# architectures. +# +# References: +# This alternate shaper attempts to go for 1/u performance in a clever way +# http://git.coverfire.com/?p=linux-qos-scripts.git;a=blob;f=src-3tos.sh;hb=HEAD +# +################################################################################ +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# Copyright (C) 2012-2017 +# Michael D. Taht, Toke Høiland-Jørgensen, Sebastian Moeller +# +################################################################################ + +. ${SQM_LIB_DIR}/defaults.sh + +################################################################################ + +egress() { + + MTU=$(get_mtu $IFACE) + BURST="$(get_burst ${MTU:-1514} ${UPLINK} ${ESHAPER_BURST_DUR_US})" + BURST=${BURST:-1514} + + SILENT=1 $TC qdisc del dev $IFACE root + + $TC qdisc add dev $IFACE root handle 1: $(get_stab_string) tbf \ + rate ${UPLINK}kbit burst $BURST latency 300ms $(get_htb_adsll_string) + $TC qdisc add dev $IFACE parent 1: handle 110: $QDISC \ + $(get_limit ${ELIMIT}) $(get_target "${ETARGET}" ${UPLINK}) \ + $(get_ecn ${EECN}) $(get_flows ${UPLINK}) ${EQDISC_OPTS} + +} + +ingress() { + sqm_debug "ingress" + SILENT=1 $TC qdisc del dev $IFACE handle ffff: ingress + $TC qdisc add dev $IFACE handle ffff: ingress + + MTU=$(get_mtu $IFACE) + BURST="$(get_burst ${MTU:-1514} ${DOWNLINK} ${ISHAPER_BURST_DUR_US})" + BURST=${BURST:-1514} + + SILENT=1 $TC qdisc del dev $DEV root + + $TC qdisc add dev $DEV root handle 1: $(get_stab_string) tbf \ + rate ${DOWNLINK}kbit burst $BURST latency 300ms $(get_htb_adsll_string) + $TC qdisc add dev $DEV parent 1: handle 110: $QDISC \ + $(get_limit ${ILIMIT}) $(get_target "${ITARGET}" ${DOWNLINK}) \ + $(get_ecn ${IECN}) $(get_flows ${DOWNLINK}) ${IQDISC_OPTS} + + $IP link set dev $DEV up + + # redirect all IP packets arriving in $IFACE to ifb0 + + $TC filter add dev $IFACE parent ffff: protocol all prio 10 u32 \ + match u32 0 0 flowid 1:1 action mirred egress redirect dev $DEV + +} + +sqm_prepare_script() { + do_modules + verify_qdisc "tbf" || return 1 + + case $QDISC in + cake*) + sqm_warn "Cake is not supported with this script; falling back to FQ-CoDel" + QDISC=fq_codel ;; + esac +} + +################################################################################ diff --git a/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/simplest_tbf.qos.help b/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/simplest_tbf.qos.help new file mode 100644 index 0000000..3f93f89 --- /dev/null +++ b/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/simplest_tbf.qos.help @@ -0,0 +1,2 @@ +Simplest possible configuration (TBF): TBF rate limiter with your qdisc attached. +TBF may give better performance than HTB on some architectures. diff --git a/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/start-sqm b/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/start-sqm new file mode 100644 index 0000000..cd76e01 --- /dev/null +++ b/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/start-sqm @@ -0,0 +1,66 @@ +#!/bin/sh + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# Copyright (C) 2012-4 Michael D. Taht, Toke Høiland-Jørgensen, Sebastian Moeller + + +[ -n "$IFACE" ] || exit 1 + +. /etc/sqm/sqm.conf +. ${SQM_LIB_DIR}/functions.sh +. ${SQM_LIB_DIR}/defaults.sh +STATE_FILE="${SQM_STATE_DIR}/${IFACE}.state" + +check_state_dir + +# log file for the most recent sqm instance start +if [ "$SQM_DEBUG" -eq "1" ] ; then + SQM_DEBUG_LOG="${SQM_START_LOG}" + OUTPUT_TARGET="${SQM_DEBUG_LOG}" + echo "start-sqm: Log for interface ${IFACE}: $(date)" > "${OUTPUT_TARGET}" +fi + +if [ -z "${SCRIPT}" ] ; then + sqm_error "SCRIPT value is not defined in /etc/sqm/${IFACE}.iface.conf" + sqm_error "Please check your configuration and try again." + exit 1 +fi + +if [ -f "${STATE_FILE}" ]; then + sqm_error "SQM already activated on ${IFACE}." + exit 1 +fi + +# in case of spurious hotplug events, try double check whether the interface is really up +if [ ! -d /sys/class/net/${IFACE} ] ; then + sqm_error "${IFACE} does currently not exist, not even trying to start SQM on nothing." + exit 1 +fi + +if [ "${ENABLED:-1}" -ne "1" ]; then + sqm_log "SQM config disabled on ${IFACE}." + exit 0 +fi + +if [ ! -f "${SQM_LIB_DIR}/$SCRIPT" ]; then + sqm_error "SQM script ${SCRIPT} not found!" + exit 1 +fi + +. "${SQM_LIB_DIR}/$SCRIPT" + +sqm_trace; sqm_trace "$(date): Starting." # Add some space and a date stamp to verbose log output and log files to separate runs +sqm_log "Starting SQM script: ${SCRIPT} on ${IFACE}, in: ${DOWNLINK} Kbps, out: ${UPLINK} Kbps" + +if fn_exists sqm_start ; then + sqm_debug "Using script specific sqm_start function overriding the generic sqm_start_default." + sqm_start && write_state_file ${STATE_FILE} && sqm_log "${SCRIPT} was started on ${IFACE} successfully" +else + sqm_debug "Using generic sqm_start_default function." + sqm_start_default && write_state_file ${STATE_FILE} && sqm_log "${SCRIPT} was started on ${IFACE} successfully" +fi + +exit 0 diff --git a/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/stop-sqm b/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/stop-sqm new file mode 100644 index 0000000..9a9cbeb --- /dev/null +++ b/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/stop-sqm @@ -0,0 +1,54 @@ +#!/bin/sh + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# Copyright (C) 2012-4 Michael D. Taht, Toke Høiland-Jørgensen, Sebastian Moeller + +# allow passing in the IFACE as first command line argument + +[ -n "$IFACE" ] || exit 1 + +. /etc/sqm/sqm.conf +. ${SQM_LIB_DIR}/functions.sh +. ${SQM_LIB_DIR}/defaults.sh + +check_state_dir +# log file for the most recent sqm instance stop +if [ "$SQM_DEBUG" -eq "1" ] ; then + SQM_DEBUG_LOG="${SQM_STOP_LOG}" + OUTPUT_TARGET="${SQM_DEBUG_LOG}" + echo "stop-sqm: Log for interface ${IFACE}: $(date)" > "${OUTPUT_TARGET}" +fi + +if [ ! -f "${SQM_STATE_DIR}/${IFACE}.state" ] ; then + sqm_error "State file does not exist; SQM was not running on interface ${IFACE}" + exit 1 +fi +STATE_FILE="${SQM_STATE_DIR}/${IFACE}.state" + +if [ -z "${SCRIPT}" ] ; then + sqm_error "SCRIPT value is not defined in /etc/sqm/${IFACE}.iface.conf" + sqm_error "Please check your configuration and try again." + exit 1 +fi + +sqm_trace; sqm_trace "$(date): Stopping." # Add some space and a date stamp to verbose log output and log files to separate runs +sqm_log "Stopping SQM on ${IFACE}" + +# make sure to only delete the ifb associated with the current interface +CUR_IFB=$( get_ifb_associated_with_if ${IFACE} ) +[ -z "$CUR_IFB" ] && CUR_IFB=$( ifb_name ${IFACE} ) + +if [ ! -f "${SQM_LIB_DIR}/$SCRIPT" ]; then + sqm_error "SQM script ${SCRIPT} not found!" + exit 1 +fi + +. "${SQM_LIB_DIR}/$SCRIPT" + +sqm_stop +rm -f "${STATE_FILE}" + +exit 0 diff --git a/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/update-available-qdiscs b/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/update-available-qdiscs new file mode 100644 index 0000000..c966a19 --- /dev/null +++ b/rooter/0optionalapps/ext-throttle/files/usr/lib/sqm/update-available-qdiscs @@ -0,0 +1,14 @@ +#!/bin/sh + +. /etc/sqm/sqm.conf +. ${SQM_LIB_DIR}/functions.sh +. ${SQM_LIB_DIR}/defaults.sh + +[ -d "${SQM_QDISC_STATE_DIR}" ] || mkdir -p "${SQM_QDISC_STATE_DIR}" + +SQM_VERBOSITY_MIN=5 # Silence errors while checking + +for qdisc in $SQM_CHECK_QDISCS; do + [ -f ${SQM_QDISC_STATE_DIR}/$qdisc ] && continue + verify_qdisc $qdisc && touch ${SQM_QDISC_STATE_DIR}/$qdisc +done diff --git a/rooter/0optionalapps/ext-wireguard/files/etc/init.d/wireguard b/rooter/0optionalapps/ext-wireguard/files/etc/init.d/wireguard index 16a34ce..4e49b81 100644 --- a/rooter/0optionalapps/ext-wireguard/files/etc/init.d/wireguard +++ b/rooter/0optionalapps/ext-wireguard/files/etc/init.d/wireguard @@ -84,9 +84,4 @@ start() { config_load wireguard config_foreach chk_start wireguard - if [ -e /etc/crontabs/root ]; then - sed -i '/wireguard_watchdog/d' /etc/crontabs/root - fi - echo '* * * * * /usr/bin/wireguard_watchdog' >> /etc/crontabs/root - /etc/init.d/cron restart } \ No newline at end of file diff --git a/rooter/0optionalapps/ext-wireguard/files/usr/lib/lua/luci/model/cbi/wireguard-client.lua b/rooter/0optionalapps/ext-wireguard/files/usr/lib/lua/luci/model/cbi/wireguard-client.lua index 45e2216..ec041aa 100644 --- a/rooter/0optionalapps/ext-wireguard/files/usr/lib/lua/luci/model/cbi/wireguard-client.lua +++ b/rooter/0optionalapps/ext-wireguard/files/usr/lib/lua/luci/model/cbi/wireguard-client.lua @@ -59,11 +59,6 @@ pkey = s:option(Value, "privatekey", translate("Private Key :"), translate("Priv pkey.rmempty = true; pkey.optional=false; -il = s:option(ListValue, "wginter", translate("Interface to Use :")); -il:value("0", translate("WG0")) -il:value("1", translate("WG1")) -il.default="0" - bl = s:option(ListValue, "auto", translate("Start on Boot :")); bl:value("0", translate("No")) bl:value("1", translate("Yes")) diff --git a/rooter/0optionalapps/ext-wireguard/files/usr/lib/lua/luci/view/wireguard/wireguard.htm b/rooter/0optionalapps/ext-wireguard/files/usr/lib/lua/luci/view/wireguard/wireguard.htm index cf7544e..d207f05 100644 --- a/rooter/0optionalapps/ext-wireguard/files/usr/lib/lua/luci/view/wireguard/wireguard.htm +++ b/rooter/0optionalapps/ext-wireguard/files/usr/lib/lua/luci/view/wireguard/wireguard.htm @@ -40,14 +40,10 @@ XHR.poll(5, '<%=luci.dispatcher.build_url("admin", "vpn", "wirestatus")%>', null, function(x, data) { - both = {}; - bothbp={}; - iii = 1; for (var key in data) { if (!data.hasOwnProperty(key)) { continue; } var ifname = key; var iface = data[key]; - var s = ""; if (iface.public_key == '(none)') { s += '<%:Interface does not have a public key!%>'; @@ -69,16 +65,7 @@ iface.fwmark ); } - if ( iii == 1 ) - { - document.getElementById("iinfo").innerHTML = s; - document.getElementById("leg").innerHTML = ifname; - } - else - { - document.getElementById("iinfo1").innerHTML = s; - document.getElementById("leg1").innerHTML = ifname; - } + document.getElementById("iinfo").innerHTML = s; for (var i = 0, ilen = iface.peers.length; i < ilen; i++) { var peer = iface.peers[i]; var s = String.format( @@ -118,18 +105,9 @@ bytes_to_str(peer.transfer_rx), bytes_to_str(peer.transfer_tx) ); - if ( iii == 1 ) - { - document.getElementById("config").innerHTML = icon; - document.getElementById("info").innerHTML = s; - } - else - { - document.getElementById("config1").innerHTML = icon; - document.getElementById("info1").innerHTML = s; - } + document.getElementById("config").innerHTML = icon; + document.getElementById("info").innerHTML = s; } - iii = iii + 1; } }); //]]> @@ -138,16 +116,9 @@
      -
      - - - - - - -
      -
      <%:Interface %>
      -
        
      + <%:Interface%> WG0 + +
      @@ -176,52 +147,6 @@
       
      - - - - - - - -
      -
      <%:Interface %>
      -
        
      - - - - - - - - - - - - - - - -
        -
      <%:Configuration%>
      -
         -
      - <%:Collecting data...%> -
      -
        -
      <%:Peer%>
      -
         -
      - <%:Collecting data...%> -
      -
      -
      diff --git a/rooter/0optionalapps/ext-wireguard/files/usr/lib/wireguard/conf.sh b/rooter/0optionalapps/ext-wireguard/files/usr/lib/wireguard/conf.sh index 5c36ca2..436e1f5 100644 --- a/rooter/0optionalapps/ext-wireguard/files/usr/lib/wireguard/conf.sh +++ b/rooter/0optionalapps/ext-wireguard/files/usr/lib/wireguard/conf.sh @@ -1,9 +1,5 @@ #!/bin/sh -log() { - modlog "Wireguard Conf" "$@" -} - name=$1 file=$2 auto=$3 @@ -29,13 +25,6 @@ extract() { if [ ! -z "$PRK" ]; then PreSharedKey=$(echo $PRK | cut -d, -f3) fi - INTER=$(echo "$line" | grep "WGinterface" | tr " " ",") - if [ ! -z "$INTER" ]; then - wginter=$(echo $INTER | cut -d, -f3) - if [ "$wginter" -gt 1 ]; then - wginter="1" - fi - fi PRK=$(echo "$line" | grep "Address" | tr " " "#") if [ ! -z "$PRK" ]; then if [ -z $Address ]; then @@ -84,8 +73,6 @@ sed -i -e "s!PresharedKey= !PresharedKey=!g" $file sed -i -e "s!PresharedKey=!PresharedKey = !g" $file sed -i -e "s!Address= !Address=!g" $file sed -i -e "s!Address=!Address = !g" $file -sed -i -e "s!WGinterface=!WGinterface = !g" $file -sed -i -e "s!WGinterface= !WGinterface = !g" $file sed -i -e "s!dns= !dns=!g" $file sed -i -e "s!dns=!dns = !g" $file sed -i -e "s!DNS= !DNS=!g" $file @@ -107,9 +94,7 @@ extract "$linex" PRK=$(echo "$endpoint" | tr ":" ",") endpoint=$(echo $PRK | cut -d, -f1) sport=$(echo $PRK | cut -d, -f2) -if [ -z "$wginter" ]; then - wginter="0" -fi + uci delete wireguard.$name uci set wireguard.$name=wireguard uci set wireguard.$name.auto=$auto @@ -120,7 +105,6 @@ uci set wireguard.$name.presharedkey="$PreSharedKey" uci set wireguard.$name.port="$listenport" uci set wireguard.$name.addresses="$Address" uci set wireguard.$name.dns="$dns" -uci set wireguard.$name.wginter="$wginter" uci set wireguard.$name.publickey="$PublicKey" uci set wireguard.$name.endpoint_host="$endpoint" uci set wireguard.$name.ips="$allowedips" diff --git a/rooter/0optionalapps/ext-wireguard/files/usr/lib/wireguard/create.sh b/rooter/0optionalapps/ext-wireguard/files/usr/lib/wireguard/create.sh index 143abe6..9d41829 100644 --- a/rooter/0optionalapps/ext-wireguard/files/usr/lib/wireguard/create.sh +++ b/rooter/0optionalapps/ext-wireguard/files/usr/lib/wireguard/create.sh @@ -33,11 +33,6 @@ do_create() { if [ ! -z $mtu ]; then echo "MTU = "$mtu >> ${PKI_DIR}/package/wg.conf fi - config_get wginter $config wginter - if [ -z"$wginter"]; then - wginter=0 - fi - echo "PrivateKey = "$wginter >> ${PKI_DIR}/package/wg.conf echo " " >> ${PKI_DIR}/package/wg.conf echo "[Peer]" >> ${PKI_DIR}/package/wg.conf PUB=$(uci get wireguard."$WG".publickey) diff --git a/rooter/0optionalapps/ext-wireguard/files/usr/lib/wireguard/startvpn.sh b/rooter/0optionalapps/ext-wireguard/files/usr/lib/wireguard/startvpn.sh index 3e00972..352032d 100644 --- a/rooter/0optionalapps/ext-wireguard/files/usr/lib/wireguard/startvpn.sh +++ b/rooter/0optionalapps/ext-wireguard/files/usr/lib/wireguard/startvpn.sh @@ -20,12 +20,11 @@ chk_zone() { do_dns() { cdns=$1 - local ifce=$2 - ldns=$(uci -q get network.wg$ifce.dns) + ldns=$(uci -q get network.wg0.dns) ex=$(echo "$ldns" | grep "$cdns") if [ -z $ex ]; then - log "Add DNS $cdns to WG$ifce" - uci add_list network.wg$ifce.dns="$cdns" + log "Add DNS $cdns to WG0" + uci add_list network.wg0.dns="$cdns" uci commit network /etc/init.d/network reload fi @@ -88,9 +87,8 @@ create_speer() { create_cpeer() { local config=$1 - local ifce=$2 - uci set network.$config="wireguard_wg$ifce" + uci set network.$config="wireguard_wg0" publickey=$(uci -q get wireguard."$config".publickey) uci set network.$config.public_key="$publickey" @@ -178,51 +176,50 @@ handle_server() { } handle_client() { - ifce=$1 - config_foreach do_delete wireguard_wg$ifce + config_foreach do_delete wireguard_wg0 - uci delete network.wg$ifce - uci set network.wg$ifce="interface" - uci set network.wg$ifce.proto="wireguard" + uci delete network.wg0 + uci set network.wg0="interface" + uci set network.wg0.proto="wireguard" auto=$(uci -q get wireguard."$WG".auto) if [ -z $auto ]; then auto="0" fi - uci set network.wg$ifce.auto="$auto" + uci set network.wg0.auto="$auto" mtu=$(uci -q get wireguard."$WG".mtu) if [ ! -z $mtu ]; then - uci set network.wg$ifce.mtu="$mtu" + uci set network.wg0.mtu="$mtu" fi dns=$(uci -q get wireguard."$WG".dns) if [ ! -z $dns ]; then - do_dns $dns $ifce + do_dns $dns fi port=$(uci -q get wireguard."$WG".port) if [ -z $port ]; then port="51280" fi - uci set network.wg$ifce.listen_port="$port" + uci set network.wg0.listen_port="$port" do_port $port udp privatekey=$(uci -q get wireguard."$WG".privatekey) - uci set network.wg$ifce.private_key="$privatekey" + uci set network.wg0.private_key="$privatekey" ips=$(uci -q get wireguard."$WG".addresses)"," cips=$(echo $ips | cut -d, -f1) i=1 while [ ! -z "$cips" ] do - uci add_list network.wg$ifce.addresses="$cips" + uci add_list network.wg0.addresses="$cips" i=$((i+1)) cips=$(echo "$ips" | cut -d, -f"$i") if [ -z "$cips" ]; then break fi done - uci add_list network.wg$ifce.addresses="::/0" + uci add_list network.wg0.addresses="::/0" - create_cpeer $WG $ifce + create_cpeer $WG uci commit network } @@ -301,19 +298,17 @@ if [ $SERVE = "0" ]; then else running=$(uci -q get wireguard.settings.client) log "Client running $running" - - INTER=$(uci -q get wireguard."$WG".wginter) - if [ -z "$INTER" ]; then - INTER=0 + if [ $running = 1 ]; then + exit 0 fi UDP=$(uci -q get wireguard."$WG".udptunnel) if [ $UDP = 1 ]; then udp_client $WG fi - handle_client $INTER + handle_client uci commit network log "Start Interface" - ifup wg$INTER + ifup wg0 sleep 2 uci set wireguard.settings.client="1" fi diff --git a/rooter/0optionalapps/ext-wireguard/files/usr/lib/wireguard/stopvpn.sh b/rooter/0optionalapps/ext-wireguard/files/usr/lib/wireguard/stopvpn.sh index 9e56adf..91e80dc 100644 --- a/rooter/0optionalapps/ext-wireguard/files/usr/lib/wireguard/stopvpn.sh +++ b/rooter/0optionalapps/ext-wireguard/files/usr/lib/wireguard/stopvpn.sh @@ -44,19 +44,15 @@ if [ $SERVE = "0" ]; then uci add_list network.wg1.addresses="" uci commit network else - INTER=$(uci -q get wireguard."$WG".wginter) - if [ -z "$INTER" ]; then - INTER=0 - fi - ifdown wg$INTER + ifdown wg0 uci set wireguard.settings.client="0" - uci delete network.wg$INTER - uci set network.wg$INTER=interface - uci set network.wg$INTER.proto="wireguard" - uci set network.wg$INTER.auto="0" - uci set network.wg$INTER.private_key="" - uci set network.wg$INTER.listen_port="" - uci add_list network.wg$INTER.addresses="" + uci delete network.wg0 + uci set network.wg0=interface + uci set network.wg0.proto="wireguard" + uci set network.wg0.auto="0" + uci set network.wg0.private_key="" + uci set network.wg0.listen_port="" + uci add_list network.wg0.addresses="" uci commit network fi UDP=$(uci get wireguard."$WG".udptunnel) diff --git a/rooter/0optionalapps/libmicroxml/Makefile b/rooter/0optionalapps/libmicroxml/Makefile new file mode 100644 index 0000000..b9fa2f3 --- /dev/null +++ b/rooter/0optionalapps/libmicroxml/Makefile @@ -0,0 +1,54 @@ +# +# Copyright (C) 2012-2014 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:=libmicroxml +PKG_VERSION:=2015-03-18 +PKG_RELEASE=$(PKG_SOURCE_VERSION) + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://github.com/pivasoftware/microxml.git +PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) +PKG_SOURCE_VERSION:=caa8d3e6887f5c70e54df555dd78e4e45cfa74cc +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz + +PKG_FIXUP:=autoreconf + +include $(INCLUDE_DIR)/package.mk + +define Package/libmicroxml + SECTION:=libs + CATEGORY:=Libraries + TITLE:=XML library + MAINTAINER:=Luka Perkov +endef + +define Package/libmicroxml/description + A micro sized XML library +endef + +CONFIGURE_ARGS += \ + --disable-threads \ + --enable-static \ + --enable-shared + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/include + $(CP) $(PKG_BUILD_DIR)/microxml.h $(1)/usr/include + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_BUILD_DIR)/libmicroxml.so* $(1)/usr/lib + $(INSTALL_DIR) $(1)/usr/lib/pkgconfig + $(CP) $(PKG_BUILD_DIR)/microxml.pc $(1)/usr/lib/pkgconfig +endef + +define Package/libmicroxml/install + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_BUILD_DIR)/libmicroxml.so* $(1)/usr/lib +endef + +$(eval $(call BuildPackage,libmicroxml)) diff --git a/rooter/0optionalapps/luci-app-dnsmasq-ipset/files/usr/lib/lua/luci/controller/dnsmasq-ipset.lua b/rooter/0optionalapps/luci-app-dnsmasq-ipset/files/usr/lib/lua/luci/controller/dnsmasq-ipset.lua index d0a49b0..e1514b0 100644 --- a/rooter/0optionalapps/luci-app-dnsmasq-ipset/files/usr/lib/lua/luci/controller/dnsmasq-ipset.lua +++ b/rooter/0optionalapps/luci-app-dnsmasq-ipset/files/usr/lib/lua/luci/controller/dnsmasq-ipset.lua @@ -3,10 +3,13 @@ module("luci.controller.dnsmasq-ipset", package.seeall) +I18N = require "luci.i18n" +translate = I18N.translate + function index() if not nixio.fs.access("/etc/config/dnsmasq-ipset") then return end - entry({"admin", "network", "dnsmasq-ipset"}, cbi("dnsmasq-ipset"), _("DNSmasq IP-Set"), 60).dependent = true + entry({"admin", "network", "dnsmasq-ipset"}, cbi("dnsmasq-ipset"), _(translate("DNSmasq IP-Set")), 60).dependent = true end diff --git a/rooter/0optionalapps/luci-app-hotspot/files/etc/hotplug.d/iface/99-travelmate-iface b/rooter/0optionalapps/luci-app-hotspot/files/etc/hotplug.d/iface/99-travelmate-iface index c075669..1e1c211 100644 --- a/rooter/0optionalapps/luci-app-hotspot/files/etc/hotplug.d/iface/99-travelmate-iface +++ b/rooter/0optionalapps/luci-app-hotspot/files/etc/hotplug.d/iface/99-travelmate-iface @@ -1,13 +1,12 @@ #!/bin/sh -wif=$(uci -q get travelmate.global.freq) -if [ "$ACTION" = ifup -a "$INTERFACE" = "wwan$wif" ]; then +if [ "$ACTION" = ifup -a "$INTERFACE" = "wwan" ]; then exit 1 fi -if [ "$ACTION" = ifdown -a "$INTERFACE" = "wwan$wif" ]; then - wifilog "HOTSPOT" "hotplug (iface): action='$ACTION' interface='$INTERFACE'" +if [ "$ACTION" = ifdown -a "$INTERFACE" = "wwan" ]; then conn=$(uci -q get travelmate.global.connecting) + wif=$(uci -q get travelmate.global.freq) if [ "$conn" != "1" ]; then uci -q set wireless.wwan$wif.ssid="Hotspot Manager Interface" uci -q set wireless.wwan$wif.encryption="none" @@ -31,7 +30,6 @@ if [ "$ACTION" = ifdown -a "$INTERFACE" = "wwan$wif" ]; then uci set travelmate.global.lost=$lost uci set travelmate.global.delay="30" uci commit travelmate - sleep 10 /usr/lib/hotspot/travelmate.sh & exit 0 fi diff --git a/rooter/0optionalapps/luci-app-hotspot/files/etc/init.d/travelmate b/rooter/0optionalapps/luci-app-hotspot/files/etc/init.d/travelmate index 565844b..7357870 100644 --- a/rooter/0optionalapps/luci-app-hotspot/files/etc/init.d/travelmate +++ b/rooter/0optionalapps/luci-app-hotspot/files/etc/init.d/travelmate @@ -69,16 +69,12 @@ log "Hotspot Firewall" if [ -z $PRO ]; then uci set network.wwan2=interface uci set network.wwan2.proto=dhcp - uci set network.wwan2.metric='2' uci set network.wwan26=interface uci set network.wwan26.proto=dhcpv6 - uci set network.wwan26.metric='2' uci set network.wwan5=interface uci set network.wwan5.proto=dhcp - uci set network.wwan5.metric='2' uci set network.wwan56=interface uci set network.wwan56.proto=dhcpv6 - uci set network.wwan56.metric='2' uci commit network fi config_load firewall diff --git a/rooter/0optionalapps/luci-app-hotspot/files/usr/lib/hotspot/travelmate.sh b/rooter/0optionalapps/luci-app-hotspot/files/usr/lib/hotspot/travelmate.sh index 81574d7..a31d4e0 100644 --- a/rooter/0optionalapps/luci-app-hotspot/files/usr/lib/hotspot/travelmate.sh +++ b/rooter/0optionalapps/luci-app-hotspot/files/usr/lib/hotspot/travelmate.sh @@ -22,7 +22,7 @@ trm_iw=1 trm_auto=$(uci -q get travelmate.global.trm_auto) check_wwan() { - uci set travelmate.global.ssid="8" + uci set travelmate.global.ssid="0" wif=$(uci -q get travelmate.global.freq) if [ -z "$wif" ]; then uci set travelmate.global.freq="2" @@ -280,7 +280,7 @@ f_main() cnt=0 delay=10 reconn=$(uci -q get travelmate.global.reconn) - while [ ${cnt} -lt $reconn ] + while [ ${cnt} -le $reconn ] do f_log "info" " Retry Count ${cnt}" if [ $reconn -eq 99 ]; then @@ -381,10 +381,8 @@ f_main() # No connection to any in list cnt=$((cnt+1)) if [ $reconn -gt 0 ]; then - if [ ${cnt} -lt $reconn ]; then - f_log "info " "Sleep before retrying" - sleep 30 - fi + f_log "info " "Sleep before retrying" + sleep 30 fi # repeat scan and connect done diff --git a/rooter/0optionalapps/luci-app-nft-qos/Makefile b/rooter/0optionalapps/luci-app-iperf/Makefile similarity index 55% rename from rooter/0optionalapps/luci-app-nft-qos/Makefile rename to rooter/0optionalapps/luci-app-iperf/Makefile index 94bf539..264060e 100644 --- a/rooter/0optionalapps/luci-app-nft-qos/Makefile +++ b/rooter/0optionalapps/luci-app-iperf/Makefile @@ -3,32 +3,32 @@ #Copyright GNU act. include $(TOPDIR)/rules.mk -PKG_NAME:=luci-app-nft-qos +PKG_NAME:=luci-app-iperf PKG_VERSION:=1.000 PKG_RELEASE:=1 PKG_MAINTAINER:=Created by DM/makefile by Cobia@whirlpool include $(INCLUDE_DIR)/package.mk -define Package/luci-app-nft-qos +define Package/luci-app-iperf SECTION:=luci CATEGORY:=LuCI - DEPENDS:=+nft-qos + DEPENDS:=+iperf3-ssl SUBMENU:=3. Applications - TITLE:=support for NFT over QOS + TITLE:=support for Iperf PKGARCH:=all endef -define Package/luci-app-nft-qos/description - Helper scripts to enable NFT over QOS +define Package/luci-app-iperf/description + Helper scripts to enable Iperf endef define Build/Compile endef -define Package/luci-app-nft-qos/install +define Package/luci-app-iperf/install $(CP) ./files/* $(1)/ endef -$(eval $(call BuildPackage,luci-app-nft-qos)) +$(eval $(call BuildPackage,luci-app-iperf)) diff --git a/rooter/0optionalapps/luci-app-iperf/files/etc/config/iperf b/rooter/0optionalapps/luci-app-iperf/files/etc/config/iperf new file mode 100644 index 0000000..911c3a1 --- /dev/null +++ b/rooter/0optionalapps/luci-app-iperf/files/etc/config/iperf @@ -0,0 +1,96 @@ +config server 'bouygues' + option host 'bouygues.iperf.fr' + option ipv4 '1' + option ipv6 '1' + option speed '10000' + option ports '5200,5201,5202,5203,5204,5205,5206,5207,5208,5209' + option tcp '1' + option udp '0' + option location 'Europe' + +config server 'online_ipv4' + option host 'ping.online.net' + option ipv4 '1' + option ipv6 '0' + option speed '10000' + option ports '5200,5201,5202,5203,5204,5205,5206,5207,5208,5209' + option tcp '1' + option udp '1' + option location 'Europe' + +config server 'online_ipv6' + option host 'ping.online.net' + option ipv4 '0' + option ipv6 '1' + option speed '10000' + option ports '5200,5201,5202,5203,5204,5205,5206,5207,5208,5209' + option tcp '1' + option udp '1' + option location 'Europe' + +config server 'serverius' + option host 'speedtest.serverius.net' + option ipv4 '1' + option ipv6 '1' + option speed '10000' + option ports '5002' + option tcp '1' + option udp '1' + option location 'Europe' + +config server 'eenet' + option host 'iperf.eenet.ee' + option ipv4 '1' + option ipv6 '0' + option ports '5201' + option tcp '1' + option udp '1' + option location 'Europe' + +config server 'volia' + option host 'iperf.volia.net' + option ipv4 '1' + option ipv6 '0' + option ports '5201' + option tcp '1' + option udp '1' + option location 'Europe' + +config server 'it_north' + option host 'iperf.it-north.net' + option ipv4 '1' + option ipv6 '0' + option speed '1000' + option ports '5200,5201,5202,5203,5204,5205,5206,5207,5208,5209' + option tcp '1' + option udp '1' + option location 'Asia' + +config server 'biznet' + option host 'iperf.biznetnetworkds.com' + option ipv4 '1' + option ipv6 '1' + option speed '1000' + option ports '5201,5202,5203' + option tcp '1' + option udp '0' + option location 'Asia' + +config server 'scottlinux' + option host 'iperf.scottlinux.com' + option ipv4 '1' + option ipv6 '1' + option speed '1000' + option ports '5201' + option tcp '1' + option udp '1' + option location 'America' + +config server 'he' + option host 'iperf.he.net' + option ipv4 '1' + option ipv6 '1' + option ports '5201' + option tcp '1' + option udp '1' + option location 'America' diff --git a/rooter/0optionalapps/luci-app-iperf/files/usr/lib/lua/luci/controller/iperf.lua b/rooter/0optionalapps/luci-app-iperf/files/usr/lib/lua/luci/controller/iperf.lua new file mode 100644 index 0000000..9d3e197 --- /dev/null +++ b/rooter/0optionalapps/luci-app-iperf/files/usr/lib/lua/luci/controller/iperf.lua @@ -0,0 +1,56 @@ +local uci = luci.model.uci.cursor() +local ut = require "luci.util" + +module("luci.controller.iperf", package.seeall) + +function index() + --entry({"admin", "openmptcprouter", "iperf"}, cbi("iperf"), _("iperf")) + entry({"admin", "services", "iperf"}, alias("admin", "services", "iperf", "test"), _("iPerf Speed Test"),72) + entry({"admin", "services", "iperf", "test"}, template("iperf/test"), nil,1) + entry({"admin", "services", "iperf", "run_test"}, post("run_test")).leaf = true +end + +function run_test(server,proto,mode,updown,omit,parallel,transmit,bitrate) + luci.http.prepare_content("text/plain") + local iperf + local addr = uci:get("iperf",server,"host") + local ports = uci:get("iperf",server,"ports") + local user = uci:get("iperf",server,"user") or "" + local password = uci:get("iperf",server,"password") or "" + local key = uci:get("iperf",server,"key") or "" + local options = "" + if user ~= "" and password ~= "" and key ~= "" then + luci.sys.call("echo " .. key .. " | base64 -d > /tmp/iperf.pem") + options = options .. " --username " .. user .. " --rsa-public-key-path /tmp/iperf.pem" + end + if mode == "udp" then + options = options .. " -u -b " .. bitrate + end + if updown ~= "upload" then + options = options .. " -R" + end + local ipv = "4" + if proto == "ipv6" then + local ipv = "6" + end + + local t={} + for pt in ports:gmatch("([^,%s]+)") do + table.insert(t,pt) + end + local port = t[ math.random( #t ) ] + if password ~= "" then + iperf = io.popen("omr-iperf -P %s -%s -O %s -t %s -J -Z %s" % {parallel,ipv,omit,transmit,options}) + else + iperf = io.popen("iperf3 -c %s -P %s -%s -p %s -O %s -t %s -J -Z %s" % {ut.shellquote(addr),parallel,ipv,port,omit,transmit,options}) + end + if iperf then + while true do + local ln = iperf:read("*l") + if not ln then break end + luci.http.write(ln) + luci.http.write("\n") + end + end + return +end \ No newline at end of file diff --git a/rooter/0optionalapps/luci-app-iperf/files/usr/lib/lua/luci/view/iperf/test.htm b/rooter/0optionalapps/luci-app-iperf/files/usr/lib/lua/luci/view/iperf/test.htm new file mode 100644 index 0000000..03d0150 --- /dev/null +++ b/rooter/0optionalapps/luci-app-iperf/files/usr/lib/lua/luci/view/iperf/test.htm @@ -0,0 +1,185 @@ +<%+header%> + +<% + local uci = require("luci.model.uci").cursor() +%> + + + + +<% if stderr and #stderr > 0 then %>
      <%=pcdata(stderr)%>
      <% end %> + +
      +

      <%:iPerf Speed Test%>

      +
      <%:Test Internet speeds using iPerf.%>
      +
      + <%:Settings%> +
      +
      + +
      + +
      +
      +
      + +
      + +
      +
      +
      + +
      + +
      +
      + <%:0 for unlimited.%> +
      +
      +
      + +
      + +
      + +
      +
      +
      + +
      + +
      +
      +
      + +
      + +
      +
      + <%:Server VPS IP is bypassed, so this will test only default route speed.%> +
      +
      +
      + + + +
      +
      + + +
      + + +
      +<%+footer%> diff --git a/rooter/0optionalapps/luci-app-iperf/files/usr/share/luci/menu.d/luci-app-iperf.json b/rooter/0optionalapps/luci-app-iperf/files/usr/share/luci/menu.d/luci-app-iperf.json new file mode 100644 index 0000000..dd6151e --- /dev/null +++ b/rooter/0optionalapps/luci-app-iperf/files/usr/share/luci/menu.d/luci-app-iperf.json @@ -0,0 +1,13 @@ +{ + "admin/services/iperf": { + "title": "iPerf", + "order": 10, + "action": { + "type": "template", + "path": "iperf/test" + }, + "depends": { + "acl": [ "luci-app-iperf" ] + } + } +} diff --git a/rooter/0optionalapps/luci-app-iperf/files/usr/share/rpcd/acl.d/luci-app-iperf.json b/rooter/0optionalapps/luci-app-iperf/files/usr/share/rpcd/acl.d/luci-app-iperf.json new file mode 100644 index 0000000..c851828 --- /dev/null +++ b/rooter/0optionalapps/luci-app-iperf/files/usr/share/rpcd/acl.d/luci-app-iperf.json @@ -0,0 +1,11 @@ +{ + "luci-app-iperf": { + "description": "Grant UCI access for luci-app-iperf", + "read": { + "uci": [ "iperf" ] + }, + "write": { + "uci": [ "iperf" ] + } + } +} \ No newline at end of file diff --git a/rooter/0optionalapps/luci-app-nft-qos/files/usr/lib/lua/luci/controller/nft-qos.lua b/rooter/0optionalapps/luci-app-nft-qos/files/usr/lib/lua/luci/controller/nft-qos.lua deleted file mode 100644 index 637eb11..0000000 --- a/rooter/0optionalapps/luci-app-nft-qos/files/usr/lib/lua/luci/controller/nft-qos.lua +++ /dev/null @@ -1,55 +0,0 @@ --- Copyright 2018 Rosy Song --- Licensed to the public under the Apache License 2.0. - -module("luci.controller.nft-qos", package.seeall) - -function index() - if not nixio.fs.access("/etc/config/nft-qos") then - return - end - - entry({"admin", "status", "realtime", "rate"}, - template("nft-qos/rate"), _("Rate"), 5).leaf = true - entry({"admin", "status", "realtime", "rate_status"}, - call("action_rate")).leaf = true - entry({"admin", "services", "nft-qos"}, cbi("nft-qos/nft-qos"), - _("Qos over Nftables"), 60) -end - -function _action_rate(rv, n) - local c = nixio.fs.access("/proc/net/ipv6_route") and - io.popen("nft list chain inet nft-qos-monitor " .. n .. " 2>/dev/null") or - io.popen("nft list chain ip nft-qos-monitor " .. n .. " 2>/dev/null") - - if c then - for l in c:lines() do - local _, i, p, b = l:match( - '^%s+ip ([^%s]+) ([^%s]+) counter packets (%d+) bytes (%d+)' - ) - if i and p and b then - -- handle expression - rv[#rv + 1] = { - rule = { - family = "inet", - table = "nft-qos-monitor", - chain = n, - handle = 0, - expr = { - { match = { right = i } }, - { counter = { packets = p, bytes = b } } - } - } - } - end - end - c:close() - end -end - -function action_rate() - luci.http.prepare_content("application/json") - local data = { nftables = {} } - _action_rate(data.nftables, "upload") - _action_rate(data.nftables, "download") - luci.http.write_json(data) -end diff --git a/rooter/0optionalapps/luci-app-nft-qos/files/usr/lib/lua/luci/model/cbi/nft-qos/nft-qos.lua b/rooter/0optionalapps/luci-app-nft-qos/files/usr/lib/lua/luci/model/cbi/nft-qos/nft-qos.lua deleted file mode 100644 index 61a6d76..0000000 --- a/rooter/0optionalapps/luci-app-nft-qos/files/usr/lib/lua/luci/model/cbi/nft-qos/nft-qos.lua +++ /dev/null @@ -1,229 +0,0 @@ --- Copyright 2018 Rosy Song --- Licensed to the public under the Apache License 2.0. - -local uci = require("luci.model.uci").cursor() -local wa = require("luci.tools.webadmin") -local fs = require("nixio.fs") -local ipc = require("luci.ip") - -local def_rate_dl = uci:get("nft-qos", "default", "static_rate_dl") -local def_rate_ul = uci:get("nft-qos", "default", "static_rate_ul") -local def_unit_dl = uci:get("nft-qos", "default", "static_unit_dl") -local def_unit_ul = uci:get("nft-qos", "default", "static_unit_ul") - -local def_up = uci:get("nft-qos", "default", "dynamic_bw_up") -local def_down = uci:get("nft-qos", "default", "dynamic_bw_down") - -local limit_enable = uci:get("nft-qos", "default", "limit_enable") -local limit_type = uci:get("nft-qos", "default", "limit_type") -local enable_priority = uci:get("nft-qos", "default", "priority_enable") - -local has_ipv6 = fs.access("/proc/net/ipv6_route") - -m = Map("nft-qos", translate("Qos over Nftables")) - --- --- Taboptions --- -s = m:section(TypedSection, "default", translate("NFT-QoS Settings")) -s.addremove = false -s.anonymous = true - -s:tab("limit", "Limit Rate") -s:tab("priority", "Traffic Priority") - --- --- Static --- -o = s:taboption("limit", Flag, "limit_enable", translate("Limit Enable"), translate("Enable Limit Rate Feature")) -o.default = limit_enable or o.enabled -o.rmempty = false - -o = s:taboption("limit", ListValue, "limit_type", translate("Limit Type"), translate("Type of Limit Rate")) -o.default = limit_static or "static" -o:depends("limit_enable","1") -o:value("static", "Static") -o:value("dynamic", "Dynamic") - -o = s:taboption("limit", Value, "static_rate_dl", translate("Default Download Rate"), translate("Default value for download rate")) -o.datatype = "uinteger" -o.default = def_rate_dl or '50' -o:depends("limit_type","static") - -o = s:taboption("limit", ListValue, "static_unit_dl", translate("Default Download Unit"), translate("Default unit for download rate")) -o.default = def_unit_dl or "kbytes" -o:depends("limit_type","static") -o:value("bytes", "Bytes/s") -o:value("kbytes", "KBytes/s") -o:value("mbytes", "MBytes/s") - -o = s:taboption("limit", Value, "static_rate_ul", translate("Default Upload Rate"), translate("Default value for upload rate")) -o.datatype = "uinteger" -o.default = def_rate_ul or '50' -o:depends("limit_type","static") - -o = s:taboption("limit", ListValue, "static_unit_ul", translate("Default Upload Unit"), translate("Default unit for upload rate")) -o.default = def_unit_ul or "kbytes" -o:depends("limit_type","static") -o:value("bytes", "Bytes/s") -o:value("kbytes", "KBytes/s") -o:value("mbytes", "MBytes/s") - --- --- Dynamic --- -o = s:taboption("limit", Value, "dynamic_bw_down", translate("Download Bandwidth (Mbps)"), translate("Default value for download bandwidth")) -o.default = def_up or '100' -o.datatype = "uinteger" -o:depends("limit_type","dynamic") - -o = s:taboption("limit", Value, "dynamic_bw_up", translate("Upload Bandwidth (Mbps)"), translate("Default value for upload bandwidth")) -o.default = def_down or '100' -o.datatype = "uinteger" -o:depends("limit_type","dynamic") - -o = s:taboption("limit", Value, "dynamic_cidr", translate("Target Network (IPv4/MASK)"), translate("Network to be apply, e.g. 192.168.1.0/24, 10.2.0.0/16, etc")) -o.datatype = "cidr4" -ipc.routes({ family = 4, type = 1 }, function(rt) o.default = rt.dest end) -o:depends("limit_type","dynamic") - -if has_ipv6 then - o = s:taboption("limit", Value, "dynamic_cidr6", translate("Target Network6 (IPv6/MASK)"), translate("Network to be apply, e.g. AAAA::BBBB/64, CCCC::1/128, etc")) - o.datatype = "cidr6" - o:depends("limit_type","dynamic") -end - -o = s:taboption("limit", DynamicList, "limit_whitelist", translate("White List for Limit Rate")) -o.datatype = "ipaddr" -o:depends("limit_enable","1") - --- --- Priority --- -o = s:taboption("priority", Flag, "priority_enable", translate("Enable Traffic Priority"), translate("Enable this feature")) -o.default = enable_priority or o.enabled -o.rmempty = false - -o = s:taboption("priority", ListValue, "priority_netdev", translate("Default Network Interface"), translate("Network Interface for Traffic Shaping, e.g. br-lan, eth0.1, eth0, etc")) -o:depends("priority_enable", "1") -wa.cbi_add_networks(o) - --- --- Static Limit Rate - Download Rate --- -if limit_enable == "1" and limit_type == "static" then - -x = m:section(TypedSection, "download", translate("Static QoS-Download Rate")) -x.anonymous = true -x.addremove = true -x.template = "cbi/tblsection" - -o = x:option(Value, "hostname", translate("Hostname")) -o.datatype = "hostname" -o.default = 'undefined' - -if has_ipv6 then - o = x:option(Value, "ipaddr", translate("IP Address(V4 / V6)")) -else - o = x:option(Value, "ipaddr", translate("IP Address(V4 Only)")) -end -o.datatype = "ipaddr" -if nixio.fs.access("/tmp/dhcp.leases") or nixio.fs.access("/var/dhcp6.leases") then - o.titleref = luci.dispatcher.build_url("admin", "status", "overview") -end - -o = x:option(Value, "macaddr", translate("MAC (optional)")) -o.rmempty = true -o.datatype = "macaddr" - -o = x:option(Value, "rate", translate("Rate")) -o.default = def_rate_dl or '50' -o.size = 4 -o.datatype = "uinteger" - -o = x:option(ListValue, "unit", translate("Unit")) -o.default = def_unit_dl or "kbytes" -o:value("bytes", "Bytes/s") -o:value("kbytes", "KBytes/s") -o:value("mbytes", "MBytes/s") - --- --- Static Limit Rate - Upload Rate --- -y = m:section(TypedSection, "upload", translate("Static QoS-Upload Rate")) -y.anonymous = true -y.addremove = true -y.template = "cbi/tblsection" - -o = y:option(Value, "hostname", translate("Hostname")) -o.datatype = "hostname" -o.default = 'undefined' - -if has_ipv6 then - o = y:option(Value, "ipaddr", translate("IP Address(V4 / V6)")) -else - o = y:option(Value, "ipaddr", translate("IP Address(V4 Only)")) -end -o.datatype = "ipaddr" -if nixio.fs.access("/tmp/dhcp.leases") or nixio.fs.access("/var/dhcp6.leases") then - o.titleref = luci.dispatcher.build_url("admin", "status", "overview") -end - -o = y:option(Value, "macaddr", translate("MAC (optional)")) -o.rmempty = true -o.datatype = "macaddr" - -o = y:option(Value, "rate", translate("Rate")) -o.default = def_rate_ul or '50' -o.size = 4 -o.datatype = "uinteger" - -o = y:option(ListValue, "unit", translate("Unit")) -o.default = def_unit_ul or "kbytes" -o:value("bytes", "Bytes/s") -o:value("kbytes", "KBytes/s") -o:value("mbytes", "MBytes/s") - -end - --- --- Traffic Priority Settings --- -if enable_priority == "1" then - -s = m:section(TypedSection, "priority", translate("Traffic Priority Settings")) -s.anonymous = true -s.addremove = true -s.template = "cbi/tblsection" - -o = s:option(ListValue, "protocol", translate("Protocol")) -o.default = "tcp" -o:value("tcp", "TCP") -o:value("udp", "UDP") -o:value("udplite", "UDP-Lite") -o:value("sctp", "SCTP") -o:value("dccp", "DCCP") - -o = s:option(ListValue, "priority", translate("Priority")) -o.default = "1" -o:value("-400", "1") -o:value("-300", "2") -o:value("-225", "3") -o:value("-200", "4") -o:value("-150", "5") -o:value("-100", "6") -o:value("0", "7") -o:value("50", "8") -o:value("100", "9") -o:value("225", "10") -o:value("300", "11") - -o = s:option(Value, "service", translate("Service"), translate("e.g. https, 23, (separator is comma)")) -o.default = '?' - -o = s:option(Value, "comment", translate("Comment")) -o.default = '?' - -end - -return m diff --git a/rooter/0optionalapps/luci-app-nft-qos/files/usr/lib/lua/luci/view/nft-qos/rate.htm b/rooter/0optionalapps/luci-app-nft-qos/files/usr/lib/lua/luci/view/nft-qos/rate.htm deleted file mode 100644 index 5f9cb57..0000000 --- a/rooter/0optionalapps/luci-app-nft-qos/files/usr/lib/lua/luci/view/nft-qos/rate.htm +++ /dev/null @@ -1,167 +0,0 @@ -<%# - Copyright 2018 Rosy Song - Licensed to the public under the Apache License 2.0. --%> - -<%+header%> - - - -

      <%:Realtime Rate%>

      - -
      <%:This page gives an overview over currently download/upload rate.%>
      - -
      - <%:Realtime Download Rate%> -
      -
      -
      -
      <%:IP Address%>
      -
      <%:Download Rate%>
      -
      <%:Bytes Total%>
      -
      <%:Packets Total%>
      -
      -
      -
      - <%:Collecting data...%> -
      -
      -
      -
      -
      - -
      - <%:Realtime Upload Rate%> -
      -
      -
      -
      <%:IP Address%>
      -
      <%:Upload Rate%>
      -
      <%:Bytes Total%>
      -
      <%:Packets Total%>
      -
      -
      -
      - <%:Collecting data...%> -
      -
      -
      -
      -
      - -<%+footer%> diff --git a/rooter/0optionalapps/luci-app-nft-qos/po/bg/nft-qos.po b/rooter/0optionalapps/luci-app-nft-qos/po/bg/nft-qos.po deleted file mode 100644 index 6bfdc6b..0000000 --- a/rooter/0optionalapps/luci-app-nft-qos/po/bg/nft-qos.po +++ /dev/null @@ -1,233 +0,0 @@ -msgid "" -msgstr "" -"Language: bg\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:136 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:155 -msgid "Bytes Total" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:141 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:160 -msgid "Collecting data..." -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:224 -msgid "Comment" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default Download Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Default Network Interface" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default Upload Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default unit for download rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default unit for upload rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Default value for download bandwidth" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default value for download rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Default value for upload bandwidth" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default value for upload rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Download Bandwidth (Mbps)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:135 -msgid "Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Enable Limit Rate Feature" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable Traffic Priority" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable this feature" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:121 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:158 -msgid "Hostname" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:134 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:153 -msgid "IP Address" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:126 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:163 -msgid "IP Address(V4 / V6)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:128 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:165 -msgid "IP Address(V4 Only)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Limit Enable" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Limit Type" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:135 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:172 -msgid "MAC (optional)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:48 -msgid "MB" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:28 -msgid "NFT-QoS Settings" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Network Interface for Traffic Shaping, e.g. br-lan, eth0.1, eth0, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Network to be apply, e.g. 192.168.1.0/24, 10.2.0.0/16, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Network to be apply, e.g. AAAA::BBBB/64, CCCC::1/128, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:65 -msgid "No information available" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:137 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:156 -msgid "Packets Total" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:207 -msgid "Priority" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:199 -msgid "Protocol" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:16 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:23 -msgid "Qos over Nftables" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:12 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:139 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:176 -msgid "Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:130 -msgid "Realtime Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:125 -msgid "Realtime Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:149 -msgid "Realtime Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "Service" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:116 -msgid "Static QoS-Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:153 -msgid "Static QoS-Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Target Network (IPv4/MASK)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Target Network6 (IPv6/MASK)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:127 -msgid "This page gives an overview over currently download/upload rate." -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:194 -msgid "Traffic Priority Settings" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Type of Limit Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:144 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:181 -msgid "Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Upload Bandwidth (Mbps)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:154 -msgid "Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:96 -msgid "White List for Limit Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "e.g. https, 23, (separator is comma)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:44 -msgid "kB" -msgstr "" diff --git a/rooter/0optionalapps/luci-app-nft-qos/po/ca/nft-qos.po b/rooter/0optionalapps/luci-app-nft-qos/po/ca/nft-qos.po deleted file mode 100644 index c2eef3c..0000000 --- a/rooter/0optionalapps/luci-app-nft-qos/po/ca/nft-qos.po +++ /dev/null @@ -1,239 +0,0 @@ -msgid "" -msgstr "" -"PO-Revision-Date: 2020-01-10 12:23+0000\n" -"Last-Translator: Adolfo Jayme Barrientos \n" -"Language-Team: Catalan \n" -"Language: ca\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 3.10.1\n" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:136 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:155 -msgid "Bytes Total" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:141 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:160 -msgid "Collecting data..." -msgstr "S’estan recollint dades…" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:224 -msgid "Comment" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default Download Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Default Network Interface" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default Upload Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default unit for download rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default unit for upload rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Default value for download bandwidth" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default value for download rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Default value for upload bandwidth" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default value for upload rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Download Bandwidth (Mbps)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:135 -msgid "Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Enable Limit Rate Feature" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable Traffic Priority" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable this feature" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:121 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:158 -msgid "Hostname" -msgstr "Nom de l’amfitrió" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:134 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:153 -msgid "IP Address" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:126 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:163 -msgid "IP Address(V4 / V6)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:128 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:165 -msgid "IP Address(V4 Only)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Limit Enable" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Limit Type" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:135 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:172 -msgid "MAC (optional)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:48 -msgid "MB" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:28 -msgid "NFT-QoS Settings" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Network Interface for Traffic Shaping, e.g. br-lan, eth0.1, eth0, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Network to be apply, e.g. 192.168.1.0/24, 10.2.0.0/16, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Network to be apply, e.g. AAAA::BBBB/64, CCCC::1/128, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:65 -msgid "No information available" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:137 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:156 -msgid "Packets Total" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:207 -msgid "Priority" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:199 -msgid "Protocol" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:16 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:23 -msgid "Qos over Nftables" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:12 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:139 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:176 -msgid "Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:130 -msgid "Realtime Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:125 -msgid "Realtime Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:149 -msgid "Realtime Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "Service" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:116 -msgid "Static QoS-Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:153 -msgid "Static QoS-Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Target Network (IPv4/MASK)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Target Network6 (IPv6/MASK)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:127 -msgid "This page gives an overview over currently download/upload rate." -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:194 -msgid "Traffic Priority Settings" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Type of Limit Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:144 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:181 -msgid "Unit" -msgstr "Unitat" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Upload Bandwidth (Mbps)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:154 -msgid "Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:96 -msgid "White List for Limit Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "e.g. https, 23, (separator is comma)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:44 -msgid "kB" -msgstr "" diff --git a/rooter/0optionalapps/luci-app-nft-qos/po/cs/nft-qos.po b/rooter/0optionalapps/luci-app-nft-qos/po/cs/nft-qos.po deleted file mode 100644 index acc9a0f..0000000 --- a/rooter/0optionalapps/luci-app-nft-qos/po/cs/nft-qos.po +++ /dev/null @@ -1,239 +0,0 @@ -msgid "" -msgstr "" -"PO-Revision-Date: 2020-02-04 05:03+0000\n" -"Last-Translator: Pavel Borecki \n" -"Language-Team: Czech \n" -"Language: cs\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 3.11-dev\n" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:136 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:155 -msgid "Bytes Total" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:141 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:160 -msgid "Collecting data..." -msgstr "Shromažďování údajů…" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:224 -msgid "Comment" -msgstr "Komentář" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default Download Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Default Network Interface" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default Upload Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default unit for download rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default unit for upload rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Default value for download bandwidth" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default value for download rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Default value for upload bandwidth" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default value for upload rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Download Bandwidth (Mbps)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:135 -msgid "Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Enable Limit Rate Feature" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable Traffic Priority" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable this feature" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:121 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:158 -msgid "Hostname" -msgstr "Název počítače" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:134 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:153 -msgid "IP Address" -msgstr "IP adresa" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:126 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:163 -msgid "IP Address(V4 / V6)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:128 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:165 -msgid "IP Address(V4 Only)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Limit Enable" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Limit Type" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:135 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:172 -msgid "MAC (optional)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:48 -msgid "MB" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:28 -msgid "NFT-QoS Settings" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Network Interface for Traffic Shaping, e.g. br-lan, eth0.1, eth0, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Network to be apply, e.g. 192.168.1.0/24, 10.2.0.0/16, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Network to be apply, e.g. AAAA::BBBB/64, CCCC::1/128, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:65 -msgid "No information available" -msgstr "Údaje nejsou k dispozici" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:137 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:156 -msgid "Packets Total" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:207 -msgid "Priority" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:199 -msgid "Protocol" -msgstr "Protokol" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:16 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:23 -msgid "Qos over Nftables" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:12 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:139 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:176 -msgid "Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:130 -msgid "Realtime Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:125 -msgid "Realtime Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:149 -msgid "Realtime Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "Service" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:116 -msgid "Static QoS-Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:153 -msgid "Static QoS-Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Target Network (IPv4/MASK)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Target Network6 (IPv6/MASK)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:127 -msgid "This page gives an overview over currently download/upload rate." -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:194 -msgid "Traffic Priority Settings" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Type of Limit Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:144 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:181 -msgid "Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Upload Bandwidth (Mbps)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:154 -msgid "Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:96 -msgid "White List for Limit Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "e.g. https, 23, (separator is comma)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:44 -msgid "kB" -msgstr "" diff --git a/rooter/0optionalapps/luci-app-nft-qos/po/de/nft-qos.po b/rooter/0optionalapps/luci-app-nft-qos/po/de/nft-qos.po deleted file mode 100644 index 2c14fe3..0000000 --- a/rooter/0optionalapps/luci-app-nft-qos/po/de/nft-qos.po +++ /dev/null @@ -1,240 +0,0 @@ -msgid "" -msgstr "" -"PO-Revision-Date: 2020-07-11 21:29+0000\n" -"Last-Translator: ssantos \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.2-dev\n" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:136 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:155 -msgid "Bytes Total" -msgstr "Bytes Gesamt" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:141 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:160 -msgid "Collecting data..." -msgstr "Sammle Daten..." - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:224 -msgid "Comment" -msgstr "Kommentar" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default Download Rate" -msgstr "Standard-Downloadrate" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default Download Unit" -msgstr "Standard-Download-Einheit" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Default Network Interface" -msgstr "Standard-Netzwerkschnittstelle" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default Upload Rate" -msgstr "Standard-Uploadrate" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default Upload Unit" -msgstr "Standard-Upload-Einheit" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default unit for download rate" -msgstr "Standardeinheit für Downloadrate" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default unit for upload rate" -msgstr "Standardeinheit für Upload-Rate" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Default value for download bandwidth" -msgstr "Standardwert für Download-Bandbreite" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default value for download rate" -msgstr "Standardwert für Downloadrate" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Default value for upload bandwidth" -msgstr "Standardwert für Upload-Bandbreite" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default value for upload rate" -msgstr "Standardwert für Upload-Rate" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Download Bandwidth (Mbps)" -msgstr "Download-Bandbreite (Mbps)" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:135 -msgid "Download Rate" -msgstr "Download-Rate" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Enable Limit Rate Feature" -msgstr "Aktiviere die Limit-Rate-Funktion" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable Traffic Priority" -msgstr "Aktiviere Traffic-Priorisierung" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable this feature" -msgstr "Diese Funktion aktivieren" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:121 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:158 -msgid "Hostname" -msgstr "Hostname" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:134 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:153 -msgid "IP Address" -msgstr "IP-Adresse" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:126 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:163 -msgid "IP Address(V4 / V6)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:128 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:165 -msgid "IP Address(V4 Only)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Limit Enable" -msgstr "Limit aktivieren" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Limit Type" -msgstr "Limit-Typ" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:135 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:172 -msgid "MAC (optional)" -msgstr "MAC (optional)" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:48 -msgid "MB" -msgstr "MB" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:28 -msgid "NFT-QoS Settings" -msgstr "NFT-QoS-Einstellungen" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Network Interface for Traffic Shaping, e.g. br-lan, eth0.1, eth0, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Network to be apply, e.g. 192.168.1.0/24, 10.2.0.0/16, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Network to be apply, e.g. AAAA::BBBB/64, CCCC::1/128, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:65 -msgid "No information available" -msgstr "Keine Informationen verfügbar" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:137 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:156 -msgid "Packets Total" -msgstr "Pakete Gesamt" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:207 -msgid "Priority" -msgstr "Priorität" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:199 -msgid "Protocol" -msgstr "Protokoll" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:16 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:23 -msgid "Qos over Nftables" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:12 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:139 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:176 -msgid "Rate" -msgstr "Rate" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:130 -msgid "Realtime Download Rate" -msgstr "Echtzeit-Downloadrate" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:125 -msgid "Realtime Rate" -msgstr "Echtzeit-Rate" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:149 -msgid "Realtime Upload Rate" -msgstr "Echtzeit-Uploadrate" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "Service" -msgstr "Service" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:116 -msgid "Static QoS-Download Rate" -msgstr "Statische QoS-Download-Rate" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:153 -msgid "Static QoS-Upload Rate" -msgstr "Statische QoS-Upload-Rate" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Target Network (IPv4/MASK)" -msgstr "Zielnetzwerk (IPv4/MASK)" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Target Network6 (IPv6/MASK)" -msgstr "Zielnetzwerk6 (IPv6/MASK)" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:127 -msgid "This page gives an overview over currently download/upload rate." -msgstr "" -"Diese Seite gibt einen Überblick über die aktuelle Download-/Uploadrate." - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:194 -msgid "Traffic Priority Settings" -msgstr "Einstellungen für Traffic-Priorität" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Type of Limit Rate" -msgstr "Typ der Limit-Rate" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:144 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:181 -msgid "Unit" -msgstr "Einheit" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Upload Bandwidth (Mbps)" -msgstr "Upload-Bandbreite (Mbps)" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:154 -msgid "Upload Rate" -msgstr "Uploadrate" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:96 -msgid "White List for Limit Rate" -msgstr "Whitelist für die Limit-Rate" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "e.g. https, 23, (separator is comma)" -msgstr "z.B. https, 23, (Trennzeichen ist Komma)" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:44 -msgid "kB" -msgstr "kB" diff --git a/rooter/0optionalapps/luci-app-nft-qos/po/el/nft-qos.po b/rooter/0optionalapps/luci-app-nft-qos/po/el/nft-qos.po deleted file mode 100644 index 57aa172..0000000 --- a/rooter/0optionalapps/luci-app-nft-qos/po/el/nft-qos.po +++ /dev/null @@ -1,239 +0,0 @@ -msgid "" -msgstr "" -"PO-Revision-Date: 2020-12-01 16:16+0000\n" -"Last-Translator: Marios Koutsoukis \n" -"Language-Team: Greek \n" -"Language: el\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.4-dev\n" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:136 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:155 -msgid "Bytes Total" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:141 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:160 -msgid "Collecting data..." -msgstr "Συλλογή δεδομένων..." - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:224 -msgid "Comment" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default Download Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Default Network Interface" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default Upload Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default unit for download rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default unit for upload rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Default value for download bandwidth" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default value for download rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Default value for upload bandwidth" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default value for upload rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Download Bandwidth (Mbps)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:135 -msgid "Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Enable Limit Rate Feature" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable Traffic Priority" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable this feature" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:121 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:158 -msgid "Hostname" -msgstr "Όνομα κεντρικού υπολογιστή" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:134 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:153 -msgid "IP Address" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:126 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:163 -msgid "IP Address(V4 / V6)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:128 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:165 -msgid "IP Address(V4 Only)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Limit Enable" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Limit Type" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:135 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:172 -msgid "MAC (optional)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:48 -msgid "MB" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:28 -msgid "NFT-QoS Settings" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Network Interface for Traffic Shaping, e.g. br-lan, eth0.1, eth0, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Network to be apply, e.g. 192.168.1.0/24, 10.2.0.0/16, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Network to be apply, e.g. AAAA::BBBB/64, CCCC::1/128, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:65 -msgid "No information available" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:137 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:156 -msgid "Packets Total" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:207 -msgid "Priority" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:199 -msgid "Protocol" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:16 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:23 -msgid "Qos over Nftables" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:12 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:139 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:176 -msgid "Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:130 -msgid "Realtime Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:125 -msgid "Realtime Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:149 -msgid "Realtime Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "Service" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:116 -msgid "Static QoS-Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:153 -msgid "Static QoS-Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Target Network (IPv4/MASK)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Target Network6 (IPv6/MASK)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:127 -msgid "This page gives an overview over currently download/upload rate." -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:194 -msgid "Traffic Priority Settings" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Type of Limit Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:144 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:181 -msgid "Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Upload Bandwidth (Mbps)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:154 -msgid "Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:96 -msgid "White List for Limit Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "e.g. https, 23, (separator is comma)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:44 -msgid "kB" -msgstr "" diff --git a/rooter/0optionalapps/luci-app-nft-qos/po/en/nft-qos.po b/rooter/0optionalapps/luci-app-nft-qos/po/en/nft-qos.po deleted file mode 100644 index f3e6b42..0000000 --- a/rooter/0optionalapps/luci-app-nft-qos/po/en/nft-qos.po +++ /dev/null @@ -1,233 +0,0 @@ -msgid "" -msgstr "" -"Language: en\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:136 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:155 -msgid "Bytes Total" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:141 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:160 -msgid "Collecting data..." -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:224 -msgid "Comment" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default Download Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Default Network Interface" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default Upload Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default unit for download rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default unit for upload rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Default value for download bandwidth" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default value for download rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Default value for upload bandwidth" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default value for upload rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Download Bandwidth (Mbps)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:135 -msgid "Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Enable Limit Rate Feature" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable Traffic Priority" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable this feature" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:121 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:158 -msgid "Hostname" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:134 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:153 -msgid "IP Address" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:126 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:163 -msgid "IP Address(V4 / V6)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:128 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:165 -msgid "IP Address(V4 Only)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Limit Enable" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Limit Type" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:135 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:172 -msgid "MAC (optional)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:48 -msgid "MB" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:28 -msgid "NFT-QoS Settings" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Network Interface for Traffic Shaping, e.g. br-lan, eth0.1, eth0, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Network to be apply, e.g. 192.168.1.0/24, 10.2.0.0/16, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Network to be apply, e.g. AAAA::BBBB/64, CCCC::1/128, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:65 -msgid "No information available" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:137 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:156 -msgid "Packets Total" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:207 -msgid "Priority" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:199 -msgid "Protocol" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:16 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:23 -msgid "Qos over Nftables" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:12 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:139 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:176 -msgid "Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:130 -msgid "Realtime Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:125 -msgid "Realtime Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:149 -msgid "Realtime Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "Service" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:116 -msgid "Static QoS-Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:153 -msgid "Static QoS-Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Target Network (IPv4/MASK)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Target Network6 (IPv6/MASK)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:127 -msgid "This page gives an overview over currently download/upload rate." -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:194 -msgid "Traffic Priority Settings" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Type of Limit Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:144 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:181 -msgid "Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Upload Bandwidth (Mbps)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:154 -msgid "Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:96 -msgid "White List for Limit Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "e.g. https, 23, (separator is comma)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:44 -msgid "kB" -msgstr "" diff --git a/rooter/0optionalapps/luci-app-nft-qos/po/es/nft-qos.po b/rooter/0optionalapps/luci-app-nft-qos/po/es/nft-qos.po deleted file mode 100644 index f12d261..0000000 --- a/rooter/0optionalapps/luci-app-nft-qos/po/es/nft-qos.po +++ /dev/null @@ -1,246 +0,0 @@ -msgid "" -msgstr "" -"Project-Id-Version: \n" -"POT-Creation-Date: \n" -"PO-Revision-Date: 2020-09-18 18:36+0000\n" -"Last-Translator: Franco Castillo \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.3-dev\n" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:136 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:155 -msgid "Bytes Total" -msgstr "Total de bytes" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:141 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:160 -msgid "Collecting data..." -msgstr "Recolectando datos…" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:224 -msgid "Comment" -msgstr "Comentario" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default Download Rate" -msgstr "Velocidad de descarga predeterminada" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default Download Unit" -msgstr "Unidad de descarga predeterminada" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Default Network Interface" -msgstr "Interfaz de red predeterminada" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default Upload Rate" -msgstr "Velocidad de carga predeterminada" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default Upload Unit" -msgstr "Unidad de carga predeterminada" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default unit for download rate" -msgstr "Unidad predeterminada para la velocidad de descarga" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default unit for upload rate" -msgstr "Unidad predeterminada para la velocidad de carga" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Default value for download bandwidth" -msgstr "Valor predeterminado para el ancho de banda de descarga" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default value for download rate" -msgstr "Valor predeterminado para la velocidad de descarga" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Default value for upload bandwidth" -msgstr "Valor predeterminado para el ancho de banda de carga" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default value for upload rate" -msgstr "Valor predeterminado para la velocidad de carga" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Download Bandwidth (Mbps)" -msgstr "Ancho de banda de descarga (Mbps)" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:135 -msgid "Download Rate" -msgstr "Velocidad de descarga" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Enable Limit Rate Feature" -msgstr "Activar función de límite de velocidad" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable Traffic Priority" -msgstr "Activar prioridad de tráfico" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable this feature" -msgstr "Activar esta característica" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:121 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:158 -msgid "Hostname" -msgstr "Nombre del host" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:134 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:153 -msgid "IP Address" -msgstr "Dirección IP" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:126 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:163 -msgid "IP Address(V4 / V6)" -msgstr "Dirección IP (v4/v6)" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:128 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:165 -msgid "IP Address(V4 Only)" -msgstr "Dirección IP (sólo v4)" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Limit Enable" -msgstr "Activar límite" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Limit Type" -msgstr "Tipo de límite" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:135 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:172 -msgid "MAC (optional)" -msgstr "MAC (opcional)" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:48 -msgid "MB" -msgstr "MB" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:28 -msgid "NFT-QoS Settings" -msgstr "Configuración de NFT-QoS" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Network Interface for Traffic Shaping, e.g. br-lan, eth0.1, eth0, etc" -msgstr "" -"Interfaz de red para configuración de tráfico, por ejemplo, br-lan, eth0.1, " -"eth0, etc." - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Network to be apply, e.g. 192.168.1.0/24, 10.2.0.0/16, etc" -msgstr "Red a aplicar, por ejemplo. 192.168.1.0/24, 10.2.0.0/16, etc." - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Network to be apply, e.g. AAAA::BBBB/64, CCCC::1/128, etc" -msgstr "Red a aplicar, por ejemplo. AAAA::BBBB/64, CCCC::1/128, etc." - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:65 -msgid "No information available" -msgstr "No hay información disponible" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:137 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:156 -msgid "Packets Total" -msgstr "Paquetes totales" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:207 -msgid "Priority" -msgstr "Prioridad" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:199 -msgid "Protocol" -msgstr "Protocolo" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:16 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:23 -msgid "Qos over Nftables" -msgstr "Qos sobre Nftables" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:12 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:139 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:176 -msgid "Rate" -msgstr "Velocidad" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:130 -msgid "Realtime Download Rate" -msgstr "Velocidad de descarga en tiempo real" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:125 -msgid "Realtime Rate" -msgstr "Velocidad en tiempo real" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:149 -msgid "Realtime Upload Rate" -msgstr "Velocidad de carga en tiempo real" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "Service" -msgstr "Servicio" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:116 -msgid "Static QoS-Download Rate" -msgstr "Velocidad de descarga de QoS estática" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:153 -msgid "Static QoS-Upload Rate" -msgstr "Velocidad de carga de QoS estática" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Target Network (IPv4/MASK)" -msgstr "Red de destino (IPv4 / MASK)" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Target Network6 (IPv6/MASK)" -msgstr "Red de destino 6 (IPv6/MÁSCARA)" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:127 -msgid "This page gives an overview over currently download/upload rate." -msgstr "" -"Esta página ofrece una vista general sobre la velocidad de descarga/carga " -"actual." - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:194 -msgid "Traffic Priority Settings" -msgstr "Ajustes de prioridad de tráfico" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Type of Limit Rate" -msgstr "Tipo de límite de velocidad" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:144 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:181 -msgid "Unit" -msgstr "Unidad" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Upload Bandwidth (Mbps)" -msgstr "Ancho de banda de carga (Mbps)" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:154 -msgid "Upload Rate" -msgstr "Velocidad de carga" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:96 -msgid "White List for Limit Rate" -msgstr "Lista blanca para el límite de velocidad" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "e.g. https, 23, (separator is comma)" -msgstr "p.ej. https, 23, (el separador es una coma)" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:44 -msgid "kB" -msgstr "kB" diff --git a/rooter/0optionalapps/luci-app-nft-qos/po/fr/nft-qos.po b/rooter/0optionalapps/luci-app-nft-qos/po/fr/nft-qos.po deleted file mode 100644 index 391c427..0000000 --- a/rooter/0optionalapps/luci-app-nft-qos/po/fr/nft-qos.po +++ /dev/null @@ -1,239 +0,0 @@ -msgid "" -msgstr "" -"PO-Revision-Date: 2020-10-24 08:56+0000\n" -"Last-Translator: ButterflyOfFire \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.3.1\n" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:136 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:155 -msgid "Bytes Total" -msgstr "Total octets" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:141 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:160 -msgid "Collecting data..." -msgstr "Récupération des données…" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:224 -msgid "Comment" -msgstr "Commentaire" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default Download Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Default Network Interface" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default Upload Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default unit for download rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default unit for upload rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Default value for download bandwidth" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default value for download rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Default value for upload bandwidth" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default value for upload rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Download Bandwidth (Mbps)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:135 -msgid "Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Enable Limit Rate Feature" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable Traffic Priority" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable this feature" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:121 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:158 -msgid "Hostname" -msgstr "Nom d'hôte" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:134 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:153 -msgid "IP Address" -msgstr "Adresse IP" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:126 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:163 -msgid "IP Address(V4 / V6)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:128 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:165 -msgid "IP Address(V4 Only)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Limit Enable" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Limit Type" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:135 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:172 -msgid "MAC (optional)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:48 -msgid "MB" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:28 -msgid "NFT-QoS Settings" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Network Interface for Traffic Shaping, e.g. br-lan, eth0.1, eth0, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Network to be apply, e.g. 192.168.1.0/24, 10.2.0.0/16, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Network to be apply, e.g. AAAA::BBBB/64, CCCC::1/128, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:65 -msgid "No information available" -msgstr "Information indisponible" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:137 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:156 -msgid "Packets Total" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:207 -msgid "Priority" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:199 -msgid "Protocol" -msgstr "Protocole" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:16 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:23 -msgid "Qos over Nftables" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:12 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:139 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:176 -msgid "Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:130 -msgid "Realtime Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:125 -msgid "Realtime Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:149 -msgid "Realtime Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "Service" -msgstr "Service" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:116 -msgid "Static QoS-Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:153 -msgid "Static QoS-Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Target Network (IPv4/MASK)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Target Network6 (IPv6/MASK)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:127 -msgid "This page gives an overview over currently download/upload rate." -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:194 -msgid "Traffic Priority Settings" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Type of Limit Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:144 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:181 -msgid "Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Upload Bandwidth (Mbps)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:154 -msgid "Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:96 -msgid "White List for Limit Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "e.g. https, 23, (separator is comma)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:44 -msgid "kB" -msgstr "" diff --git a/rooter/0optionalapps/luci-app-nft-qos/po/he/nft-qos.po b/rooter/0optionalapps/luci-app-nft-qos/po/he/nft-qos.po deleted file mode 100644 index b182668..0000000 --- a/rooter/0optionalapps/luci-app-nft-qos/po/he/nft-qos.po +++ /dev/null @@ -1,240 +0,0 @@ -msgid "" -msgstr "" -"PO-Revision-Date: 2020-10-17 15:26+0000\n" -"Last-Translator: Yaron Shahrabani \n" -"Language-Team: Hebrew \n" -"Language: he\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=4; plural=(n == 1) ? 0 : ((n == 2) ? 1 : ((n > 10 && " -"n % 10 == 0) ? 2 : 3));\n" -"X-Generator: Weblate 4.3.1-dev\n" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:136 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:155 -msgid "Bytes Total" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:141 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:160 -msgid "Collecting data..." -msgstr "נאספים נתונים…" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:224 -msgid "Comment" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default Download Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Default Network Interface" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default Upload Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default unit for download rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default unit for upload rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Default value for download bandwidth" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default value for download rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Default value for upload bandwidth" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default value for upload rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Download Bandwidth (Mbps)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:135 -msgid "Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Enable Limit Rate Feature" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable Traffic Priority" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable this feature" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:121 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:158 -msgid "Hostname" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:134 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:153 -msgid "IP Address" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:126 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:163 -msgid "IP Address(V4 / V6)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:128 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:165 -msgid "IP Address(V4 Only)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Limit Enable" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Limit Type" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:135 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:172 -msgid "MAC (optional)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:48 -msgid "MB" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:28 -msgid "NFT-QoS Settings" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Network Interface for Traffic Shaping, e.g. br-lan, eth0.1, eth0, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Network to be apply, e.g. 192.168.1.0/24, 10.2.0.0/16, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Network to be apply, e.g. AAAA::BBBB/64, CCCC::1/128, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:65 -msgid "No information available" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:137 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:156 -msgid "Packets Total" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:207 -msgid "Priority" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:199 -msgid "Protocol" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:16 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:23 -msgid "Qos over Nftables" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:12 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:139 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:176 -msgid "Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:130 -msgid "Realtime Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:125 -msgid "Realtime Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:149 -msgid "Realtime Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "Service" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:116 -msgid "Static QoS-Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:153 -msgid "Static QoS-Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Target Network (IPv4/MASK)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Target Network6 (IPv6/MASK)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:127 -msgid "This page gives an overview over currently download/upload rate." -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:194 -msgid "Traffic Priority Settings" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Type of Limit Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:144 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:181 -msgid "Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Upload Bandwidth (Mbps)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:154 -msgid "Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:96 -msgid "White List for Limit Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "e.g. https, 23, (separator is comma)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:44 -msgid "kB" -msgstr "" diff --git a/rooter/0optionalapps/luci-app-nft-qos/po/hi/nft-qos.po b/rooter/0optionalapps/luci-app-nft-qos/po/hi/nft-qos.po deleted file mode 100644 index 29961a2..0000000 --- a/rooter/0optionalapps/luci-app-nft-qos/po/hi/nft-qos.po +++ /dev/null @@ -1,233 +0,0 @@ -msgid "" -msgstr "" -"Language: hi\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:136 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:155 -msgid "Bytes Total" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:141 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:160 -msgid "Collecting data..." -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:224 -msgid "Comment" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default Download Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Default Network Interface" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default Upload Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default unit for download rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default unit for upload rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Default value for download bandwidth" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default value for download rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Default value for upload bandwidth" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default value for upload rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Download Bandwidth (Mbps)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:135 -msgid "Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Enable Limit Rate Feature" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable Traffic Priority" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable this feature" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:121 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:158 -msgid "Hostname" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:134 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:153 -msgid "IP Address" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:126 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:163 -msgid "IP Address(V4 / V6)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:128 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:165 -msgid "IP Address(V4 Only)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Limit Enable" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Limit Type" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:135 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:172 -msgid "MAC (optional)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:48 -msgid "MB" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:28 -msgid "NFT-QoS Settings" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Network Interface for Traffic Shaping, e.g. br-lan, eth0.1, eth0, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Network to be apply, e.g. 192.168.1.0/24, 10.2.0.0/16, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Network to be apply, e.g. AAAA::BBBB/64, CCCC::1/128, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:65 -msgid "No information available" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:137 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:156 -msgid "Packets Total" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:207 -msgid "Priority" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:199 -msgid "Protocol" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:16 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:23 -msgid "Qos over Nftables" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:12 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:139 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:176 -msgid "Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:130 -msgid "Realtime Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:125 -msgid "Realtime Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:149 -msgid "Realtime Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "Service" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:116 -msgid "Static QoS-Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:153 -msgid "Static QoS-Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Target Network (IPv4/MASK)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Target Network6 (IPv6/MASK)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:127 -msgid "This page gives an overview over currently download/upload rate." -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:194 -msgid "Traffic Priority Settings" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Type of Limit Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:144 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:181 -msgid "Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Upload Bandwidth (Mbps)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:154 -msgid "Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:96 -msgid "White List for Limit Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "e.g. https, 23, (separator is comma)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:44 -msgid "kB" -msgstr "" diff --git a/rooter/0optionalapps/luci-app-nft-qos/po/hu/nft-qos.po b/rooter/0optionalapps/luci-app-nft-qos/po/hu/nft-qos.po deleted file mode 100644 index 1027fc6..0000000 --- a/rooter/0optionalapps/luci-app-nft-qos/po/hu/nft-qos.po +++ /dev/null @@ -1,240 +0,0 @@ -msgid "" -msgstr "" -"PO-Revision-Date: 2020-01-08 19:28+0000\n" -"Last-Translator: Balázs Úr \n" -"Language-Team: Hungarian \n" -"Language: hu\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 3.10.1-dev\n" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:136 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:155 -msgid "Bytes Total" -msgstr "Bájt összesen" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:141 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:160 -msgid "Collecting data..." -msgstr "Adatok összegyűjtése…" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:224 -msgid "Comment" -msgstr "Megjegyzés" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default Download Rate" -msgstr "Alapértelmezett letöltési arány" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default Download Unit" -msgstr "Alapértelmezett letöltési mértékegység" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Default Network Interface" -msgstr "Alapértelmezett hálózati csatoló" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default Upload Rate" -msgstr "Alapértelmezett feltöltési arány" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default Upload Unit" -msgstr "Alapértelmezett feltöltési mértékegység" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default unit for download rate" -msgstr "Alapértelmezett mértékegység a letöltési aránynál" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default unit for upload rate" -msgstr "Alapértelmezett mértékegység a feltöltési aránynál" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Default value for download bandwidth" -msgstr "Alapértelmezett érték a letöltési sávszélességnél" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default value for download rate" -msgstr "Alapértelmezett érték a letöltési aránynál" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Default value for upload bandwidth" -msgstr "Alapértelmezett érték a feltöltési sávszélességnél" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default value for upload rate" -msgstr "Alapértelmezett érték a feltöltési aránynál" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Download Bandwidth (Mbps)" -msgstr "Letöltési sávszélesség (Mbps)" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:135 -msgid "Download Rate" -msgstr "Letöltési arány" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Enable Limit Rate Feature" -msgstr "Arány korlátozása funkció engedélyezése" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable Traffic Priority" -msgstr "Forgalomprioritás engedélyezése" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable this feature" -msgstr "A funkció engedélyezése" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:121 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:158 -msgid "Hostname" -msgstr "Gépnév" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:134 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:153 -msgid "IP Address" -msgstr "IP-cím" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:126 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:163 -msgid "IP Address(V4 / V6)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:128 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:165 -msgid "IP Address(V4 Only)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Limit Enable" -msgstr "Korlátozás engedélyezése" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Limit Type" -msgstr "Korlát típusa" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:135 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:172 -msgid "MAC (optional)" -msgstr "MAC (elhagyható)" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:48 -msgid "MB" -msgstr "MB" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:28 -msgid "NFT-QoS Settings" -msgstr "NFT-QoS beállítások" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Network Interface for Traffic Shaping, e.g. br-lan, eth0.1, eth0, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Network to be apply, e.g. 192.168.1.0/24, 10.2.0.0/16, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Network to be apply, e.g. AAAA::BBBB/64, CCCC::1/128, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:65 -msgid "No information available" -msgstr "Nincs elérhető információ" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:137 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:156 -msgid "Packets Total" -msgstr "Csomagok összesen" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:207 -msgid "Priority" -msgstr "Prioritás" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:199 -msgid "Protocol" -msgstr "Protokoll" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:16 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:23 -msgid "Qos over Nftables" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:12 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:139 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:176 -msgid "Rate" -msgstr "Arány" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:130 -msgid "Realtime Download Rate" -msgstr "Valós idejű letöltési arány" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:125 -msgid "Realtime Rate" -msgstr "Valós idejű arány" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:149 -msgid "Realtime Upload Rate" -msgstr "Valós idejű feltöltési arány" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "Service" -msgstr "Szolgáltatás" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:116 -msgid "Static QoS-Download Rate" -msgstr "Statikus QoS-letöltési arány" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:153 -msgid "Static QoS-Upload Rate" -msgstr "Statikus QoS feltöltési arány" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Target Network (IPv4/MASK)" -msgstr "Célhálózat (IPv4/MASZK)" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Target Network6 (IPv6/MASK)" -msgstr "Célhálózat 6 (IPv6/MASZK)" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:127 -msgid "This page gives an overview over currently download/upload rate." -msgstr "" -"Ez az oldal áttekintést ad a jelenlegi letöltési és feltöltési arányról." - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:194 -msgid "Traffic Priority Settings" -msgstr "Forgalomprioritás beállításai" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Type of Limit Rate" -msgstr "Arány korlátozásának típusa" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:144 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:181 -msgid "Unit" -msgstr "Mértékegység" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Upload Bandwidth (Mbps)" -msgstr "Feltöltési sávszélesség (Mbps)" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:154 -msgid "Upload Rate" -msgstr "Feltöltési arány" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:96 -msgid "White List for Limit Rate" -msgstr "Fehérlista az arány korlátázásához" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "e.g. https, 23, (separator is comma)" -msgstr "például https, 23, (vesszővel elválasztva)" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:44 -msgid "kB" -msgstr "kB" diff --git a/rooter/0optionalapps/luci-app-nft-qos/po/it/nft-qos.po b/rooter/0optionalapps/luci-app-nft-qos/po/it/nft-qos.po deleted file mode 100644 index 0635c24..0000000 --- a/rooter/0optionalapps/luci-app-nft-qos/po/it/nft-qos.po +++ /dev/null @@ -1,239 +0,0 @@ -msgid "" -msgstr "" -"PO-Revision-Date: 2020-03-04 04:29+0000\n" -"Last-Translator: TuxAlex0 \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.0-dev\n" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:136 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:155 -msgid "Bytes Total" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:141 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:160 -msgid "Collecting data..." -msgstr "Raccolta dati..." - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:224 -msgid "Comment" -msgstr "Commento" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default Download Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Default Network Interface" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default Upload Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default unit for download rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default unit for upload rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Default value for download bandwidth" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default value for download rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Default value for upload bandwidth" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default value for upload rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Download Bandwidth (Mbps)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:135 -msgid "Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Enable Limit Rate Feature" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable Traffic Priority" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable this feature" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:121 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:158 -msgid "Hostname" -msgstr "Hostname" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:134 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:153 -msgid "IP Address" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:126 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:163 -msgid "IP Address(V4 / V6)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:128 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:165 -msgid "IP Address(V4 Only)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Limit Enable" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Limit Type" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:135 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:172 -msgid "MAC (optional)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:48 -msgid "MB" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:28 -msgid "NFT-QoS Settings" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Network Interface for Traffic Shaping, e.g. br-lan, eth0.1, eth0, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Network to be apply, e.g. 192.168.1.0/24, 10.2.0.0/16, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Network to be apply, e.g. AAAA::BBBB/64, CCCC::1/128, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:65 -msgid "No information available" -msgstr "Nessuna informazione disponibile" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:137 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:156 -msgid "Packets Total" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:207 -msgid "Priority" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:199 -msgid "Protocol" -msgstr "Protocollo" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:16 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:23 -msgid "Qos over Nftables" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:12 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:139 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:176 -msgid "Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:130 -msgid "Realtime Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:125 -msgid "Realtime Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:149 -msgid "Realtime Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "Service" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:116 -msgid "Static QoS-Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:153 -msgid "Static QoS-Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Target Network (IPv4/MASK)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Target Network6 (IPv6/MASK)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:127 -msgid "This page gives an overview over currently download/upload rate." -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:194 -msgid "Traffic Priority Settings" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Type of Limit Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:144 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:181 -msgid "Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Upload Bandwidth (Mbps)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:154 -msgid "Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:96 -msgid "White List for Limit Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "e.g. https, 23, (separator is comma)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:44 -msgid "kB" -msgstr "" diff --git a/rooter/0optionalapps/luci-app-nft-qos/po/ja/nft-qos.po b/rooter/0optionalapps/luci-app-nft-qos/po/ja/nft-qos.po deleted file mode 100644 index 186ecb0..0000000 --- a/rooter/0optionalapps/luci-app-nft-qos/po/ja/nft-qos.po +++ /dev/null @@ -1,239 +0,0 @@ -msgid "" -msgstr "" -"PO-Revision-Date: 2020-10-10 13:26+0000\n" -"Last-Translator: RyotaGamer <21ryotagamer@gmail.com>\n" -"Language-Team: Japanese \n" -"Language: ja\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.3-dev\n" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:136 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:155 -msgid "Bytes Total" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:141 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:160 -msgid "Collecting data..." -msgstr "データを収集中..." - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:224 -msgid "Comment" -msgstr "コメント" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default Download Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Default Network Interface" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default Upload Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default unit for download rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default unit for upload rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Default value for download bandwidth" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default value for download rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Default value for upload bandwidth" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default value for upload rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Download Bandwidth (Mbps)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:135 -msgid "Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Enable Limit Rate Feature" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable Traffic Priority" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable this feature" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:121 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:158 -msgid "Hostname" -msgstr "ホスト名" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:134 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:153 -msgid "IP Address" -msgstr "IP アドレス" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:126 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:163 -msgid "IP Address(V4 / V6)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:128 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:165 -msgid "IP Address(V4 Only)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Limit Enable" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Limit Type" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:135 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:172 -msgid "MAC (optional)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:48 -msgid "MB" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:28 -msgid "NFT-QoS Settings" -msgstr "NFT-QoS 設定" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Network Interface for Traffic Shaping, e.g. br-lan, eth0.1, eth0, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Network to be apply, e.g. 192.168.1.0/24, 10.2.0.0/16, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Network to be apply, e.g. AAAA::BBBB/64, CCCC::1/128, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:65 -msgid "No information available" -msgstr "情報なし" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:137 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:156 -msgid "Packets Total" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:207 -msgid "Priority" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:199 -msgid "Protocol" -msgstr "プロトコル" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:16 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:23 -msgid "Qos over Nftables" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:12 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:139 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:176 -msgid "Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:130 -msgid "Realtime Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:125 -msgid "Realtime Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:149 -msgid "Realtime Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "Service" -msgstr "サービス" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:116 -msgid "Static QoS-Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:153 -msgid "Static QoS-Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Target Network (IPv4/MASK)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Target Network6 (IPv6/MASK)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:127 -msgid "This page gives an overview over currently download/upload rate." -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:194 -msgid "Traffic Priority Settings" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Type of Limit Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:144 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:181 -msgid "Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Upload Bandwidth (Mbps)" -msgstr "アップロード帯域幅 (Mbps)" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:154 -msgid "Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:96 -msgid "White List for Limit Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "e.g. https, 23, (separator is comma)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:44 -msgid "kB" -msgstr "" diff --git a/rooter/0optionalapps/luci-app-nft-qos/po/ko/nft-qos.po b/rooter/0optionalapps/luci-app-nft-qos/po/ko/nft-qos.po deleted file mode 100644 index 5a3f704..0000000 --- a/rooter/0optionalapps/luci-app-nft-qos/po/ko/nft-qos.po +++ /dev/null @@ -1,239 +0,0 @@ -msgid "" -msgstr "" -"PO-Revision-Date: 2020-07-28 17:55+0000\n" -"Last-Translator: TheNoFace \n" -"Language-Team: Korean \n" -"Language: ko\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.2-dev\n" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:136 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:155 -msgid "Bytes Total" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:141 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:160 -msgid "Collecting data..." -msgstr "데이터 수집 중..." - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:224 -msgid "Comment" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default Download Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Default Network Interface" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default Upload Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default unit for download rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default unit for upload rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Default value for download bandwidth" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default value for download rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Default value for upload bandwidth" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default value for upload rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Download Bandwidth (Mbps)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:135 -msgid "Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Enable Limit Rate Feature" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable Traffic Priority" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable this feature" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:121 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:158 -msgid "Hostname" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:134 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:153 -msgid "IP Address" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:126 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:163 -msgid "IP Address(V4 / V6)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:128 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:165 -msgid "IP Address(V4 Only)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Limit Enable" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Limit Type" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:135 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:172 -msgid "MAC (optional)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:48 -msgid "MB" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:28 -msgid "NFT-QoS Settings" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Network Interface for Traffic Shaping, e.g. br-lan, eth0.1, eth0, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Network to be apply, e.g. 192.168.1.0/24, 10.2.0.0/16, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Network to be apply, e.g. AAAA::BBBB/64, CCCC::1/128, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:65 -msgid "No information available" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:137 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:156 -msgid "Packets Total" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:207 -msgid "Priority" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:199 -msgid "Protocol" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:16 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:23 -msgid "Qos over Nftables" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:12 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:139 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:176 -msgid "Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:130 -msgid "Realtime Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:125 -msgid "Realtime Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:149 -msgid "Realtime Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "Service" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:116 -msgid "Static QoS-Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:153 -msgid "Static QoS-Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Target Network (IPv4/MASK)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Target Network6 (IPv6/MASK)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:127 -msgid "This page gives an overview over currently download/upload rate." -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:194 -msgid "Traffic Priority Settings" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Type of Limit Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:144 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:181 -msgid "Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Upload Bandwidth (Mbps)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:154 -msgid "Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:96 -msgid "White List for Limit Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "e.g. https, 23, (separator is comma)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:44 -msgid "kB" -msgstr "" diff --git a/rooter/0optionalapps/luci-app-nft-qos/po/mr/nft-qos.po b/rooter/0optionalapps/luci-app-nft-qos/po/mr/nft-qos.po deleted file mode 100644 index 86c0604..0000000 --- a/rooter/0optionalapps/luci-app-nft-qos/po/mr/nft-qos.po +++ /dev/null @@ -1,239 +0,0 @@ -msgid "" -msgstr "" -"PO-Revision-Date: 2020-02-07 09:18+0000\n" -"Last-Translator: Prachi Joshi \n" -"Language-Team: Marathi \n" -"Language: mr\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 3.11-dev\n" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:136 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:155 -msgid "Bytes Total" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:141 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:160 -msgid "Collecting data..." -msgstr "डेटा संकलित करीत आहे ..." - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:224 -msgid "Comment" -msgstr "टिप्पणी" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default Download Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Default Network Interface" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default Upload Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default unit for download rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default unit for upload rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Default value for download bandwidth" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default value for download rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Default value for upload bandwidth" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default value for upload rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Download Bandwidth (Mbps)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:135 -msgid "Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Enable Limit Rate Feature" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable Traffic Priority" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable this feature" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:121 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:158 -msgid "Hostname" -msgstr "होस्टनाव" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:134 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:153 -msgid "IP Address" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:126 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:163 -msgid "IP Address(V4 / V6)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:128 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:165 -msgid "IP Address(V4 Only)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Limit Enable" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Limit Type" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:135 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:172 -msgid "MAC (optional)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:48 -msgid "MB" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:28 -msgid "NFT-QoS Settings" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Network Interface for Traffic Shaping, e.g. br-lan, eth0.1, eth0, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Network to be apply, e.g. 192.168.1.0/24, 10.2.0.0/16, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Network to be apply, e.g. AAAA::BBBB/64, CCCC::1/128, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:65 -msgid "No information available" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:137 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:156 -msgid "Packets Total" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:207 -msgid "Priority" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:199 -msgid "Protocol" -msgstr "प्रोटोकॉल" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:16 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:23 -msgid "Qos over Nftables" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:12 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:139 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:176 -msgid "Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:130 -msgid "Realtime Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:125 -msgid "Realtime Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:149 -msgid "Realtime Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "Service" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:116 -msgid "Static QoS-Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:153 -msgid "Static QoS-Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Target Network (IPv4/MASK)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Target Network6 (IPv6/MASK)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:127 -msgid "This page gives an overview over currently download/upload rate." -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:194 -msgid "Traffic Priority Settings" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Type of Limit Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:144 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:181 -msgid "Unit" -msgstr "युनिट" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Upload Bandwidth (Mbps)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:154 -msgid "Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:96 -msgid "White List for Limit Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "e.g. https, 23, (separator is comma)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:44 -msgid "kB" -msgstr "" diff --git a/rooter/0optionalapps/luci-app-nft-qos/po/ms/nft-qos.po b/rooter/0optionalapps/luci-app-nft-qos/po/ms/nft-qos.po deleted file mode 100644 index 08bfab1..0000000 --- a/rooter/0optionalapps/luci-app-nft-qos/po/ms/nft-qos.po +++ /dev/null @@ -1,239 +0,0 @@ -msgid "" -msgstr "" -"PO-Revision-Date: 2019-12-16 23:25+0000\n" -"Last-Translator: Pusak Hitam \n" -"Language-Team: Malay \n" -"Language: ms\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 3.10-dev\n" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:136 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:155 -msgid "Bytes Total" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:141 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:160 -msgid "Collecting data..." -msgstr "Mengumpul data..." - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:224 -msgid "Comment" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default Download Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Default Network Interface" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default Upload Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default unit for download rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default unit for upload rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Default value for download bandwidth" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default value for download rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Default value for upload bandwidth" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default value for upload rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Download Bandwidth (Mbps)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:135 -msgid "Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Enable Limit Rate Feature" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable Traffic Priority" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable this feature" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:121 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:158 -msgid "Hostname" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:134 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:153 -msgid "IP Address" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:126 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:163 -msgid "IP Address(V4 / V6)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:128 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:165 -msgid "IP Address(V4 Only)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Limit Enable" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Limit Type" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:135 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:172 -msgid "MAC (optional)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:48 -msgid "MB" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:28 -msgid "NFT-QoS Settings" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Network Interface for Traffic Shaping, e.g. br-lan, eth0.1, eth0, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Network to be apply, e.g. 192.168.1.0/24, 10.2.0.0/16, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Network to be apply, e.g. AAAA::BBBB/64, CCCC::1/128, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:65 -msgid "No information available" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:137 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:156 -msgid "Packets Total" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:207 -msgid "Priority" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:199 -msgid "Protocol" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:16 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:23 -msgid "Qos over Nftables" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:12 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:139 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:176 -msgid "Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:130 -msgid "Realtime Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:125 -msgid "Realtime Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:149 -msgid "Realtime Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "Service" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:116 -msgid "Static QoS-Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:153 -msgid "Static QoS-Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Target Network (IPv4/MASK)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Target Network6 (IPv6/MASK)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:127 -msgid "This page gives an overview over currently download/upload rate." -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:194 -msgid "Traffic Priority Settings" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Type of Limit Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:144 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:181 -msgid "Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Upload Bandwidth (Mbps)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:154 -msgid "Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:96 -msgid "White List for Limit Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "e.g. https, 23, (separator is comma)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:44 -msgid "kB" -msgstr "" diff --git a/rooter/0optionalapps/luci-app-nft-qos/po/nb_NO/nft-qos.po b/rooter/0optionalapps/luci-app-nft-qos/po/nb_NO/nft-qos.po deleted file mode 100644 index 5ecf971..0000000 --- a/rooter/0optionalapps/luci-app-nft-qos/po/nb_NO/nft-qos.po +++ /dev/null @@ -1,239 +0,0 @@ -msgid "" -msgstr "" -"PO-Revision-Date: 2019-10-30 03:21+0000\n" -"Last-Translator: Allan Nordhøy \n" -"Language-Team: Norwegian Bokmål \n" -"Language: nb_NO\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 3.9.1\n" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:136 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:155 -msgid "Bytes Total" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:141 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:160 -msgid "Collecting data..." -msgstr "Samler inn data…" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:224 -msgid "Comment" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default Download Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Default Network Interface" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default Upload Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default unit for download rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default unit for upload rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Default value for download bandwidth" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default value for download rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Default value for upload bandwidth" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default value for upload rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Download Bandwidth (Mbps)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:135 -msgid "Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Enable Limit Rate Feature" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable Traffic Priority" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable this feature" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:121 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:158 -msgid "Hostname" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:134 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:153 -msgid "IP Address" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:126 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:163 -msgid "IP Address(V4 / V6)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:128 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:165 -msgid "IP Address(V4 Only)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Limit Enable" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Limit Type" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:135 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:172 -msgid "MAC (optional)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:48 -msgid "MB" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:28 -msgid "NFT-QoS Settings" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Network Interface for Traffic Shaping, e.g. br-lan, eth0.1, eth0, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Network to be apply, e.g. 192.168.1.0/24, 10.2.0.0/16, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Network to be apply, e.g. AAAA::BBBB/64, CCCC::1/128, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:65 -msgid "No information available" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:137 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:156 -msgid "Packets Total" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:207 -msgid "Priority" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:199 -msgid "Protocol" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:16 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:23 -msgid "Qos over Nftables" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:12 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:139 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:176 -msgid "Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:130 -msgid "Realtime Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:125 -msgid "Realtime Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:149 -msgid "Realtime Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "Service" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:116 -msgid "Static QoS-Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:153 -msgid "Static QoS-Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Target Network (IPv4/MASK)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Target Network6 (IPv6/MASK)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:127 -msgid "This page gives an overview over currently download/upload rate." -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:194 -msgid "Traffic Priority Settings" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Type of Limit Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:144 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:181 -msgid "Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Upload Bandwidth (Mbps)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:154 -msgid "Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:96 -msgid "White List for Limit Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "e.g. https, 23, (separator is comma)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:44 -msgid "kB" -msgstr "" diff --git a/rooter/0optionalapps/luci-app-nft-qos/po/pl/nft-qos.po b/rooter/0optionalapps/luci-app-nft-qos/po/pl/nft-qos.po deleted file mode 100644 index 7342882..0000000 --- a/rooter/0optionalapps/luci-app-nft-qos/po/pl/nft-qos.po +++ /dev/null @@ -1,240 +0,0 @@ -msgid "" -msgstr "" -"PO-Revision-Date: 2020-09-19 18:03+0000\n" -"Last-Translator: Marcin Net \n" -"Language-Team: Polish \n" -"Language: pl\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.3-dev\n" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:136 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:155 -msgid "Bytes Total" -msgstr "Bajty ogółem" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:141 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:160 -msgid "Collecting data..." -msgstr "Trwa zbieranie danych..." - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:224 -msgid "Comment" -msgstr "Komentarz" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default Download Rate" -msgstr "Domyślna szybkość pobierania" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default Download Unit" -msgstr "Domyślna jednostka pobierania" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Default Network Interface" -msgstr "Domyślny interfejs sieciowy" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default Upload Rate" -msgstr "Domyślna szybkość przesyłania" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default Upload Unit" -msgstr "Domyślna jednostka przesyłania" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default unit for download rate" -msgstr "Domyślna jednostka dla szybkości pobierania" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default unit for upload rate" -msgstr "Domyślna jednostka szybkości wysyłania" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Default value for download bandwidth" -msgstr "Wartość domyślna dla przepustowości pobierania" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default value for download rate" -msgstr "Wartość domyślna dla szybkości pobierania" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Default value for upload bandwidth" -msgstr "Wartość domyślna dla przepustowości wysyłania" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default value for upload rate" -msgstr "Wartość domyślna szybkości wysyłania" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Download Bandwidth (Mbps)" -msgstr "Przepustowość pobierania (Mbps)" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:135 -msgid "Download Rate" -msgstr "Szybkość pobierania" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Enable Limit Rate Feature" -msgstr "Włącz funkcję limitu prędkości" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable Traffic Priority" -msgstr "Włącz priorytet ruchu" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable this feature" -msgstr "Włącz tę funkcję" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:121 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:158 -msgid "Hostname" -msgstr "Nazwa hosta" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:134 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:153 -msgid "IP Address" -msgstr "Adres IP" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:126 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:163 -msgid "IP Address(V4 / V6)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:128 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:165 -msgid "IP Address(V4 Only)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Limit Enable" -msgstr "Włącz limit" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Limit Type" -msgstr "Typ limitu" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:135 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:172 -msgid "MAC (optional)" -msgstr "MAC (opcjonalnie)" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:48 -msgid "MB" -msgstr "MB" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:28 -msgid "NFT-QoS Settings" -msgstr "Ustawienia NFT-QoS" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Network Interface for Traffic Shaping, e.g. br-lan, eth0.1, eth0, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Network to be apply, e.g. 192.168.1.0/24, 10.2.0.0/16, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Network to be apply, e.g. AAAA::BBBB/64, CCCC::1/128, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:65 -msgid "No information available" -msgstr "Brak dostępnych informacji" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:137 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:156 -msgid "Packets Total" -msgstr "Suma pakietów" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:207 -msgid "Priority" -msgstr "Priorytet" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:199 -msgid "Protocol" -msgstr "Protokół" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:16 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:23 -msgid "Qos over Nftables" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:12 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:139 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:176 -msgid "Rate" -msgstr "Tempo" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:130 -msgid "Realtime Download Rate" -msgstr "Szybkość pobierania w czasie rzeczywistym" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:125 -msgid "Realtime Rate" -msgstr "Szybkość w czasie rzeczywistym" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:149 -msgid "Realtime Upload Rate" -msgstr "Szybkość wysyłania w czasie rzeczywistym" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "Service" -msgstr "Usługa" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:116 -msgid "Static QoS-Download Rate" -msgstr "Statyczna prędkość pobierania QoS" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:153 -msgid "Static QoS-Upload Rate" -msgstr "Statyczna prędkość wysyłania QoS" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Target Network (IPv4/MASK)" -msgstr "Sieć docelowa (IPv4/Maska)" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Target Network6 (IPv6/MASK)" -msgstr "Sieć docelowa (IPv6/Maska)" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:127 -msgid "This page gives an overview over currently download/upload rate." -msgstr "Ta strona zawiera przegląd aktualnej prędkości pobierania/wysyłania." - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:194 -msgid "Traffic Priority Settings" -msgstr "Ustawienia priorytetu ruchu sieciowego" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Type of Limit Rate" -msgstr "Typ limitu prędkości" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:144 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:181 -msgid "Unit" -msgstr "Jednostka" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Upload Bandwidth (Mbps)" -msgstr "Przepustowość przesyłania (Mbps)" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:154 -msgid "Upload Rate" -msgstr "Szybkość wysyłania" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:96 -msgid "White List for Limit Rate" -msgstr "Biała lista dla limitu prędkości" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "e.g. https, 23, (separator is comma)" -msgstr "np. https, 23, (separator to przecinek)" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:44 -msgid "kB" -msgstr "kB" diff --git a/rooter/0optionalapps/luci-app-nft-qos/po/pt/nft-qos.po b/rooter/0optionalapps/luci-app-nft-qos/po/pt/nft-qos.po deleted file mode 100644 index 8c6b36e..0000000 --- a/rooter/0optionalapps/luci-app-nft-qos/po/pt/nft-qos.po +++ /dev/null @@ -1,240 +0,0 @@ -msgid "" -msgstr "" -"PO-Revision-Date: 2020-09-18 18:36+0000\n" -"Last-Translator: ssantos \n" -"Language-Team: Portuguese \n" -"Language: pt\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.3-dev\n" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:136 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:155 -msgid "Bytes Total" -msgstr "Total de Bytes" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:141 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:160 -msgid "Collecting data..." -msgstr "A recolher dados..." - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:224 -msgid "Comment" -msgstr "Comentário" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default Download Rate" -msgstr "Taxa de Descarregamento Padrão" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default Download Unit" -msgstr "Unidade de Descarregamento Padrão" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Default Network Interface" -msgstr "Interface de Rede Padrão" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default Upload Rate" -msgstr "Taxa de Envio Padrão" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default Upload Unit" -msgstr "Unidade de Envio Padrão" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default unit for download rate" -msgstr "Unidade padrão para taxa de descarregamento" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default unit for upload rate" -msgstr "Unidade padrão para taxa de envio" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Default value for download bandwidth" -msgstr "Valor padrão para largura de banda de descarregamento" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default value for download rate" -msgstr "Valor padrão para taxa de descarregamento" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Default value for upload bandwidth" -msgstr "Valor padrão para a largura de banda de envio" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default value for upload rate" -msgstr "Valor padrão para a taxa de envio" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Download Bandwidth (Mbps)" -msgstr "Largura de Banda de Descarregamento (Mbps)" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:135 -msgid "Download Rate" -msgstr "Taxa de Descarregamento" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Enable Limit Rate Feature" -msgstr "Ativar Recurso de Limite de Taxa" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable Traffic Priority" -msgstr "Ativar Prioridade de Tráfego" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable this feature" -msgstr "Ativar este recurso" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:121 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:158 -msgid "Hostname" -msgstr "Nome do Host" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:134 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:153 -msgid "IP Address" -msgstr "Endereço IP" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:126 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:163 -msgid "IP Address(V4 / V6)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:128 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:165 -msgid "IP Address(V4 Only)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Limit Enable" -msgstr "Limitar Ativação" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Limit Type" -msgstr "Tipo de Limite" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:135 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:172 -msgid "MAC (optional)" -msgstr "MAC (opcional)" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:48 -msgid "MB" -msgstr "MB" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:28 -msgid "NFT-QoS Settings" -msgstr "Configurações NFT-QoS" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Network Interface for Traffic Shaping, e.g. br-lan, eth0.1, eth0, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Network to be apply, e.g. 192.168.1.0/24, 10.2.0.0/16, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Network to be apply, e.g. AAAA::BBBB/64, CCCC::1/128, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:65 -msgid "No information available" -msgstr "Sem informação disponível" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:137 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:156 -msgid "Packets Total" -msgstr "Total de Pacotes" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:207 -msgid "Priority" -msgstr "Prioridade" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:199 -msgid "Protocol" -msgstr "Protocolo" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:16 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:23 -msgid "Qos over Nftables" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:12 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:139 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:176 -msgid "Rate" -msgstr "Taxa" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:130 -msgid "Realtime Download Rate" -msgstr "Taxa de Descarregamento em Tempo Real" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:125 -msgid "Realtime Rate" -msgstr "Taxa em Tempo Real" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:149 -msgid "Realtime Upload Rate" -msgstr "Taxa de Envio em Tempo Real" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "Service" -msgstr "Serviço" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:116 -msgid "Static QoS-Download Rate" -msgstr "Taxa Estática de Descarregamanto de QoS" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:153 -msgid "Static QoS-Upload Rate" -msgstr "Taxa Estática de Envio QoS" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Target Network (IPv4/MASK)" -msgstr "Rede de Destino (IPv4/MASK)" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Target Network6 (IPv6/MASK)" -msgstr "Rede6 de Destino (IPv6/MASK)" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:127 -msgid "This page gives an overview over currently download/upload rate." -msgstr "" -"Esta página dá uma visão geral sobre a taxa de descarregamento/envio atual." - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:194 -msgid "Traffic Priority Settings" -msgstr "Configurações de Prioridade de Tráfego" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Type of Limit Rate" -msgstr "Tipo de Taxa Limite" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:144 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:181 -msgid "Unit" -msgstr "Unidade" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Upload Bandwidth (Mbps)" -msgstr "Largura de Banda de Envio (Mbps)" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:154 -msgid "Upload Rate" -msgstr "Taxa de Envio" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:96 -msgid "White List for Limit Rate" -msgstr "Lista Branca para a Taxa Limite" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "e.g. https, 23, (separator is comma)" -msgstr "por exemplo https, 23, (o separador é vírgula)" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:44 -msgid "kB" -msgstr "kB" diff --git a/rooter/0optionalapps/luci-app-nft-qos/po/pt_BR/nft-qos.po b/rooter/0optionalapps/luci-app-nft-qos/po/pt_BR/nft-qos.po deleted file mode 100644 index 40f436d..0000000 --- a/rooter/0optionalapps/luci-app-nft-qos/po/pt_BR/nft-qos.po +++ /dev/null @@ -1,239 +0,0 @@ -msgid "" -msgstr "" -"PO-Revision-Date: 2020-09-17 16:34+0000\n" -"Last-Translator: Wellington Terumi Uemura \n" -"Language-Team: Portuguese (Brazil) \n" -"Language: pt_BR\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.3-dev\n" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:136 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:155 -msgid "Bytes Total" -msgstr "Total de Bytes" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:141 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:160 -msgid "Collecting data..." -msgstr "Coletando dados..." - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:224 -msgid "Comment" -msgstr "Comentário" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default Download Rate" -msgstr "Taxa de Download Padrão" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default Download Unit" -msgstr "Unidade de Download Padrão" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Default Network Interface" -msgstr "Interface de Rede Padrão" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default Upload Rate" -msgstr "Taxa de Upload Padrão" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default Upload Unit" -msgstr "Unidade de Upload Padrão" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default unit for download rate" -msgstr "Unidade padrão para taxa de download" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default unit for upload rate" -msgstr "Unidade padrão para taxa de upload" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Default value for download bandwidth" -msgstr "Valor padrão para a largura de banda para download" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default value for download rate" -msgstr "Valor padrão para a taxa de download" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Default value for upload bandwidth" -msgstr "Valor padrão para a largura de banda de upload" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default value for upload rate" -msgstr "Valor padrão para a taxa de upload" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Download Bandwidth (Mbps)" -msgstr "Largura de Banda de Download (Mbps)" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:135 -msgid "Download Rate" -msgstr "Taxa de Download" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Enable Limit Rate Feature" -msgstr "Ativar o Recurso de Limitação de Taxa" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable Traffic Priority" -msgstr "Ativar a Prioridade de Tráfego" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable this feature" -msgstr "Ativar este recurso" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:121 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:158 -msgid "Hostname" -msgstr "Nome do equipamento" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:134 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:153 -msgid "IP Address" -msgstr "Endereço IP" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:126 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:163 -msgid "IP Address(V4 / V6)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:128 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:165 -msgid "IP Address(V4 Only)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Limit Enable" -msgstr "Ativar Limite" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Limit Type" -msgstr "Tipo de Limite" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:135 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:172 -msgid "MAC (optional)" -msgstr "MAC (opcional)" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:48 -msgid "MB" -msgstr "MB" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:28 -msgid "NFT-QoS Settings" -msgstr "Configurações NFT-QoS" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Network Interface for Traffic Shaping, e.g. br-lan, eth0.1, eth0, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Network to be apply, e.g. 192.168.1.0/24, 10.2.0.0/16, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Network to be apply, e.g. AAAA::BBBB/64, CCCC::1/128, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:65 -msgid "No information available" -msgstr "Nenhuma informação disponível" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:137 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:156 -msgid "Packets Total" -msgstr "Total de Pacotes" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:207 -msgid "Priority" -msgstr "Prioridade" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:199 -msgid "Protocol" -msgstr "Protocolo" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:16 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:23 -msgid "Qos over Nftables" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:12 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:139 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:176 -msgid "Rate" -msgstr "Taxa" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:130 -msgid "Realtime Download Rate" -msgstr "Taxa de Download em Tempo Real" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:125 -msgid "Realtime Rate" -msgstr "Taxa em Tempo Real" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:149 -msgid "Realtime Upload Rate" -msgstr "Taxa de Upload em Tempo Real" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "Service" -msgstr "Serviço" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:116 -msgid "Static QoS-Download Rate" -msgstr "QoS estático - Taxa de download" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:153 -msgid "Static QoS-Upload Rate" -msgstr "QoS-Estático - Taxa de Upload" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Target Network (IPv4/MASK)" -msgstr "Rede de Destino (IPv4/MASK)" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Target Network6 (IPv6/MASK)" -msgstr "Rede de Destino (IPV6/MASK)" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:127 -msgid "This page gives an overview over currently download/upload rate." -msgstr "Esta página dá uma visão geral sobre a taxa atual de download/upload." - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:194 -msgid "Traffic Priority Settings" -msgstr "Configuração da Prioridade do Tráfego" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Type of Limit Rate" -msgstr "Tipo de Taxa Limite" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:144 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:181 -msgid "Unit" -msgstr "Unidade" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Upload Bandwidth (Mbps)" -msgstr "Largura de Banda de Upload (Mbps)" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:154 -msgid "Upload Rate" -msgstr "Taxa de Upload" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:96 -msgid "White List for Limit Rate" -msgstr "Lista Branca para a Limitação da Taxa" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "e.g. https, 23, (separator is comma)" -msgstr "por exemplo, https, 23, (separado por vírgulas)" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:44 -msgid "kB" -msgstr "kB" diff --git a/rooter/0optionalapps/luci-app-nft-qos/po/ro/nft-qos.po b/rooter/0optionalapps/luci-app-nft-qos/po/ro/nft-qos.po deleted file mode 100644 index bc97a06..0000000 --- a/rooter/0optionalapps/luci-app-nft-qos/po/ro/nft-qos.po +++ /dev/null @@ -1,240 +0,0 @@ -msgid "" -msgstr "" -"PO-Revision-Date: 2020-03-29 21:22+0000\n" -"Last-Translator: Cristian Ionescu \n" -"Language-Team: Romanian \n" -"Language: ro\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.0-dev\n" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:136 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:155 -msgid "Bytes Total" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:141 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:160 -msgid "Collecting data..." -msgstr "Colectare date..." - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:224 -msgid "Comment" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default Download Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Default Network Interface" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default Upload Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default unit for download rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default unit for upload rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Default value for download bandwidth" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default value for download rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Default value for upload bandwidth" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default value for upload rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Download Bandwidth (Mbps)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:135 -msgid "Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Enable Limit Rate Feature" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable Traffic Priority" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable this feature" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:121 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:158 -msgid "Hostname" -msgstr "Numele gazdei ( hostname )" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:134 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:153 -msgid "IP Address" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:126 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:163 -msgid "IP Address(V4 / V6)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:128 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:165 -msgid "IP Address(V4 Only)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Limit Enable" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Limit Type" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:135 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:172 -msgid "MAC (optional)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:48 -msgid "MB" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:28 -msgid "NFT-QoS Settings" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Network Interface for Traffic Shaping, e.g. br-lan, eth0.1, eth0, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Network to be apply, e.g. 192.168.1.0/24, 10.2.0.0/16, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Network to be apply, e.g. AAAA::BBBB/64, CCCC::1/128, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:65 -msgid "No information available" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:137 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:156 -msgid "Packets Total" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:207 -msgid "Priority" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:199 -msgid "Protocol" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:16 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:23 -msgid "Qos over Nftables" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:12 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:139 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:176 -msgid "Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:130 -msgid "Realtime Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:125 -msgid "Realtime Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:149 -msgid "Realtime Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "Service" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:116 -msgid "Static QoS-Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:153 -msgid "Static QoS-Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Target Network (IPv4/MASK)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Target Network6 (IPv6/MASK)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:127 -msgid "This page gives an overview over currently download/upload rate." -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:194 -msgid "Traffic Priority Settings" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Type of Limit Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:144 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:181 -msgid "Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Upload Bandwidth (Mbps)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:154 -msgid "Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:96 -msgid "White List for Limit Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "e.g. https, 23, (separator is comma)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:44 -msgid "kB" -msgstr "" diff --git a/rooter/0optionalapps/luci-app-nft-qos/po/ru/nft-qos.po b/rooter/0optionalapps/luci-app-nft-qos/po/ru/nft-qos.po deleted file mode 100644 index 638701b..0000000 --- a/rooter/0optionalapps/luci-app-nft-qos/po/ru/nft-qos.po +++ /dev/null @@ -1,240 +0,0 @@ -msgid "" -msgstr "" -"PO-Revision-Date: 2020-10-09 00:10+0000\n" -"Last-Translator: Artem \n" -"Language-Team: Russian \n" -"Language: ru\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.3-dev\n" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:136 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:155 -msgid "Bytes Total" -msgstr "Всего байт" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:141 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:160 -msgid "Collecting data..." -msgstr "Сбор данных..." - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:224 -msgid "Comment" -msgstr "Комментарий" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default Download Rate" -msgstr "Скорость загрузки по умолчанию" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default Download Unit" -msgstr "Единица загрузки по умолчанию" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Default Network Interface" -msgstr "Сетевой интерфейс по умолчанию" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default Upload Rate" -msgstr "Скорость отправки по умолчанию" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default Upload Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default unit for download rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default unit for upload rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Default value for download bandwidth" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default value for download rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Default value for upload bandwidth" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default value for upload rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Download Bandwidth (Mbps)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:135 -msgid "Download Rate" -msgstr "Скорость загрузки" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Enable Limit Rate Feature" -msgstr "Включить функцию ограничения скорости" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable Traffic Priority" -msgstr "Включить приоритет трафика" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable this feature" -msgstr "Включить эту функцию" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:121 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:158 -msgid "Hostname" -msgstr "Имя хоста" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:134 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:153 -msgid "IP Address" -msgstr "IP адрес" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:126 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:163 -msgid "IP Address(V4 / V6)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:128 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:165 -msgid "IP Address(V4 Only)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Limit Enable" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Limit Type" -msgstr "Тип лимита" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:135 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:172 -msgid "MAC (optional)" -msgstr "MAC (необязательно)" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:48 -msgid "MB" -msgstr "МБ" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:28 -msgid "NFT-QoS Settings" -msgstr "Настройки NFT-QoS" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Network Interface for Traffic Shaping, e.g. br-lan, eth0.1, eth0, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Network to be apply, e.g. 192.168.1.0/24, 10.2.0.0/16, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Network to be apply, e.g. AAAA::BBBB/64, CCCC::1/128, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:65 -msgid "No information available" -msgstr "Нет доступной информации" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:137 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:156 -msgid "Packets Total" -msgstr "Всего пакетов" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:207 -msgid "Priority" -msgstr "Приоритет" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:199 -msgid "Protocol" -msgstr "Протокол" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:16 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:23 -msgid "Qos over Nftables" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:12 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:139 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:176 -msgid "Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:130 -msgid "Realtime Download Rate" -msgstr "Скорость загрузки в реальном времени" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:125 -msgid "Realtime Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:149 -msgid "Realtime Upload Rate" -msgstr "Скорость отправки в реальном времени" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "Service" -msgstr "Служба" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:116 -msgid "Static QoS-Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:153 -msgid "Static QoS-Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Target Network (IPv4/MASK)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Target Network6 (IPv6/MASK)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:127 -msgid "This page gives an overview over currently download/upload rate." -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:194 -msgid "Traffic Priority Settings" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Type of Limit Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:144 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:181 -msgid "Unit" -msgstr "узел" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Upload Bandwidth (Mbps)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:154 -msgid "Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:96 -msgid "White List for Limit Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "e.g. https, 23, (separator is comma)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:44 -msgid "kB" -msgstr "" diff --git a/rooter/0optionalapps/luci-app-nft-qos/po/sk/nft-qos.po b/rooter/0optionalapps/luci-app-nft-qos/po/sk/nft-qos.po deleted file mode 100644 index 7c4afad..0000000 --- a/rooter/0optionalapps/luci-app-nft-qos/po/sk/nft-qos.po +++ /dev/null @@ -1,239 +0,0 @@ -msgid "" -msgstr "" -"PO-Revision-Date: 2020-04-04 17:35+0000\n" -"Last-Translator: Dušan Kazik \n" -"Language-Team: Slovak \n" -"Language: sk\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.0-dev\n" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:136 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:155 -msgid "Bytes Total" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:141 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:160 -msgid "Collecting data..." -msgstr "Zbieram dáta..." - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:224 -msgid "Comment" -msgstr "Komentár" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default Download Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Default Network Interface" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default Upload Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default unit for download rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default unit for upload rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Default value for download bandwidth" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default value for download rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Default value for upload bandwidth" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default value for upload rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Download Bandwidth (Mbps)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:135 -msgid "Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Enable Limit Rate Feature" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable Traffic Priority" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable this feature" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:121 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:158 -msgid "Hostname" -msgstr "Názov hostiteľa" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:134 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:153 -msgid "IP Address" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:126 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:163 -msgid "IP Address(V4 / V6)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:128 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:165 -msgid "IP Address(V4 Only)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Limit Enable" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Limit Type" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:135 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:172 -msgid "MAC (optional)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:48 -msgid "MB" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:28 -msgid "NFT-QoS Settings" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Network Interface for Traffic Shaping, e.g. br-lan, eth0.1, eth0, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Network to be apply, e.g. 192.168.1.0/24, 10.2.0.0/16, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Network to be apply, e.g. AAAA::BBBB/64, CCCC::1/128, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:65 -msgid "No information available" -msgstr "Nie sú dostupné žiadne informácie" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:137 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:156 -msgid "Packets Total" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:207 -msgid "Priority" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:199 -msgid "Protocol" -msgstr "Protokol" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:16 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:23 -msgid "Qos over Nftables" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:12 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:139 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:176 -msgid "Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:130 -msgid "Realtime Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:125 -msgid "Realtime Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:149 -msgid "Realtime Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "Service" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:116 -msgid "Static QoS-Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:153 -msgid "Static QoS-Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Target Network (IPv4/MASK)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Target Network6 (IPv6/MASK)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:127 -msgid "This page gives an overview over currently download/upload rate." -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:194 -msgid "Traffic Priority Settings" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Type of Limit Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:144 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:181 -msgid "Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Upload Bandwidth (Mbps)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:154 -msgid "Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:96 -msgid "White List for Limit Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "e.g. https, 23, (separator is comma)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:44 -msgid "kB" -msgstr "" diff --git a/rooter/0optionalapps/luci-app-nft-qos/po/sv/nft-qos.po b/rooter/0optionalapps/luci-app-nft-qos/po/sv/nft-qos.po deleted file mode 100644 index da1b53a..0000000 --- a/rooter/0optionalapps/luci-app-nft-qos/po/sv/nft-qos.po +++ /dev/null @@ -1,239 +0,0 @@ -msgid "" -msgstr "" -"PO-Revision-Date: 2020-11-22 15:35+0000\n" -"Last-Translator: PontusÖsterlindh \n" -"Language-Team: Swedish \n" -"Language: sv\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.4-dev\n" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:136 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:155 -msgid "Bytes Total" -msgstr "Bytes Totalt" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:141 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:160 -msgid "Collecting data..." -msgstr "Samlar in data..." - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:224 -msgid "Comment" -msgstr "Kommentera" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default Download Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Default Network Interface" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default Upload Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default unit for download rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default unit for upload rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Default value for download bandwidth" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default value for download rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Default value for upload bandwidth" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default value for upload rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Download Bandwidth (Mbps)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:135 -msgid "Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Enable Limit Rate Feature" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable Traffic Priority" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable this feature" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:121 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:158 -msgid "Hostname" -msgstr "Värdnamn" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:134 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:153 -msgid "IP Address" -msgstr "IP-adress" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:126 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:163 -msgid "IP Address(V4 / V6)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:128 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:165 -msgid "IP Address(V4 Only)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Limit Enable" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Limit Type" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:135 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:172 -msgid "MAC (optional)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:48 -msgid "MB" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:28 -msgid "NFT-QoS Settings" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Network Interface for Traffic Shaping, e.g. br-lan, eth0.1, eth0, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Network to be apply, e.g. 192.168.1.0/24, 10.2.0.0/16, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Network to be apply, e.g. AAAA::BBBB/64, CCCC::1/128, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:65 -msgid "No information available" -msgstr "Ingen information tillgänglig" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:137 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:156 -msgid "Packets Total" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:207 -msgid "Priority" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:199 -msgid "Protocol" -msgstr "Protokoll" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:16 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:23 -msgid "Qos over Nftables" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:12 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:139 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:176 -msgid "Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:130 -msgid "Realtime Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:125 -msgid "Realtime Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:149 -msgid "Realtime Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "Service" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:116 -msgid "Static QoS-Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:153 -msgid "Static QoS-Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Target Network (IPv4/MASK)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Target Network6 (IPv6/MASK)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:127 -msgid "This page gives an overview over currently download/upload rate." -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:194 -msgid "Traffic Priority Settings" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Type of Limit Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:144 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:181 -msgid "Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Upload Bandwidth (Mbps)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:154 -msgid "Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:96 -msgid "White List for Limit Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "e.g. https, 23, (separator is comma)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:44 -msgid "kB" -msgstr "" diff --git a/rooter/0optionalapps/luci-app-nft-qos/po/templates/nft-qos.pot b/rooter/0optionalapps/luci-app-nft-qos/po/templates/nft-qos.pot deleted file mode 100644 index 8fecfa0..0000000 --- a/rooter/0optionalapps/luci-app-nft-qos/po/templates/nft-qos.pot +++ /dev/null @@ -1,230 +0,0 @@ -msgid "" -msgstr "Content-Type: text/plain; charset=UTF-8" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:136 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:155 -msgid "Bytes Total" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:141 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:160 -msgid "Collecting data..." -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:224 -msgid "Comment" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default Download Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Default Network Interface" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default Upload Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default unit for download rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default unit for upload rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Default value for download bandwidth" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default value for download rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Default value for upload bandwidth" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default value for upload rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Download Bandwidth (Mbps)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:135 -msgid "Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Enable Limit Rate Feature" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable Traffic Priority" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable this feature" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:121 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:158 -msgid "Hostname" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:134 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:153 -msgid "IP Address" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:126 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:163 -msgid "IP Address(V4 / V6)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:128 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:165 -msgid "IP Address(V4 Only)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Limit Enable" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Limit Type" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:135 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:172 -msgid "MAC (optional)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:48 -msgid "MB" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:28 -msgid "NFT-QoS Settings" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Network Interface for Traffic Shaping, e.g. br-lan, eth0.1, eth0, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Network to be apply, e.g. 192.168.1.0/24, 10.2.0.0/16, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Network to be apply, e.g. AAAA::BBBB/64, CCCC::1/128, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:65 -msgid "No information available" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:137 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:156 -msgid "Packets Total" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:207 -msgid "Priority" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:199 -msgid "Protocol" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:16 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:23 -msgid "Qos over Nftables" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:12 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:139 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:176 -msgid "Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:130 -msgid "Realtime Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:125 -msgid "Realtime Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:149 -msgid "Realtime Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "Service" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:116 -msgid "Static QoS-Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:153 -msgid "Static QoS-Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Target Network (IPv4/MASK)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Target Network6 (IPv6/MASK)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:127 -msgid "This page gives an overview over currently download/upload rate." -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:194 -msgid "Traffic Priority Settings" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Type of Limit Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:144 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:181 -msgid "Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Upload Bandwidth (Mbps)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:154 -msgid "Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:96 -msgid "White List for Limit Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "e.g. https, 23, (separator is comma)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:44 -msgid "kB" -msgstr "" diff --git a/rooter/0optionalapps/luci-app-nft-qos/po/tr/nft-qos.po b/rooter/0optionalapps/luci-app-nft-qos/po/tr/nft-qos.po deleted file mode 100644 index fd53746..0000000 --- a/rooter/0optionalapps/luci-app-nft-qos/po/tr/nft-qos.po +++ /dev/null @@ -1,239 +0,0 @@ -msgid "" -msgstr "" -"PO-Revision-Date: 2020-11-28 20:18+0000\n" -"Last-Translator: Oğuz Ersen \n" -"Language-Team: Turkish \n" -"Language: tr\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.4-dev\n" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:136 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:155 -msgid "Bytes Total" -msgstr "Bayt Toplamı" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:141 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:160 -msgid "Collecting data..." -msgstr "Veri alınıyor..." - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:224 -msgid "Comment" -msgstr "Açıklama" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default Download Rate" -msgstr "Varsayılan İndirme Hızı" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default Download Unit" -msgstr "Varsayılan İndirme Birimi" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Default Network Interface" -msgstr "Varsayılan Ağ Arayüzü" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default Upload Rate" -msgstr "Varsayılan Yükleme Hızı" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default Upload Unit" -msgstr "Varsayılan Yükleme Birimi" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default unit for download rate" -msgstr "İndirme hızı için varsayılan birim" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default unit for upload rate" -msgstr "Yükleme hızı için varsayılan birim" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Default value for download bandwidth" -msgstr "İndirme bant genişliği için varsayılan değer" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default value for download rate" -msgstr "İndirme hızı için varsayılan değer" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Default value for upload bandwidth" -msgstr "Yükleme band genişliği için varsayılan değer" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default value for upload rate" -msgstr "Yükleme hızı için varsayılan değer" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Download Bandwidth (Mbps)" -msgstr "İndirme Band Genişliği (Mbps)" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:135 -msgid "Download Rate" -msgstr "İndirme Hızı" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Enable Limit Rate Feature" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable Traffic Priority" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable this feature" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:121 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:158 -msgid "Hostname" -msgstr "Sunucu adı" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:134 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:153 -msgid "IP Address" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:126 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:163 -msgid "IP Address(V4 / V6)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:128 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:165 -msgid "IP Address(V4 Only)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Limit Enable" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Limit Type" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:135 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:172 -msgid "MAC (optional)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:48 -msgid "MB" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:28 -msgid "NFT-QoS Settings" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Network Interface for Traffic Shaping, e.g. br-lan, eth0.1, eth0, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Network to be apply, e.g. 192.168.1.0/24, 10.2.0.0/16, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Network to be apply, e.g. AAAA::BBBB/64, CCCC::1/128, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:65 -msgid "No information available" -msgstr "Bilgi bulunmamaktadır" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:137 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:156 -msgid "Packets Total" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:207 -msgid "Priority" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:199 -msgid "Protocol" -msgstr "Protokol" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:16 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:23 -msgid "Qos over Nftables" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:12 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:139 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:176 -msgid "Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:130 -msgid "Realtime Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:125 -msgid "Realtime Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:149 -msgid "Realtime Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "Service" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:116 -msgid "Static QoS-Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:153 -msgid "Static QoS-Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Target Network (IPv4/MASK)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Target Network6 (IPv6/MASK)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:127 -msgid "This page gives an overview over currently download/upload rate." -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:194 -msgid "Traffic Priority Settings" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Type of Limit Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:144 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:181 -msgid "Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Upload Bandwidth (Mbps)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:154 -msgid "Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:96 -msgid "White List for Limit Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "e.g. https, 23, (separator is comma)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:44 -msgid "kB" -msgstr "" diff --git a/rooter/0optionalapps/luci-app-nft-qos/po/uk/nft-qos.po b/rooter/0optionalapps/luci-app-nft-qos/po/uk/nft-qos.po deleted file mode 100644 index 748da14..0000000 --- a/rooter/0optionalapps/luci-app-nft-qos/po/uk/nft-qos.po +++ /dev/null @@ -1,240 +0,0 @@ -msgid "" -msgstr "" -"PO-Revision-Date: 2020-02-17 11:51+0000\n" -"Last-Translator: Olexandr Nesterenko \n" -"Language-Team: Ukrainian \n" -"Language: uk\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 3.11-dev\n" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:136 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:155 -msgid "Bytes Total" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:141 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:160 -msgid "Collecting data..." -msgstr "Збирання даних..." - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:224 -msgid "Comment" -msgstr "Примітка" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default Download Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Default Network Interface" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default Upload Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default unit for download rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default unit for upload rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Default value for download bandwidth" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default value for download rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Default value for upload bandwidth" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default value for upload rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Download Bandwidth (Mbps)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:135 -msgid "Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Enable Limit Rate Feature" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable Traffic Priority" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable this feature" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:121 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:158 -msgid "Hostname" -msgstr "Назва (ім'я) вузла" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:134 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:153 -msgid "IP Address" -msgstr "IP-адреса" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:126 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:163 -msgid "IP Address(V4 / V6)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:128 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:165 -msgid "IP Address(V4 Only)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Limit Enable" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Limit Type" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:135 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:172 -msgid "MAC (optional)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:48 -msgid "MB" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:28 -msgid "NFT-QoS Settings" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Network Interface for Traffic Shaping, e.g. br-lan, eth0.1, eth0, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Network to be apply, e.g. 192.168.1.0/24, 10.2.0.0/16, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Network to be apply, e.g. AAAA::BBBB/64, CCCC::1/128, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:65 -msgid "No information available" -msgstr "Інформація відсутня" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:137 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:156 -msgid "Packets Total" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:207 -msgid "Priority" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:199 -msgid "Protocol" -msgstr "Протокол" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:16 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:23 -msgid "Qos over Nftables" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:12 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:139 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:176 -msgid "Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:130 -msgid "Realtime Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:125 -msgid "Realtime Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:149 -msgid "Realtime Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "Service" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:116 -msgid "Static QoS-Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:153 -msgid "Static QoS-Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Target Network (IPv4/MASK)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Target Network6 (IPv6/MASK)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:127 -msgid "This page gives an overview over currently download/upload rate." -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:194 -msgid "Traffic Priority Settings" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Type of Limit Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:144 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:181 -msgid "Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Upload Bandwidth (Mbps)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:154 -msgid "Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:96 -msgid "White List for Limit Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "e.g. https, 23, (separator is comma)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:44 -msgid "kB" -msgstr "" diff --git a/rooter/0optionalapps/luci-app-nft-qos/po/vi/nft-qos.po b/rooter/0optionalapps/luci-app-nft-qos/po/vi/nft-qos.po deleted file mode 100644 index dcbba21..0000000 --- a/rooter/0optionalapps/luci-app-nft-qos/po/vi/nft-qos.po +++ /dev/null @@ -1,239 +0,0 @@ -msgid "" -msgstr "" -"PO-Revision-Date: 2019-11-13 13:07+0000\n" -"Last-Translator: Le Van Uoc \n" -"Language-Team: Vietnamese \n" -"Language: vi\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 3.10-dev\n" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:136 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:155 -msgid "Bytes Total" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:141 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:160 -msgid "Collecting data..." -msgstr "Đang lấy dữ liệu..." - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:224 -msgid "Comment" -msgstr "Bình luận" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default Download Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Default Network Interface" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default Upload Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default unit for download rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default unit for upload rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Default value for download bandwidth" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default value for download rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Default value for upload bandwidth" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default value for upload rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Download Bandwidth (Mbps)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:135 -msgid "Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Enable Limit Rate Feature" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable Traffic Priority" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable this feature" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:121 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:158 -msgid "Hostname" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:134 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:153 -msgid "IP Address" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:126 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:163 -msgid "IP Address(V4 / V6)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:128 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:165 -msgid "IP Address(V4 Only)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Limit Enable" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Limit Type" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:135 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:172 -msgid "MAC (optional)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:48 -msgid "MB" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:28 -msgid "NFT-QoS Settings" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Network Interface for Traffic Shaping, e.g. br-lan, eth0.1, eth0, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Network to be apply, e.g. 192.168.1.0/24, 10.2.0.0/16, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Network to be apply, e.g. AAAA::BBBB/64, CCCC::1/128, etc" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:65 -msgid "No information available" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:137 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:156 -msgid "Packets Total" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:207 -msgid "Priority" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:199 -msgid "Protocol" -msgstr "Giao thức" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:16 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:23 -msgid "Qos over Nftables" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:12 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:139 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:176 -msgid "Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:130 -msgid "Realtime Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:125 -msgid "Realtime Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:149 -msgid "Realtime Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "Service" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:116 -msgid "Static QoS-Download Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:153 -msgid "Static QoS-Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Target Network (IPv4/MASK)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Target Network6 (IPv6/MASK)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:127 -msgid "This page gives an overview over currently download/upload rate." -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:194 -msgid "Traffic Priority Settings" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Type of Limit Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:144 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:181 -msgid "Unit" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Upload Bandwidth (Mbps)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:154 -msgid "Upload Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:96 -msgid "White List for Limit Rate" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "e.g. https, 23, (separator is comma)" -msgstr "" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:44 -msgid "kB" -msgstr "" diff --git a/rooter/0optionalapps/luci-app-nft-qos/po/zh_Hans/nft-qos.po b/rooter/0optionalapps/luci-app-nft-qos/po/zh_Hans/nft-qos.po deleted file mode 100644 index 02a59da..0000000 --- a/rooter/0optionalapps/luci-app-nft-qos/po/zh_Hans/nft-qos.po +++ /dev/null @@ -1,245 +0,0 @@ -# -# Yangfl , 2019. -# -msgid "" -msgstr "" -"Project-Id-Version: \n" -"POT-Creation-Date: \n" -"PO-Revision-Date: 2020-11-22 15:35+0000\n" -"Last-Translator: Eric \n" -"Language-Team: Chinese (Simplified) \n" -"Language: zh_Hans\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.4-dev\n" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:136 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:155 -msgid "Bytes Total" -msgstr "字节总数" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:141 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:160 -msgid "Collecting data..." -msgstr "正在收集数据…" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:224 -msgid "Comment" -msgstr "注解" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default Download Rate" -msgstr "默认下载速率" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default Download Unit" -msgstr "默认下载速率单位" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Default Network Interface" -msgstr "默认网络接口" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default Upload Rate" -msgstr "默认上传速率" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default Upload Unit" -msgstr "默认上传速率单位" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default unit for download rate" -msgstr "默认的下载速率单位" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default unit for upload rate" -msgstr "默认的上传速率单位" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Default value for download bandwidth" -msgstr "下载带宽的默认值" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default value for download rate" -msgstr "下载速率的默认值" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Default value for upload bandwidth" -msgstr "上传带宽的默认值" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default value for upload rate" -msgstr "上传速率的默认值" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Download Bandwidth (Mbps)" -msgstr "下载带宽(Mbps)" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:135 -msgid "Download Rate" -msgstr "下载速率" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Enable Limit Rate Feature" -msgstr "开启速率限制功能" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable Traffic Priority" -msgstr "开启流量优先级" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable this feature" -msgstr "开启这个功能" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:121 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:158 -msgid "Hostname" -msgstr "主机名" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:134 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:153 -msgid "IP Address" -msgstr "IP 地址" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:126 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:163 -msgid "IP Address(V4 / V6)" -msgstr "IP 地址(V4 / V6)" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:128 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:165 -msgid "IP Address(V4 Only)" -msgstr "IP 地址(仅 V4)" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Limit Enable" -msgstr "限速开启" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Limit Type" -msgstr "限速类型" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:135 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:172 -msgid "MAC (optional)" -msgstr "物理地址(可选)" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:48 -msgid "MB" -msgstr "MB" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:28 -msgid "NFT-QoS Settings" -msgstr "NFT-QoS 设置" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Network Interface for Traffic Shaping, e.g. br-lan, eth0.1, eth0, etc" -msgstr "流量整形的目标网络接口,例如br-lan、eth0.1、eth0等" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Network to be apply, e.g. 192.168.1.0/24, 10.2.0.0/16, etc" -msgstr "将要应用规则的网络,例如192.168.1.0/24、10.2.0.0/16等" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Network to be apply, e.g. AAAA::BBBB/64, CCCC::1/128, etc" -msgstr "将要应用规则的网络,例如AAAA::BBBB/64、CCCC::1/128等" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:65 -msgid "No information available" -msgstr "无可用信息" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:137 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:156 -msgid "Packets Total" -msgstr "数据包总数" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:207 -msgid "Priority" -msgstr "优先级" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:199 -msgid "Protocol" -msgstr "协议" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:16 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:23 -msgid "Qos over Nftables" -msgstr "QoS Nftables 版" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:12 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:139 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:176 -msgid "Rate" -msgstr "速率" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:130 -msgid "Realtime Download Rate" -msgstr "实时下载速率" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:125 -msgid "Realtime Rate" -msgstr "实时速率显示" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:149 -msgid "Realtime Upload Rate" -msgstr "实时上传速率" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "Service" -msgstr "服务" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:116 -msgid "Static QoS-Download Rate" -msgstr "静态 QoS-下载速率" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:153 -msgid "Static QoS-Upload Rate" -msgstr "静态 QoS-上传速率" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Target Network (IPv4/MASK)" -msgstr "目标网络(IPv4 地址/掩码)" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Target Network6 (IPv6/MASK)" -msgstr "目标网络 v6(IPv6 地址/掩码)" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:127 -msgid "This page gives an overview over currently download/upload rate." -msgstr "该页面提供了当前上传和下载速率的一个总览。" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:194 -msgid "Traffic Priority Settings" -msgstr "流量优先级设置" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Type of Limit Rate" -msgstr "限速的类型" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:144 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:181 -msgid "Unit" -msgstr "单元" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Upload Bandwidth (Mbps)" -msgstr "上传带宽(Mbps)" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:154 -msgid "Upload Rate" -msgstr "上传速率" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:96 -msgid "White List for Limit Rate" -msgstr "限速白名单" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "e.g. https, 23, (separator is comma)" -msgstr "例如https, 23(用逗号分隔)" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:44 -msgid "kB" -msgstr "kB" diff --git a/rooter/0optionalapps/luci-app-nft-qos/po/zh_Hant/nft-qos.po b/rooter/0optionalapps/luci-app-nft-qos/po/zh_Hant/nft-qos.po deleted file mode 100644 index e2fa5f4..0000000 --- a/rooter/0optionalapps/luci-app-nft-qos/po/zh_Hant/nft-qos.po +++ /dev/null @@ -1,245 +0,0 @@ -# -# Yangfl , 2019. -# -msgid "" -msgstr "" -"Project-Id-Version: \n" -"POT-Creation-Date: \n" -"PO-Revision-Date: 2020-06-30 13:41+0000\n" -"Last-Translator: Hulen \n" -"Language-Team: Chinese (Traditional) \n" -"Language: zh_Hant\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.2-dev\n" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:136 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:155 -msgid "Bytes Total" -msgstr "位元組總數" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:141 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:160 -msgid "Collecting data..." -msgstr "收集資料中..." - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:224 -msgid "Comment" -msgstr "註解" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default Download Rate" -msgstr "預設下載速率" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default Download Unit" -msgstr "預設下載速率單位" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Default Network Interface" -msgstr "預設網路介面" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default Upload Rate" -msgstr "預設上傳速率" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default Upload Unit" -msgstr "預設上傳速率單位" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:53 -msgid "Default unit for download rate" -msgstr "預設的下載速率單位" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:65 -msgid "Default unit for upload rate" -msgstr "預設的上傳速率單位" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Default value for download bandwidth" -msgstr "下載頻寬的預設值" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:48 -msgid "Default value for download rate" -msgstr "下載速率的預設值" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Default value for upload bandwidth" -msgstr "上傳頻寬的預設值" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:60 -msgid "Default value for upload rate" -msgstr "上傳速率的預設值" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:75 -msgid "Download Bandwidth (Mbps)" -msgstr "下載頻寬(Mbps)" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:135 -msgid "Download Rate" -msgstr "下載速率" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Enable Limit Rate Feature" -msgstr "開啟速率限制功能" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable Traffic Priority" -msgstr "開啟流量優先順序" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:103 -msgid "Enable this feature" -msgstr "開啟這個功能" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:121 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:158 -msgid "Hostname" -msgstr "主機名稱" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:134 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:153 -msgid "IP Address" -msgstr "IP 位址" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:126 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:163 -msgid "IP Address(V4 / V6)" -msgstr "IP 位址(V4 / V6)" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:128 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:165 -msgid "IP Address(V4 Only)" -msgstr "IP 位址(僅 V4)" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:38 -msgid "Limit Enable" -msgstr "限速開啟" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Limit Type" -msgstr "限速型別" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:135 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:172 -msgid "MAC (optional)" -msgstr "實體位址(可選)" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:48 -msgid "MB" -msgstr "MB" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:28 -msgid "NFT-QoS Settings" -msgstr "NFT-QoS 設定" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:107 -msgid "Network Interface for Traffic Shaping, e.g. br-lan, eth0.1, eth0, etc" -msgstr "流量整形的目標網路介面,例如br-lan、eth0.1、eth0等" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Network to be apply, e.g. 192.168.1.0/24, 10.2.0.0/16, etc" -msgstr "將要應用規則的網路,例如192.168.1.0/24、10.2.0.0/16等" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Network to be apply, e.g. AAAA::BBBB/64, CCCC::1/128, etc" -msgstr "將要應用規則的網路,例如AAAA::BBBB/64、CCCC::1/128等" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:65 -msgid "No information available" -msgstr "無可用資訊" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:137 -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:156 -msgid "Packets Total" -msgstr "資料包總數" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:207 -msgid "Priority" -msgstr "優先順序" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:199 -msgid "Protocol" -msgstr "協定" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:16 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:23 -msgid "Qos over Nftables" -msgstr "QoS Nftables 版" - -#: applications/luci-app-nft-qos/luasrc/controller/nft-qos.lua:12 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:139 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:176 -msgid "Rate" -msgstr "速率" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:130 -msgid "Realtime Download Rate" -msgstr "實時下載速率" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:125 -msgid "Realtime Rate" -msgstr "實時速率顯示" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:149 -msgid "Realtime Upload Rate" -msgstr "實時上傳速率" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "Service" -msgstr "服務" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:116 -msgid "Static QoS-Download Rate" -msgstr "靜態 QoS-下載速率" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:153 -msgid "Static QoS-Upload Rate" -msgstr "靜態 QoS-上傳速率" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:85 -msgid "Target Network (IPv4/MASK)" -msgstr "目標網路(IPv4 位址/掩碼)" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:91 -msgid "Target Network6 (IPv6/MASK)" -msgstr "目標網路 v6(IPv6 位址/掩碼)" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:127 -msgid "This page gives an overview over currently download/upload rate." -msgstr "該頁面提供了當前上傳和下載速率的一個總覽。" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:194 -msgid "Traffic Priority Settings" -msgstr "流量優先順序設定" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:42 -msgid "Type of Limit Rate" -msgstr "限速的型別" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:144 -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:181 -msgid "Unit" -msgstr "單元" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:80 -msgid "Upload Bandwidth (Mbps)" -msgstr "上傳頻寬(Mbps)" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:154 -msgid "Upload Rate" -msgstr "上傳速率" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:96 -msgid "White List for Limit Rate" -msgstr "限速白名單" - -#: applications/luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua:221 -msgid "e.g. https, 23, (separator is comma)" -msgstr "例如https, 23(用逗號分隔)" - -#: applications/luci-app-nft-qos/luasrc/view/nft-qos/rate.htm:44 -msgid "kB" -msgstr "kB" diff --git a/rooter/0optionalapps/luci-app-nft-qos/root/usr/share/rpcd/acl.d/luci-app-nft-qos.json b/rooter/0optionalapps/luci-app-nft-qos/root/usr/share/rpcd/acl.d/luci-app-nft-qos.json deleted file mode 100644 index b2de626..0000000 --- a/rooter/0optionalapps/luci-app-nft-qos/root/usr/share/rpcd/acl.d/luci-app-nft-qos.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "luci-app-nft-qos": { - "description": "Grant UCI access for luci-app-nft-qos", - "read": { - "uci": [ "nft-qos" ] - }, - "write": { - "uci": [ "nft-qos" ] - } - } -} diff --git a/rooter/0optionalapps/luci-app-rooterddns/Makefile b/rooter/0optionalapps/luci-app-rooterddns/Makefile deleted file mode 100644 index 4ed1d3b..0000000 --- a/rooter/0optionalapps/luci-app-rooterddns/Makefile +++ /dev/null @@ -1,34 +0,0 @@ -#Owned by DairyMan@Whirlpool -# -#Copyright GNU act. -include $(TOPDIR)/rules.mk - -PKG_NAME:=luci-app-rooterddns -PKG_VERSION:=1.000 -PKG_RELEASE:=1 - -PKG_MAINTAINER:=Created by DM/makefile by Cobia@whirlpool -include $(INCLUDE_DIR)/package.mk - -define Package/luci-app-rooterddns - SECTION:=luci - CATEGORY:=LuCI - DEPENDS:=+ddns-scripts +ddns-scripts_no-ip_com - SUBMENU:=3. Applications - TITLE:=LuCI Support for Dynamic DNS Client - PKGARCH:=all -endef - -define Package/luci-app-rooterddns/description - LuCI Support for Dynamic DNS Client -endef - - -define Build/Compile -endef - -define Package/luci-app-rooterddns/install - $(CP) ./files/* $(1)/ -endef - -$(eval $(call BuildPackage,luci-app-rooterddns)) diff --git a/rooter/0optionalapps/luci-app-rooterddns/files/etc/uci-defaults/40_luci-ddns b/rooter/0optionalapps/luci-app-rooterddns/files/etc/uci-defaults/40_luci-ddns deleted file mode 100644 index a82c1f9..0000000 --- a/rooter/0optionalapps/luci-app-rooterddns/files/etc/uci-defaults/40_luci-ddns +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -# no longer needed for "Save and Apply" to restart ddns -uci -q batch <<-EOF >/dev/null - delete ucitrack.@ddns[-1] - commit ucitrack -EOF - -rm -f /tmp/luci-indexcache -return 0 diff --git a/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/controller/ddns.lua b/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/controller/ddns.lua deleted file mode 100644 index 89da567..0000000 --- a/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/controller/ddns.lua +++ /dev/null @@ -1,308 +0,0 @@ --- Copyright 2008 Steven Barth --- Copyright 2008 Jo-Philipp Wich --- Copyright 2013 Manuel Munz --- Copyright 2014-2016 Christian Schoenebeck --- Licensed to the public under the Apache License 2.0. - -module("luci.controller.ddns", package.seeall) - -local NX = require "nixio" -local NXFS = require "nixio.fs" -local DISP = require "luci.dispatcher" -local HTTP = require "luci.http" -local I18N = require "luci.i18n" -- not globally avalible here -local IPKG = require "luci.model.ipkg" -local SYS = require "luci.sys" -local UCI = require "luci.model.uci" -local UTIL = require "luci.util" -local DDNS = require "luci.tools.ddns" -- ddns multiused functions - -luci_helper = "/usr/lib/ddns/dynamic_dns_lucihelper.sh" - -local srv_name = "ddns-scripts" -local srv_ver_min = "2.7.6" -- minimum version of service required -local srv_ver_cmd = luci_helper .. [[ -V | awk {'print $2'}]] -local app_name = "luci-app-ddns" -local app_title = "Dynamic DNS" -local app_version = "2.4.8-1" - -function index() - local nxfs = require "nixio.fs" -- global definitions not available - local sys = require "luci.sys" -- in function index() - local ddns = require "luci.tools.ddns" -- ddns multiused functions - local muci = require "luci.model.uci" - - -- no config create an empty one - if not nxfs.access("/etc/config/ddns") then - nxfs.writefile("/etc/config/ddns", "") - end - - -- preset new option "lookup_host" if not already defined - local uci = muci.cursor() - local commit = false - uci:foreach("ddns", "service", function (s) - if not s["lookup_host"] and s["domain"] then - uci:set("ddns", s[".name"], "lookup_host", s["domain"]) - commit = true - end - end) - if commit then uci:commit("ddns") end - uci:unload("ddns") - - entry( {"admin", "services", "ddns"}, cbi("ddns/overview"), _("Dynamic DNS"), 59) - entry( {"admin", "services", "ddns", "detail"}, cbi("ddns/detail"), nil ).leaf = true - entry( {"admin", "services", "ddns", "hints"}, cbi("ddns/hints", - {hideapplybtn=true, hidesavebtn=true, hideresetbtn=true}), nil ).leaf = true - entry( {"admin", "services", "ddns", "global"}, cbi("ddns/global"), nil ).leaf = true - entry( {"admin", "services", "ddns", "logview"}, call("logread") ).leaf = true - entry( {"admin", "services", "ddns", "startstop"}, post("startstop") ).leaf = true - entry( {"admin", "services", "ddns", "status"}, call("status") ).leaf = true -end - --- Application specific information functions -function app_description() - return I18N.translate("Dynamic DNS allows your router to be reached with " .. - "a fixed hostname while having a dynamically changing IP address.") -end -function app_title_back() - return [[]] - .. I18N.translate(app_title) - .. [[]] -end - --- Standardized application/service functions -function app_title_main() - return [[]] - .. I18N.translate(app_title) - .. [[]] -end -function service_version() - local ver = nil - - ver = UTIL.exec(srv_ver_cmd) - if #ver > 0 then return ver end - - IPKG.list_installed(srv_name, function(n, v, d) - if v and (#v > 0) then ver = v end - end - ) - return ver -end -function service_ok() - return IPKG.compare_versions((service_version() or "0"), ">=", srv_ver_min) -end - --- internal function to read all sections status and return data array -local function _get_status() - local uci = UCI.cursor() - local service = SYS.init.enabled("ddns") and 1 or 0 - local url_start = DISP.build_url("admin", "system", "startup") - local data = {} -- Array to transfer data to javascript - - data[#data+1] = { - enabled = service, -- service enabled - url_up = url_start, -- link to enable DDS (System-Startup) - } - - uci:foreach("ddns", "service", function (s) - - -- Get section we are looking at - -- and enabled state - local section = s[".name"] - local enabled = tonumber(s["enabled"]) or 0 - local datelast = "_empty_" -- formatted date of last update - local datenext = "_empty_" -- formatted date of next update - - -- get force seconds - local force_seconds = DDNS.calc_seconds( - tonumber(s["force_interval"]) or 72 , - s["force_unit"] or "hours" ) - -- get/validate pid and last update - local pid = DDNS.get_pid(section) - local uptime = SYS.uptime() - local lasttime = DDNS.get_lastupd(section) - if lasttime > uptime then -- /var might not be linked to /tmp - lasttime = 0 -- and/or not cleared on reboot - end - - -- no last update happen - if lasttime == 0 then - datelast = "_never_" - - -- we read last update - else - -- calc last update - -- sys.epoch - sys uptime + lastupdate(uptime) - local epoch = os.time() - uptime + lasttime - -- use linux date to convert epoch - datelast = DDNS.epoch2date(epoch) - -- calc and fill next update - datenext = DDNS.epoch2date(epoch + force_seconds) - end - - -- process running but update needs to happen - -- problems if force_seconds > uptime - force_seconds = (force_seconds > uptime) and uptime or force_seconds - if pid > 0 and ( lasttime + force_seconds - uptime ) <= 0 then - datenext = "_verify_" - - -- run once - elseif force_seconds == 0 then - datenext = "_runonce_" - - -- no process running and NOT enabled - elseif pid == 0 and enabled == 0 then - datenext = "_disabled_" - - -- no process running and enabled - elseif pid == 0 and enabled ~= 0 then - datenext = "_stopped_" - end - - -- get/set monitored interface and IP version - local iface = s["interface"] or "_nonet_" - local use_ipv6 = tonumber(s["use_ipv6"]) or 0 - if iface ~= "_nonet_" then - local ipv = (use_ipv6 == 1) and "IPv6" or "IPv4" - iface = ipv .. " / " .. iface - end - - -- try to get registered IP - local lookup_host = s["lookup_host"] or "_nolookup_" - local dnsserver = s["dns_server"] or "" - local force_ipversion = tonumber(s["force_ipversion"] or 0) - local force_dnstcp = tonumber(s["force_dnstcp"] or 0) - local is_glue = tonumber(s["is_glue"] or 0) - local command = luci_helper .. [[ -]] - if (use_ipv6 == 1) then command = command .. [[6]] end - if (force_ipversion == 1) then command = command .. [[f]] end - if (force_dnstcp == 1) then command = command .. [[t]] end - if (is_glue == 1) then command = command .. [[g]] end - command = command .. [[l ]] .. lookup_host - if (#dnsserver > 0) then command = command .. [[ -d ]] .. dnsserver end - command = command .. [[ -- get_registered_ip]] - local reg_ip = SYS.exec(command) - if reg_ip == "" then - reg_ip = "_nodata_" - end - - -- fill transfer array - data[#data+1] = { - section = section, - enabled = enabled, - iface = iface, - lookup = lookup_host, - reg_ip = reg_ip, - pid = pid, - datelast = datelast, - datenext = datenext - } - end) - - uci:unload("ddns") - return data -end - --- called by XHR.get from detail_logview.htm -function logread(section) - -- read application settings - local uci = UCI.cursor() - local ldir = uci:get("ddns", "global", "ddns_logdir") or "/var/log/ddns" - local lfile = ldir .. "/" .. section .. ".log" - local ldata = NXFS.readfile(lfile) - - if not ldata or #ldata == 0 then - ldata="_nodata_" - end - uci:unload("ddns") - HTTP.write(ldata) -end - --- called by XHR.get from overview_status.htm -function startstop(section, enabled) - local uci = UCI.cursor() - local pid = DDNS.get_pid(section) - local data = {} -- Array to transfer data to javascript - - -- if process running we want to stop and return - if pid > 0 then - local tmp = NX.kill(pid, 15) -- terminate - NX.nanosleep(2) -- 2 second "show time" - -- status changed so return full status - data = _get_status() - HTTP.prepare_content("application/json") - HTTP.write_json(data) - return - end - - -- read uncommitted changes - -- we don't save and commit data from other section or other options - -- only enabled will be done - local exec = true - local changed = uci:changes("ddns") - for k_config, v_section in pairs(changed) do - -- security check because uci.changes only gets our config - if k_config ~= "ddns" then - exec = false - break - end - for k_section, v_option in pairs(v_section) do - -- check if only section of button was changed - if k_section ~= section then - exec = false - break - end - for k_option, v_value in pairs(v_option) do - -- check if only enabled was changed - if k_option ~= "enabled" then - exec = false - break - end - end - end - end - - -- we can not execute because other - -- uncommitted changes pending, so exit here - if not exec then - HTTP.write("_uncommitted_") - return - end - - -- save enable state - uci:set("ddns", section, "enabled", ( (enabled == "true") and "1" or "0") ) - uci:save("ddns") - uci:commit("ddns") - uci:unload("ddns") - - -- start ddns-updater for section - local command = luci_helper .. [[ -S ]] .. section .. [[ -- start]] - os.execute(command) - NX.nanosleep(3) -- 3 seconds "show time" - - -- status changed so return full status - data = _get_status() - HTTP.prepare_content("application/json") - HTTP.write_json(data) -end - --- called by XHR.poll from overview_status.htm -function status() - local data = _get_status() - HTTP.prepare_content("application/json") - HTTP.write_json(data) -end - diff --git a/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/model/cbi/ddns/detail.lua b/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/model/cbi/ddns/detail.lua deleted file mode 100644 index d283c54..0000000 --- a/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/model/cbi/ddns/detail.lua +++ /dev/null @@ -1,1479 +0,0 @@ --- Copyright 2008 Steven Barth --- Copyright 2008 Jo-Philipp Wich --- Copyright 2013 Manuel Munz --- Copyright 2014-2016 Christian Schoenebeck --- Licensed to the public under the Apache License 2.0. - -local NX = require "nixio" -local NXFS = require "nixio.fs" -local SYS = require "luci.sys" -local UTIL = require "luci.util" -local HTTP = require "luci.http" -local DISP = require "luci.dispatcher" -local WADM = require "luci.tools.webadmin" -local DTYP = require "luci.cbi.datatypes" -local CTRL = require "luci.controller.ddns" -- this application's controller -local DDNS = require "luci.tools.ddns" -- ddns multiused functions - --- takeover arguments -- ####################################################### -local section = arg[1] - --- html constants -- ########################################################### -local font_red = "" -local font_off = "" -local bold_on = "" -local bold_off = "" - --- error text constants -- ##################################################### -local err_ipv6_plain = translate("IPv6 not supported") .. " - " .. - translate("please select 'IPv4' address version") -local err_ipv6_basic = bold_on .. - font_red .. - translate("IPv6 not supported") .. - font_off .. - "
      " .. translate("please select 'IPv4' address version") .. - bold_off -local err_ipv6_other = bold_on .. - font_red .. - translate("IPv6 not supported") .. - font_off .. - "
      " .. translate("please select 'IPv4' address version in") .. " " .. - [[]] .. - translate("Basic Settings") .. - [[]] .. - bold_off - -function err_tab_basic(self) - return translate("Basic Settings") .. " - " .. self.title .. ": " -end -function err_tab_adv(self) - return translate("Advanced Settings") .. " - " .. self.title .. ": " -end -function err_tab_timer(self) - return translate("Timer Settings") .. " - " .. self.title .. ": " -end - --- read services/services_ipv6 files -- ######################################## -local services4 = { } -- IPv4 -- -local fd4 = io.open("/etc/ddns/services", "r") -if fd4 then - local ln, s, t - repeat - ln = fd4:read("*l") - s = ln and ln:match('^%s*".*') -- only handle lines beginning with " - s = s and s:gsub('"','') -- remove " - t = s and UTIL.split(s,"(%s+)",nil,true) -- split on whitespaces - if t then services4[t[1]]=t[2] end - until not ln - fd4:close() -end - -local services6 = { } -- IPv6 -- -local fd6 = io.open("/etc/ddns/services_ipv6", "r") -if fd6 then - local ln, s, t - repeat - ln = fd6:read("*l") - s = ln and ln:match('^%s*".*') -- only handle lines beginning with " - s = s and s:gsub('"','') -- remove " - t = s and UTIL.split(s,"(%s+)",nil,true) -- split on whitespaces - if t then services6[t[1]]=t[2] end - until not ln - fd6:close() -end - --- multi-used functions -- #################################################### --- function to verify settings around ip_source --- will use dynamic_dns_lucihelper to check if --- local IP can be read -local function _verify_ip_source() - -- section is globally defined here be calling agrument (see above) - local _arg - - local _ipv6 = usev6:formvalue(section) - local _source = (_ipv6 == "1") - and src6:formvalue(section) - or src4:formvalue(section) - - local command = CTRL.luci_helper .. [[ -]] - if (_ipv6 == "1") then command = command .. [[6]] end - - if _source == "network" then - _arg = (_ipv6 == "1") - and ipn6:formvalue(section) - or ipn4:formvalue(section) - command = command .. [[n ]] .. _arg - elseif _source == "web" then - _arg = (_ipv6 == "1") - and iurl6:formvalue(section) - or iurl4:formvalue(section) - command = command .. [[u ]] .. _arg - - -- proxy only needed for checking url - _arg = (pxy) and pxy:formvalue(section) or "" - if (_arg and #_arg > 0) then - command = command .. [[ -p ]] .. _arg - end - elseif _source == "interface" then - command = command .. [[i ]] .. ipi:formvalue(section) - elseif _source == "script" then - command = command .. [[s ]] .. ips:formvalue(section) - end - command = command .. [[ -- get_local_ip]] - return (SYS.call(command) == 0) -end - --- function to check if option is used inside url or script --- return -1 on error, 0 NOT required, 1 required -local function _option_used(option, urlscript) - local surl -- search string for url - local ssh -- search string for script - local required -- option used inside url or script - - if option == "domain" then surl, ssh = '%[DOMAIN%]', '%$domain' - elseif option == "username" then surl, ssh = '%[USERNAME%]', '%$username' - elseif option == "password" then surl, ssh = '%[PASSWORD%]', '%$password' - elseif option == "param_enc" then surl, ssh = '%[PARAMENC%]', '%$param_enc' - elseif option == "param_opt" then surl, ssh = '%[PARAMOPT%]', '%$param_opt' - else - error("undefined option") - return -1 -- return on error - end - - local required = false - -- handle url - if urlscript:find('http') then - required = ( urlscript:find(surl) ) - -- handle script - else - if not urlscript:find("/") then - -- might be inside ddns-scripts directory - urlscript = "/usr/lib/ddns/" .. urlscript - end - -- problem with script exit here - if not NXFS.access(urlscript) then return -1 end - - local f = io.input(urlscript) - -- still problem with script exit here - if not f then return -1 end - for l in f:lines() do - repeat - if l:find('^#') then break end -- continue on comment lines - required = ( l:find(surl) or l:find(ssh) ) - until true - if required then break end - end - f:close() - end - return (required and 1 or 0) -end - --- function to verify if option is valid -local function _option_validate(self, value) - -- section is globally defined here be calling agrument (see above) - local fusev6 = usev6:formvalue(section) or "0" - local fsvc4 = svc4:formvalue(section) or "-" - local fsvc6 = svc6:formvalue(section) or "-" - local urlsh, used - - -- IP-Version dependent custom service selected - if (fusev6 == "0" and fsvc4 == "-") or - (fusev6 == "1" and fsvc6 == "-") then - -- read custom url - urlsh = uurl:formvalue(section) or "" - -- no url then read custom script - if (#urlsh == 0) then - urlsh = ush:formvalue(section) or "" - end - -- IPv4 read from services4 table - elseif (fusev6 == "0") then - urlsh = services4[fsvc4] or "" - -- IPv6 read from services6 table - else - urlsh = services6[fsvc6] or "" - end - -- problem with url or script exit here - -- error handled somewhere else - if (#urlsh == 0) then return "" end - - used = _option_used(self.option, urlsh) - -- on error or not used return empty sting - if used < 1 then return "" end - -- needed but no data then return error - if not value or (#value == 0) then - return nil, err_tab_basic(self) .. translate("missing / required") - end - return value -end - --- cbi-map definition -- ####################################################### -local m = Map("ddns") -m.title = CTRL.app_title_back() -m.description = CTRL.app_description() -m.redirect = DISP.build_url("admin", "services", "ddns") - -m.on_after_commit = function(self) - if self.changed then -- changes ? - local pid = DDNS.get_pid(section) - if pid > 0 then -- running ? - local tmp = NX.kill(pid, 1) -- send SIGHUP - end - end -end - --- provider switch was requested, save and reload page -if m:formvalue("cbid.ddns.%s._switch" % section) then -- section == arg[1] - local fsvc - local fusev6 = m:formvalue("cbid.ddns.%s.use_ipv6" % section) or "0" - if fusev6 == "1" then - fsvc = m:formvalue("cbid.ddns.%s.ipv6_service_name" % section) or "" - else - fsvc = m:formvalue("cbid.ddns.%s.ipv4_service_name" % section) or "" - end - - if fusev6 ~= (m:get(section, "use_ipv6") or "0") then -- IPv6 was changed - m:set(section, "use_ipv6", fusev6) -- save it - end - - if fsvc ~= "-" then -- NOT "custom" - m:set(section, "service_name", fsvc) -- save it - else -- else - m:del(section, "service_name") -- delete it - end - m.uci:save(m.config) - - -- reload page - HTTP.redirect( DISP.build_url("admin", "services", "ddns", "detail", section) ) - return -end - --- read application settings -- ################################################ --- log directory -local logdir = m.uci:get(m.config, "global", "ddns_logdir") or "/var/log/ddns" - --- cbi-section definition -- ################################################### -local ns = m:section( NamedSection, section, "service", - translate("Details for") .. ([[: %s]] % section), - translate("Configure here the details for selected Dynamic DNS service.") ) -ns.instance = section -- arg [1] -ns:tab("basic", translate("Basic Settings"), nil ) -ns:tab("advanced", translate("Advanced Settings"), nil ) -ns:tab("timer", translate("Timer Settings"), nil ) -ns:tab("logview", translate("Log File Viewer"), nil ) - --- TAB: Basic ##################################################################################### --- enabled -- ################################################################# -en = ns:taboption("basic", Flag, "enabled", - translate("Enabled"), - translate("Enable service") ) -en.orientation = "horizontal" - --- IPv4/IPv6 - lookup_host -- ################################################# -luh = ns:taboption("basic", Value, "lookup_host", - translate("Lookup Hostname"), - translate("Hostname/FQDN to validate, if an IP update happens or is necessary") ) -luh.rmempty = false -luh.placeholder = "myhost.example.com" -function luh.validate(self, value) - if not value - or not (#value > 0) - or not DTYP.hostname(value) then - return nil, err_tab_basic(self) .. translate("invalid FQDN / required - Sample") .. ": 'myhost.example.com'" - else - return UTIL.trim(value) - end -end -function luh.parse(self, section, novld) - DDNS.value_parse(self, section, novld) -end - --- use_ipv6 -- ################################################################ -usev6 = ns:taboption("basic", ListValue, "use_ipv6", - translate("IP address version"), - translate("Defines which IP address 'IPv4/IPv6' is send to the DDNS provider") ) -usev6.widget = "radio" -usev6.default = "0" -usev6:value("0", translate("IPv4-Address") ) -function usev6.cfgvalue(self, section) - local value = AbstractValue.cfgvalue(self, section) or "0" - if DDNS.has_ipv6 or (value == "1" and not DDNS.has_ipv6) then - self:value("1", translate("IPv6-Address") ) - end - if value == "1" and not DDNS.has_ipv6 then - self.description = err_ipv6_basic - end - return value -end -function usev6.validate(self, value) - if (value == "1" and DDNS.has_ipv6) or value == "0" then - return value - end - return nil, err_tab_basic(self) .. err_ipv6_plain -end -function usev6.parse(self, section, novld) - DDNS.value_parse(self, section, novld) -end - --- IPv4 - service_name -- ##################################################### -svc4 = ns:taboption("basic", ListValue, "ipv4_service_name", - translate("DDNS Service provider") .. " [IPv4]" ) -svc4.default = "-" -svc4:depends("use_ipv6", "0") -- only show on IPv4 -function svc4.cfgvalue(self, section) - local v = DDNS.read_value(self, section, "service_name") - if v and (#v > 0) then - for s, u in UTIL.kspairs(services4) do - if v == s then return v end - end - end - return "-" -end -function svc4.validate(self, value) - if usev6:formvalue(section) ~= "1" then -- do only on IPv4 - return value - else - return "" -- suppress validate error - end -end -function svc4.write(self, section, value) - if usev6:formvalue(section) ~= "1" then -- do only IPv4 here - self.map:del(section, self.option) -- to be shure - if value ~= "-" then -- and write "service_name - self.map:del(section, "update_url") -- delete update_url - self.map:del(section, "update_script") -- delete update_script - return self.map:set(section, "service_name", value) - else - return self.map:del(section, "service_name") - end - end -end -function svc4.parse(self, section, novld) - DDNS.value_parse(self, section, novld) -end - --- IPv6 - service_name -- ##################################################### -svc6 = ns:taboption("basic", ListValue, "ipv6_service_name", - translate("DDNS Service provider") .. " [IPv6]" ) -svc6.default = "-" -svc6:depends("use_ipv6", "1") -- only show on IPv6 -if not DDNS.has_ipv6 then - svc6.description = err_ipv6_basic -end -function svc6.cfgvalue(self, section) - local v = DDNS.read_value(self, section, "service_name") - if v and (#v > 0) then - for s, u in UTIL.kspairs(services4) do - if v == s then return v end - end - end - return "-" -end -function svc6.validate(self, value) - if usev6:formvalue(section) == "1" then -- do only on IPv6 - if DDNS.has_ipv6 then return value end - return nil, err_tab_basic(self) .. err_ipv6_plain - else - return "" -- suppress validate error - end -end -function svc6.write(self, section, value) - if usev6:formvalue(section) == "1" then -- do only when IPv6 - self.map:del(section, self.option) -- delete "ipv6_service_name" helper - if value ~= "-" then -- and write "service_name - self.map:del(section, "update_url") -- delete update_url - self.map:del(section, "update_script") -- delete update_script - return self.map:set(section, "service_name", value) - else - return self.map:del(section, "service_name") - end - end -end -function svc6.parse(self, section, novld) - DDNS.value_parse(self, section, novld) -end - --- IPv4/IPv6 - change Provider -- ############################################# -svs = ns:taboption("basic", Button, "_switch") -svs.title = translate("Really change DDNS provider?") -svs.inputtitle = translate("Change provider") -svs.inputstyle = "apply" - --- IPv4/IPv6 - update_url -- ################################################## -uurl = ns:taboption("basic", Value, "update_url", - translate("Custom update-URL"), - translate("Update URL to be used for updating your DDNS Provider." .. "
      " .. - "Follow instructions you will find on their WEB page.") ) -function uurl.validate(self, value) - local fush = ush:formvalue(section) - local fusev6 = usev6:formvalue(section) - - if (fusev6 ~= "1" and svc4:formvalue(section) ~= "-") or - (fusev6 == "1" and svc6:formvalue(section) ~= "-") then - return "" -- suppress validate error - elseif not value or (#value == 0) then - if not fush or (#fush == 0) then - return nil, err_tab_basic(self) .. translate("missing / required") - else - return "" -- suppress validate error / update_script is given - end - elseif (#fush > 0) then - return nil, err_tab_basic(self) .. translate("either url or script could be set") - end - - local url = DDNS.parse_url(value) - if not url.scheme == "http" then - return nil, err_tab_basic(self) .. translate("must start with 'http://'") - elseif not url.query then - return nil, err_tab_basic(self) .. " " .. translate("missing / required") - elseif not url.host then - return nil, err_tab_basic(self) .. " " .. translate("missing / required") - elseif SYS.call([[nslookup ]] .. url.host .. [[ >/dev/null 2>&1]]) ~= 0 then - return nil, err_tab_basic(self) .. translate("can not resolve host: ") .. url.host - end - - return value -end -function uurl.parse(self, section, novld) - DDNS.value_parse(self, section, novld) -end - --- IPv4/IPv6 - update_script -- ############################################### -ush = ns:taboption("basic", Value, "update_script", - translate("Custom update-script"), - translate("Custom update script to be used for updating your DDNS Provider.") ) -function ush.validate(self, value) - local fuurl = uurl:formvalue(section) - local fusev6 = usev6:formvalue(section) - - if (fusev6 ~= "1" and svc4:formvalue(section) ~= "-") or - (fusev6 == "1" and svc6:formvalue(section) ~= "-") then - return "" -- suppress validate error - elseif not value or (#value == 0) then - if not fuurl or (#fuurl == 0) then - return nil, err_tab_basic(self) .. translate("missing / required") - else - return "" -- suppress validate error / update_url is given - end - elseif (#fuurl > 0) then - return nil, err_tab_basic(self) .. translate("either url or script could be set") - elseif not NXFS.access(value) then - return nil, err_tab_basic(self) .. translate("File not found") - end - return value -end -function ush.parse(self, section, novld) - DDNS.value_parse(self, section, novld) -end - --- IPv4/IPv6 - domain -- ###################################################### -dom = ns:taboption("basic", Value, "domain", - translate("Domain"), - translate("Replaces [DOMAIN] in Update-URL") ) -dom.placeholder = "myhost.example.com" -function dom.validate(self, value) - return _option_validate(self, value) -end -function dom.parse(self, section, novld) - DDNS.value_parse(self, section, novld) -end - --- IPv4/IPv6 - username -- #################################################### -user = ns:taboption("basic", Value, "username", - translate("Username"), - translate("Replaces [USERNAME] in Update-URL (URL-encoded)") ) -function user.validate(self, value) - return _option_validate(self, value) -end -function user.parse(self, section, novld) - DDNS.value_parse(self, section, novld) -end - --- IPv4/IPv6 - password -- #################################################### -pw = ns:taboption("basic", Value, "password", - translate("Password"), - translate("Replaces [PASSWORD] in Update-URL (URL-encoded)") ) -pw.password = true -function pw.validate(self, value) - return _option_validate(self, value) -end -function pw.parse(self, section, novld) - DDNS.value_parse(self, section, novld) -end - --- IPv4/IPv6 - param_enc -- ################################################### -pe = ns:taboption("basic", Value, "param_enc", - translate("Optional Encoded Parameter"), - translate("Optional: Replaces [PARAMENC] in Update-URL (URL-encoded)") ) -function pe.validate(self, value) - return _option_validate(self, value) -end -function pe.parse(self, section, novld) - DDNS.value_parse(self, section, novld) -end - --- IPv4/IPv6 - param_enc -- ################################################### -po = ns:taboption("basic", Value, "param_opt", - translate("Optional Parameter"), - translate("Optional: Replaces [PARAMOPT] in Update-URL (NOT URL-encoded)") ) -function po.validate(self, value) - return _option_validate(self, value) -end -function po.parse(self, section, novld) - DDNS.value_parse(self, section, novld) -end - --- handled service dependent show/display -- ################################## --- IPv4 -- -local cv4 = svc4:cfgvalue(section) -if cv4 ~= "-" then - svs:depends ("ipv4_service_name", "-" ) -- show only if "-" - ush:depends ("ipv4_service_name", "?") - uurl:depends("ipv4_service_name", "?") -else - uurl:depends("ipv4_service_name", "-") - ush:depends ("ipv4_service_name", "-") - dom:depends("ipv4_service_name", "-" ) - user:depends("ipv4_service_name", "-" ) - pw:depends("ipv4_service_name", "-" ) - pe:depends("ipv4_service_name", "-" ) - po:depends("ipv4_service_name", "-" ) -end -for s, u in UTIL.kspairs(services4) do - svc4:value(s) -- fill DropDown-List - if cv4 ~= s then - svs:depends("ipv4_service_name", s ) - else - dom:depends ("ipv4_service_name", ((_option_used(dom.option, u) == 1) and s or "?") ) - user:depends("ipv4_service_name", ((_option_used(user.option, u) == 1) and s or "?") ) - pw:depends ("ipv4_service_name", ((_option_used(pw.option, u) == 1) and s or "?") ) - pe:depends ("ipv4_service_name", ((_option_used(pe.option, u) == 1) and s or "?") ) - po:depends ("ipv4_service_name", ((_option_used(po.option, u) == 1) and s or "?") ) - end -end -svc4:value("-", translate("-- custom --") ) - --- IPv6 -- -local cv6 = svc6:cfgvalue(section) -if cv6 ~= "-" then - svs:depends ("ipv6_service_name", "-" ) - uurl:depends("ipv6_service_name", "?") - ush:depends ("ipv6_service_name", "?") -else - uurl:depends("ipv6_service_name", "-") - ush:depends ("ipv6_service_name", "-") - dom:depends("ipv6_service_name", "-" ) - user:depends("ipv6_service_name", "-" ) - pw:depends("ipv6_service_name", "-" ) - pe:depends("ipv6_service_name", "-" ) - po:depends("ipv6_service_name", "-" ) -end -for s, u in UTIL.kspairs(services6) do - svc6:value(s) -- fill DropDown-List - if cv6 ~= s then - svs:depends("ipv6_service_name", s ) - else - dom:depends ("ipv6_service_name", ((_option_used(dom.option, u) == 1) and s or "?") ) - user:depends("ipv6_service_name", ((_option_used(user.option, u) == 1) and s or "?") ) - pw:depends ("ipv6_service_name", ((_option_used(pw.option, u) == 1) and s or "?") ) - pe:depends ("ipv6_service_name", ((_option_used(pe.option, u) == 1) and s or "?") ) - po:depends ("ipv6_service_name", ((_option_used(po.option, u) == 1) and s or "?") ) - end -end -svc6:value("-", translate("-- custom --") ) - --- IPv4/IPv6 - use_https -- ################################################### -if DDNS.has_ssl or ( ( m:get(section, "use_https") or "0" ) == "1" ) then - https = ns:taboption("basic", Flag, "use_https", - translate("Use HTTP Secure") ) - https.orientation = "horizontal" - function https.cfgvalue(self, section) - local value = AbstractValue.cfgvalue(self, section) - if not DDNS.has_ssl and value == "1" then - self.description = bold_on .. font_red .. - translate("HTTPS not supported") .. font_off .. "
      " .. - translate("please disable") .. " !" .. bold_off - else - self.description = translate("Enable secure communication with DDNS provider") - end - return value - end - function https.validate(self, value) - if (value == "1" and DDNS.has_ssl ) or value == "0" then return value end - return nil, err_tab_basic(self) .. translate("HTTPS not supported") .. " !" - end - function https.write(self, section, value) - if value == "1" then - return self.map:set(section, self.option, value) - else - self.map:del(section, "cacert") - return self.map:del(section, self.option) - end - end -end - --- IPv4/IPv6 - cacert -- ###################################################### -if DDNS.has_ssl then - cert = ns:taboption("basic", Value, "cacert", - translate("Path to CA-Certificate"), - translate("directory or path/file") .. "
      " .. - translate("or") .. bold_on .. " IGNORE " .. bold_off .. - translate("to run HTTPS without verification of server certificates (insecure)") ) - cert:depends("use_https", "1") - cert.placeholder = "/etc/ssl/certs" - cert.forcewrite = true - function cert.validate(self, value) - if https:formvalue(section) ~= "1" then - return "" -- suppress validate error if NOT https - end - if value then -- otherwise errors in datatype check - if DTYP.directory(value) - or DTYP.file(value) - or (value == "IGNORE") - or (#value == 0) then - return value - end - end - return nil, err_tab_basic(self) .. - translate("file or directory not found or not 'IGNORE'") .. " !" - end - function cert.parse(self, section, novld) - DDNS.value_parse(self, section, novld) - end -end - --- TAB: Advanced ################################################################################# --- IPv4 - ip_source -- ######################################################## -src4 = ns:taboption("advanced", ListValue, "ipv4_source", - translate("IP address source") .. " [IPv4]", - translate("Defines the source to read systems IPv4-Address from, that will be send to the DDNS provider") ) -src4:depends("use_ipv6", "0") -- IPv4 selected -src4.default = "network" -src4:value("network", translate("Network")) -src4:value("web", translate("URL")) -src4:value("interface", translate("Interface")) -src4:value("script", translate("Script")) -function src4.cfgvalue(self, section) - return DDNS.read_value(self, section, "ip_source") -end -function src4.validate(self, value) - if usev6:formvalue(section) == "1" then - return "" -- ignore on IPv6 selected - elseif not _verify_ip_source() then - return nil, err_tab_adv(self) .. - translate("can not detect local IP. Please select a different Source combination") - else - return value - end -end -function src4.write(self, section, value) - if usev6:formvalue(section) == "1" then - return true -- ignore on IPv6 selected - elseif value == "network" then - self.map:del(section, "ip_url") -- delete not need parameters - self.map:del(section, "ip_interface") - self.map:del(section, "ip_script") - elseif value == "web" then - self.map:del(section, "ip_network") -- delete not need parameters - self.map:del(section, "ip_interface") - self.map:del(section, "ip_script") - elseif value == "interface" then - self.map:del(section, "ip_network") -- delete not need parameters - self.map:del(section, "ip_url") - self.map:del(section, "ip_script") - elseif value == "script" then - self.map:del(section, "ip_network") - self.map:del(section, "ip_url") -- delete not need parameters - self.map:del(section, "ip_interface") - end - self.map:del(section, self.option) -- delete "ipv4_source" helper - return self.map:set(section, "ip_source", value) -- and write "ip_source -end -function src4.parse(self, section, novld) - DDNS.value_parse(self, section, novld) -end - --- IPv6 - ip_source -- ######################################################## -src6 = ns:taboption("advanced", ListValue, "ipv6_source", - translate("IP address source") .. " [IPv6]", - translate("Defines the source to read systems IPv6-Address from, that will be send to the DDNS provider") ) -src6:depends("use_ipv6", 1) -- IPv6 selected -src6.default = "network" -src6:value("network", translate("Network")) -src6:value("web", translate("URL")) -src6:value("interface", translate("Interface")) -src6:value("script", translate("Script")) -if not DDNS.has_ipv6 then - src6.description = err_ipv6_other -end -function src6.cfgvalue(self, section) - return DDNS.read_value(self, section, "ip_source") -end -function src6.validate(self, value) - if usev6:formvalue(section) ~= "1" then - return "" -- ignore on IPv4 selected - elseif not DDNS.has_ipv6 then - return nil, err_tab_adv(self) .. err_ipv6_plain - elseif not _verify_ip_source() then - return nil, err_tab_adv(self) .. - translate("can not detect local IP. Please select a different Source combination") - else - return value - end -end -function src6.write(self, section, value) - if usev6:formvalue(section) ~= "1" then - return true -- ignore on IPv4 selected - elseif value == "network" then - self.map:del(section, "ip_url") -- delete not need parameters - self.map:del(section, "ip_interface") - self.map:del(section, "ip_script") - elseif value == "web" then - self.map:del(section, "ip_network") -- delete not need parameters - self.map:del(section, "ip_interface") - self.map:del(section, "ip_script") - elseif value == "interface" then - self.map:del(section, "ip_network") -- delete not need parameters - self.map:del(section, "ip_url") - self.map:del(section, "ip_script") - elseif value == "script" then - self.map:del(section, "ip_network") - self.map:del(section, "ip_url") -- delete not need parameters - self.map:del(section, "ip_interface") - end - self.map:del(section, self.option) -- delete "ipv4_source" helper - return self.map:set(section, "ip_source", value) -- and write "ip_source -end -function src6.parse(self, section, novld) - DDNS.value_parse(self, section, novld) -end - --- IPv4 - ip_network (default "wan") -- ####################################### -ipn4 = ns:taboption("advanced", ListValue, "ipv4_network", - translate("Network") .. " [IPv4]", - translate("Defines the network to read systems IPv4-Address from") ) -ipn4:depends("ipv4_source", "network") -ipn4.default = "wan" -WADM.cbi_add_networks(ipn4) -function ipn4.cfgvalue(self, section) - return DDNS.read_value(self, section, "ip_network") -end -function ipn4.validate(self, value) - if usev6:formvalue(section) == "1" - or src4:formvalue(section) ~= "network" then - -- ignore if IPv6 selected OR - -- ignore everything except "network" - return "" - else - return value - end -end -function ipn4.write(self, section, value) - if usev6:formvalue(section) == "1" - or src4:formvalue(section) ~= "network" then - -- ignore if IPv6 selected OR - -- ignore everything except "network" - return true - else - -- set also as "interface" for monitoring events changes/hot-plug - self.map:set(section, "interface", value) - self.map:del(section, self.option) -- delete "ipv4_network" helper - return self.map:set(section, "ip_network", value) -- and write "ip_network" - end -end -function ipn4.parse(self, section, novld) - DDNS.value_parse(self, section, novld) -end - --- IPv6 - ip_network (default "wan6") -- ###################################### -ipn6 = ns:taboption("advanced", ListValue, "ipv6_network", - translate("Network") .. " [IPv6]" ) -ipn6:depends("ipv6_source", "network") -ipn6.default = "wan6" -WADM.cbi_add_networks(ipn6) -if DDNS.has_ipv6 then - ipn6.description = translate("Defines the network to read systems IPv6-Address from") -else - ipn6.description = err_ipv6_other -end -function ipn6.cfgvalue(self, section) - return DDNS.read_value(self, section, "ip_network") -end -function ipn6.validate(self, value) - if usev6:formvalue(section) ~= "1" - or src6:formvalue(section) ~= "network" then - -- ignore if IPv4 selected OR - -- ignore everything except "network" - return "" - elseif DDNS.has_ipv6 then - return value - else - return nil, err_tab_adv(self) .. err_ipv6_plain - end -end -function ipn6.write(self, section, value) - if usev6:formvalue(section) ~= "1" - or src6:formvalue(section) ~= "network" then - -- ignore if IPv4 selected OR - -- ignore everything except "network" - return true - else - -- set also as "interface" for monitoring events changes/hotplug - self.map:set(section, "interface", value) - self.map:del(section, self.option) -- delete "ipv6_network" helper - return self.map:set(section, "ip_network", value) -- and write "ip_network" - end -end -function ipn6.parse(self, section, novld) - DDNS.value_parse(self, section, novld) -end - --- IPv4 - ip_url (default "checkip.dyndns.com") -- ############################ -iurl4 = ns:taboption("advanced", Value, "ipv4_url", - translate("URL to detect") .. " [IPv4]", - translate("Defines the Web page to read systems IPv4-Address from") ) -iurl4:depends("ipv4_source", "web") -iurl4.default = "http://checkip.dyndns.com" -function iurl4.cfgvalue(self, section) - return DDNS.read_value(self, section, "ip_url") -end -function iurl4.validate(self, value) - if usev6:formvalue(section) == "1" - or src4:formvalue(section) ~= "web" then - -- ignore if IPv6 selected OR - -- ignore everything except "web" - return "" - elseif not value or #value == 0 then - return nil, err_tab_adv(self) .. translate("missing / required") - end - - local url = DDNS.parse_url(value) - if not (url.scheme == "http" or url.scheme == "https") then - return nil, err_tab_adv(self) .. translate("must start with 'http://'") - elseif not url.host then - return nil, err_tab_adv(self) .. " " .. translate("missing / required") - elseif SYS.call([[nslookup ]] .. url.host .. [[>/dev/null 2>&1]]) ~= 0 then - return nil, err_tab_adv(self) .. translate("can not resolve host: ") .. url.host - else - return value - end -end -function iurl4.write(self, section, value) - if usev6:formvalue(section) == "1" - or src4:formvalue(section) ~= "web" then - -- ignore if IPv6 selected OR - -- ignore everything except "web" - return true - else - self.map:del(section, self.option) -- delete "ipv4_url" helper - return self.map:set(section, "ip_url", value) -- and write "ip_url" - end -end -function iurl4.parse(self, section, novld) - DDNS.value_parse(self, section, novld) -end - --- IPv6 - ip_url (default "checkipv6.dyndns.com") -- ########################## -iurl6 = ns:taboption("advanced", Value, "ipv6_url", - translate("URL to detect") .. " [IPv6]" ) -iurl6:depends("ipv6_source", "web") -iurl6.default = "http://checkipv6.dyndns.com" -if DDNS.has_ipv6 then - iurl6.description = translate("Defines the Web page to read systems IPv6-Address from") -else - iurl6.description = err_ipv6_other -end -function iurl6.cfgvalue(self, section) - return DDNS.read_value(self, section, "ip_url") -end -function iurl6.validate(self, value) - if usev6:formvalue(section) ~= "1" - or src6:formvalue(section) ~= "web" then - -- ignore if IPv4 selected OR - -- ignore everything except "web" - return "" - elseif not DDNS.has_ipv6 then - return nil, err_tab_adv(self) .. err_ipv6_plain - elseif not value or #value == 0 then - return nil, err_tab_adv(self) .. translate("missing / required") - end - - local url = DDNS.parse_url(value) - if not (url.scheme == "http" or url.scheme == "https") then - return nil, err_tab_adv(self) .. translate("must start with 'http://'") - elseif not url.host then - return nil, err_tab_adv(self) .. " " .. translate("missing / required") - elseif SYS.call([[nslookup ]] .. url.host .. [[>/dev/null 2>&1]]) ~= 0 then - return nil, err_tab_adv(self) .. translate("can not resolve host: ") .. url.host - else - return value - end -end -function iurl6.write(self, section, value) - if usev6:formvalue(section) ~= "1" - or src6:formvalue(section) ~= "web" then - -- ignore if IPv4 selected OR - -- ignore everything except "web" - return true - else - self.map:del(section, self.option) -- delete "ipv6_url" helper - return self.map:set(section, "ip_url", value) -- and write "ip_url" - end -end -function iurl6.parse(self, section, novld) - DDNS.value_parse(self, section, novld) -end - --- IPv4 + IPv6 - ip_interface -- ############################################## -ipi = ns:taboption("advanced", ListValue, "ip_interface", - translate("Interface"), - translate("Defines the interface to read systems IP-Address from") ) -ipi:depends("ipv4_source", "interface") -- IPv4 -ipi:depends("ipv6_source", "interface") -- or IPv6 -for _, v in pairs(SYS.net.devices()) do - -- show only interface set to a network - -- and ignore loopback - net = WADM.iface_get_network(v) - if net and net ~= "loopback" then - ipi:value(v) - end -end -function ipi.validate(self, value) - local fusev6 = usev6:formvalue(section) - if (fusev6 ~= "1" and src4:formvalue(section) ~= "interface") - or (fusev6 == "1" and src6:formvalue(section) ~= "interface") then - return "" - else - return value - end -end -function ipi.write(self, section, value) - local fusev6 = usev6:formvalue(section) - if (fusev6 ~= "1" and src4:formvalue(section) ~= "interface") - or (fusev6 == "1" and src6:formvalue(section) ~= "interface") then - return true - else - -- get network from device to - -- set also as "interface" for monitoring events changes/hotplug - local net = WADM.iface_get_network(value) - self.map:set(section, "interface", net) - return self.map:set(section, self.option, value) - end -end -function ipi.parse(self, section, novld) - DDNS.value_parse(self, section, novld) -end - --- IPv4 + IPv6 - ip_script -- ################################################# -ips = ns:taboption("advanced", Value, "ip_script", - translate("Script"), - translate("User defined script to read systems IP-Address") ) -ips:depends("ipv4_source", "script") -- IPv4 -ips:depends("ipv6_source", "script") -- or IPv6 -ips.placeholder = "/path/to/script.sh" -function ips.validate(self, value) - local fusev6 = usev6:formvalue(section) - local split - if value then split = UTIL.split(value, " ") end - - if (fusev6 ~= "1" and src4:formvalue(section) ~= "script") - or (fusev6 == "1" and src6:formvalue(section) ~= "script") then - return "" - elseif not value or not (#value > 0) or not NXFS.access(split[1], "x") then - return nil, err_tab_adv(self) .. - translate("not found or not executable - Sample: '/path/to/script.sh'") - else - return value - end -end -function ips.write(self, section, value) - local fusev6 = usev6:formvalue(section) - if (fusev6 ~= "1" and src4:formvalue(section) ~= "script") - or (fusev6 == "1" and src6:formvalue(section) ~= "script") then - return true - else - return self.map:set(section, self.option, value) - end -end -function ips.parse(self, section, novld) - DDNS.value_parse(self, section, novld) -end - --- IPv4 - interface - default "wan" -- ######################################## --- event network to monitor changes/hotplug/dynamic_dns_updater.sh --- only needs to be set if "ip_source"="web" or "script" --- if "ip_source"="network" or "interface" we use their network -eif4 = ns:taboption("advanced", ListValue, "ipv4_interface", - translate("Event Network") .. " [IPv4]", - translate("Network on which the ddns-updater scripts will be started") ) -eif4:depends("ipv4_source", "web") -eif4:depends("ipv4_source", "script") -eif4.default = "wan" -WADM.cbi_add_networks(eif4) -function eif4.cfgvalue(self, section) - return DDNS.read_value(self, section, "interface") -end -function eif4.validate(self, value) - local fsrc4 = src4:formvalue(section) or "" - if usev6:formvalue(section) == "1" - or fsrc4 == "network" - or fsrc4 == "interface" then - return "" -- ignore IPv6, network, interface - else - return value - end -end -function eif4.write(self, section, value) - local fsrc4 = src4:formvalue(section) or "" - if usev6:formvalue(section) == "1" - or fsrc4 == "network" - or fsrc4 == "interface" then - return true -- ignore IPv6, network, interface - else - self.map:del(section, self.option) -- delete "ipv4_interface" helper - return self.map:set(section, "interface", value) -- and write "interface" - end -end -function eif4.parse(self, section, novld) - DDNS.value_parse(self, section, novld) -end - --- IPv6 - interface - default "wan6" -- ####################################### --- event network to monitor changes/hotplug --- only needs to be set if "ip_source"="web" or "script" --- if "ip_source"="network" or "interface" we use their network -eif6 = ns:taboption("advanced", ListValue, "ipv6_interface", - translate("Event Network") .. " [IPv6]" ) -eif6:depends("ipv6_source", "web") -eif6:depends("ipv6_source", "script") -eif6.default = "wan6" -WADM.cbi_add_networks(eif6) -if not DDNS.has_ipv6 then - eif6.description = err_ipv6_other -else - eif6.description = translate("Network on which the ddns-updater scripts will be started") -end -function eif6.cfgvalue(self, section) - return DDNS.read_value(self, section, "interface") -end -function eif6.validate(self, value) - local fsrc6 = src6:formvalue(section) or "" - if usev6:formvalue(section) ~= "1" - or fsrc6 == "network" - or fsrc6 == "interface" then - return "" -- ignore IPv4, network, interface - elseif not DDNS.has_ipv6 then - return nil, err_tab_adv(self) .. err_ipv6_plain - else - return value - end -end -function eif6.write(self, section, value) - local fsrc6 = src6:formvalue(section) or "" - if usev6:formvalue(section) ~= "1" - or fsrc6 == "network" - or fsrc6 == "interface" then - return true -- ignore IPv4, network, interface - else - self.map:del(section, self.option) -- delete "ipv6_interface" helper - return self.map:set(section, "interface", value) -- and write "interface" - end -end -function eif6.parse(self, section, novld) - DDNS.value_parse(self, section, novld) -end - --- IPv4/IPv6 - bind_network -- ################################################ -if DDNS.has_bindnet or ( ( m:get(section, "bind_network") or "" ) ~= "" ) then - bnet = ns:taboption("advanced", ListValue, "bind_network", - translate("Bind Network") ) - bnet:depends("ipv4_source", "web") - bnet:depends("ipv6_source", "web") - bnet.default = "" - bnet:value("", translate("-- default --")) - WADM.cbi_add_networks(bnet) - function bnet.cfgvalue(self, section) - local value = AbstractValue.cfgvalue(self, section) - if not DDNS.has_bindnet and value ~= "" then - self.description = bold_on .. font_red .. - translate("Binding to a specific network not supported") .. font_off .. "
      " .. - translate("please set to 'default'") .. " !" .. bold_off - else - self.description = translate("OPTIONAL: Network to use for communication") .. - "
      " .. translate("Casual users should not change this setting") - end - return value - end - function bnet.validate(self, value) - if ( (value ~= "") and DDNS.has_bindnet ) or (value == "") then return value end - return nil, err_tab_adv(self) .. translate("Binding to a specific network not supported") .. " !" - end - function bnet.parse(self, section, novld) - DDNS.value_parse(self, section, novld) - end -end - --- IPv4 + IPv6 - force_ipversion -- ########################################### --- optional to force wget/curl and host to use only selected IP version --- command parameter "-4" or "-6" -if DDNS.has_forceip or ( ( m:get(section, "force_ipversion") or "0" ) ~= "0" ) then - fipv = ns:taboption("advanced", Flag, "force_ipversion", - translate("Force IP Version") ) - fipv.orientation = "horizontal" - function fipv.cfgvalue(self, section) - local value = AbstractValue.cfgvalue(self, section) - if not DDNS.has_forceip and value ~= "0" then - self.description = bold_on .. font_red .. - translate("Force IP Version not supported") .. font_off .. "
      " .. - translate("please disable") .. " !" .. bold_off - else - self.description = translate("OPTIONAL: Force the usage of pure IPv4/IPv6 only communication.") - end - return value - end - function fipv.validate(self, value) - if (value == "1" and DDNS.has_forceip) or value == "0" then return value end - return nil, err_tab_adv(self) .. translate("Force IP Version not supported") - end -end - --- IPv4 + IPv6 - dns_server -- ################################################ --- optional DNS Server to use resolving my IP -if DDNS.has_dnsserver or ( ( m:get(section, "dns_server") or "" ) ~= "" ) then - dns = ns:taboption("advanced", Value, "dns_server", - translate("DNS-Server"), - translate("OPTIONAL: Use non-default DNS-Server to detect 'Registered IP'.") .. "
      " .. - translate("Format: IP or FQDN")) - dns.placeholder = "mydns.lan" - function dns.validate(self, value) - -- if .datatype is set, then it is checked before calling this function - if not value or (#value == 0) then - return "" -- ignore on empty - elseif not DDNS.has_dnsserver then - return nil, err_tab_adv(self) .. translate("Specifying a DNS-Server is not supported") - elseif not DTYP.host(value) then - return nil, err_tab_adv(self) .. translate("use hostname, FQDN, IPv4- or IPv6-Address") - else - local ipv6 = usev6:formvalue(section) or "0" - local force = fipv:formvalue(section) or "0" - local command = CTRL.luci_helper .. [[ -]] - if (ipv6 == 1) then command = command .. [[6]] end - if (force == 1) then command = command .. [[f]] end - command = command .. [[d ]] .. value .. [[ -- verify_dns]] - - local ret = SYS.call(command) - if ret == 0 then return value -- everything OK - elseif ret == 2 then return nil, err_tab_adv(self) .. translate("nslookup can not resolve host") - elseif ret == 3 then return nil, err_tab_adv(self) .. translate("nc (netcat) can not connect") - elseif ret == 4 then return nil, err_tab_adv(self) .. translate("Forced IP Version don't matched") - else return nil, err_tab_adv(self) .. translate("unspecific error") - end - end - end - function dns.parse(self, section, novld) - DDNS.value_parse(self, section, novld) - end -end - --- IPv4 + IPv6 - force_dnstcp -- ############################################## -if DDNS.has_bindhost or ( ( m:get(section, "force_dnstcp") or "0" ) ~= "0" ) then - tcp = ns:taboption("advanced", Flag, "force_dnstcp", - translate("Force TCP on DNS") ) - tcp.orientation = "horizontal" - function tcp.cfgvalue(self, section) - local value = AbstractValue.cfgvalue(self, section) - if not DDNS.has_bindhost and value ~= "0" then - self.description = bold_on .. font_red .. - translate("DNS requests via TCP not supported") .. font_off .. "
      " .. - translate("please disable") .. " !" .. bold_off - else - self.description = translate("OPTIONAL: Force the use of TCP instead of default UDP on DNS requests.") - end - return value - end - function tcp.validate(self, value) - if (value == "1" and DDNS.has_bindhost ) or value == "0" then - return value - end - return nil, err_tab_adv(self) .. translate("DNS requests via TCP not supported") - end -end - --- IPv4 + IPv6 - proxy -- ##################################################### --- optional Proxy to use for http/https requests [user:password@]proxyhost[:port] -if DDNS.has_proxy or ( ( m:get(section, "proxy") or "" ) ~= "" ) then - pxy = ns:taboption("advanced", Value, "proxy", - translate("PROXY-Server") ) - pxy.placeholder="user:password@myproxy.lan:8080" - function pxy.cfgvalue(self, section) - local value = AbstractValue.cfgvalue(self, section) - if not DDNS.has_proxy and value ~= "" then - self.description = bold_on .. font_red .. - translate("PROXY-Server not supported") .. font_off .. "
      " .. - translate("please remove entry") .. "!" .. bold_off - else - self.description = translate("OPTIONAL: Proxy-Server for detection and updates.") .. "
      " .. - translate("Format") .. ": " .. bold_on .. "[user:password@]proxyhost:port" .. bold_off .. "
      " .. - translate("IPv6 address must be given in square brackets") .. ": " .. - bold_on .. " [2001:db8::1]:8080" .. bold_off - end - return value - end - function pxy.validate(self, value) - -- if .datatype is set, then it is checked before calling this function - if not value or (#value == 0) then - return "" -- ignore on empty - elseif DDNS.has_proxy then - local ipv6 = usev6:formvalue(section) or "0" - local force = fipv:formvalue(section) or "0" - local command = CRTL.luci_helper .. [[ -]] - if (ipv6 == 1) then command = command .. [[6]] end - if (force == 1) then command = command .. [[f]] end - command = command .. [[p ]] .. value .. [[ -- verify_proxy]] - local ret = SYS.call(command) - if ret == 0 then return value - elseif ret == 2 then return nil, err_tab_adv(self) .. translate("nslookup can not resolve host") - elseif ret == 3 then return nil, err_tab_adv(self) .. translate("nc (netcat) can not connect") - elseif ret == 4 then return nil, err_tab_adv(self) .. translate("Forced IP Version don't matched") - elseif ret == 5 then return nil, err_tab_adv(self) .. translate("proxy port missing") - else return nil, err_tab_adv(self) .. translate("unspecific error") - end - else - return nil, err_tab_adv(self) .. translate("PROXY-Server not supported") - end - end - function pxy.parse(self, section, novld) - DDNS.value_parse(self, section, novld) - end -end - --- use_syslog -- ############################################################## -slog = ns:taboption("advanced", ListValue, "use_syslog", - translate("Log to syslog"), - translate("Writes log messages to syslog. Critical Errors will always be written to syslog.") ) -slog.default = "2" -slog:value("0", translate("No logging")) -slog:value("1", translate("Info")) -slog:value("2", translate("Notice")) -slog:value("3", translate("Warning")) -slog:value("4", translate("Error")) -function slog.parse(self, section, novld) - DDNS.value_parse(self, section, novld) -end - --- use_logfile -- ############################################################# -logf = ns:taboption("advanced", Flag, "use_logfile", - translate("Log to file"), - translate("Writes detailed messages to log file. File will be truncated automatically.") .. "
      " .. - translate("File") .. [[: "]] .. logdir .. [[/]] .. section .. [[.log"]] ) -logf.orientation = "horizontal" -logf.default = "1" -- if not defined write to log by default - --- TAB: Timer #################################################################################### --- check_interval -- ########################################################## -ci = ns:taboption("timer", Value, "check_interval", - translate("Check Interval") ) -ci.template = "ddns/detail_value" -ci.default = "10" -function ci.validate(self, value) - if not DTYP.uinteger(value) - or tonumber(value) < 1 then - return nil, err_tab_timer(self) .. translate("minimum value 5 minutes == 300 seconds") - end - - local secs = DDNS.calc_seconds(value, cu:formvalue(section)) - if secs >= 300 then - return value - else - return nil, err_tab_timer(self) .. translate("minimum value 5 minutes == 300 seconds") - end -end -function ci.write(self, section, value) - -- remove when default - local secs = DDNS.calc_seconds(value, cu:formvalue(section)) - if secs ~= 600 then --default 10 minutes - return self.map:set(section, self.option, value) - else - self.map:del(section, "check_unit") - return self.map:del(section, self.option) - end -end -function ci.parse(self, section, novld) - DDNS.value_parse(self, section, novld) -end - --- check_unit -- ############################################################## -cu = ns:taboption("timer", ListValue, "check_unit", "not displayed, but needed otherwise error", - translate("Interval to check for changed IP" .. "
      " .. - "Values below 5 minutes == 300 seconds are not supported") ) -cu.template = "ddns/detail_lvalue" -cu.default = "minutes" -cu:value("seconds", translate("seconds")) -cu:value("minutes", translate("minutes")) -cu:value("hours", translate("hours")) ---cu:value("days", translate("days")) -function cu.write(self, section, value) - -- remove when default - local secs = DDNS.calc_seconds(ci:formvalue(section), value) - if secs ~= 600 then --default 10 minutes - return self.map:set(section, self.option, value) - else - return true - end -end -function cu.parse(self, section, novld) - DDNS.value_parse(self, section, novld) -end - --- force_interval (modified) -- ############################################### -fi = ns:taboption("timer", Value, "force_interval", - translate("Force Interval") ) -fi.template = "ddns/detail_value" -fi.default = "72" -- see dynamic_dns_updater.sh script ---fi.rmempty = false -- validate ourselves for translatable error messages -function fi.validate(self, value) - if not DTYP.uinteger(value) - or tonumber(value) < 0 then - return nil, err_tab_timer(self) .. translate("minimum value '0'") - end - - local force_s = DDNS.calc_seconds(value, fu:formvalue(section)) - if force_s == 0 then - return value - end - - local ci_value = ci:formvalue(section) - if not DTYP.uinteger(ci_value) then - return "" -- ignore because error in check_interval above - end - - local check_s = DDNS.calc_seconds(ci_value, cu:formvalue(section)) - if force_s >= check_s then - return value - end - - return nil, err_tab_timer(self) .. translate("must be greater or equal 'Check Interval'") -end -function fi.write(self, section, value) - -- simulate rmempty=true remove default - local secs = DDNS.calc_seconds(value, fu:formvalue(section)) - if secs ~= 259200 then --default 72 hours == 3 days - return self.map:set(section, self.option, value) - else - self.map:del(section, "force_unit") - return self.map:del(section, self.option) - end -end -function fi.parse(self, section, novld) - DDNS.value_parse(self, section, novld) -end - --- force_unit -- ############################################################## -fu = ns:taboption("timer", ListValue, "force_unit", "not displayed, but needed otherwise error", - translate("Interval to force updates send to DDNS Provider" .. "
      " .. - "Setting this parameter to 0 will force the script to only run once" .. "
      " .. - "Values lower 'Check Interval' except '0' are not supported") ) -fu.template = "ddns/detail_lvalue" -fu.default = "hours" ---fu.rmempty = false -- want to control write process ---fu:value("seconds", translate("seconds")) -fu:value("minutes", translate("minutes")) -fu:value("hours", translate("hours")) -fu:value("days", translate("days")) -function fu.write(self, section, value) - -- simulate rmempty=true remove default - local secs = DDNS.calc_seconds(fi:formvalue(section), value) - if secs ~= 259200 and secs ~= 0 then --default 72 hours == 3 days - return self.map:set(section, self.option, value) - else - return true - end -end -function fu.parse(self, section, novld) - DDNS.value_parse(self, section, novld) -end - --- retry_count -- ############################################################# -rc = ns:taboption("timer", Value, "retry_count") -rc.title = translate("Error Retry Counter") -rc.description = translate("On Error the script will stop execution after given number of retrys") - .. "
      " - .. translate("The default setting of '0' will retry infinite.") -rc.default = "0" -function rc.validate(self, value) - if not DTYP.uinteger(value) then - return nil, err_tab_timer(self) .. translate("minimum value '0'") - else - return value - end -end -function rc.parse(self, section, novld) - DDNS.value_parse(self, section, novld) -end - --- retry_interval -- ########################################################## -ri = ns:taboption("timer", Value, "retry_interval", - translate("Error Retry Interval") ) -ri.template = "ddns/detail_value" -ri.default = "60" -function ri.validate(self, value) - if not DTYP.uinteger(value) - or tonumber(value) < 1 then - return nil, err_tab_timer(self) .. translate("minimum value '1'") - else - return value - end -end -function ri.write(self, section, value) - -- simulate rmempty=true remove default - local secs = DDNS.calc_seconds(value, ru:formvalue(section)) - if secs ~= 60 then --default 60seconds - return self.map:set(section, self.option, value) - else - self.map:del(section, "retry_unit") - return self.map:del(section, self.option) - end -end -function ri.parse(self, section, novld) - DDNS.value_parse(self, section, novld) -end - --- retry_unit -- ############################################################## -ru = ns:taboption("timer", ListValue, "retry_unit", "not displayed, but needed otherwise error", - translate("On Error the script will retry the failed action after given time") ) -ru.template = "ddns/detail_lvalue" -ru.default = "seconds" ---ru.rmempty = false -- want to control write process -ru:value("seconds", translate("seconds")) -ru:value("minutes", translate("minutes")) ---ru:value("hours", translate("hours")) ---ru:value("days", translate("days")) -function ru.write(self, section, value) - -- simulate rmempty=true remove default - local secs = DDNS.calc_seconds(ri:formvalue(section), value) - if secs ~= 60 then --default 60seconds - return self.map:set(section, self.option, value) - else - return true -- will be deleted by retry_interval - end -end -function ru.parse(self, section, novld) - DDNS.value_parse(self, section, novld) -end - --- TAB: LogView ################################################################################## -lv = ns:taboption("logview", DummyValue, "_logview") -lv.template = "ddns/detail_logview" -lv.inputtitle = translate("Read / Reread log file") -lv.rows = 50 -function lv.cfgvalue(self, section) - local lfile=logdir .. "/" .. section .. ".log" - if NXFS.access(lfile) then - return lfile .. "\n" .. translate("Please press [Read] button") - end - return lfile .. "\n" .. translate("File not found or empty") -end - -return m diff --git a/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/model/cbi/ddns/global.lua b/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/model/cbi/ddns/global.lua deleted file mode 100644 index 9dc0857..0000000 --- a/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/model/cbi/ddns/global.lua +++ /dev/null @@ -1,121 +0,0 @@ --- Copyright 2014 Christian Schoenebeck --- Licensed to the public under the Apache License 2.0. - -local NX = require "nixio" -local NXFS = require "nixio.fs" -local DISP = require "luci.dispatcher" -local SYS = require "luci.sys" -local CTRL = require "luci.controller.ddns" -- this application's controller -local DDNS = require "luci.tools.ddns" -- ddns multiused functions - --- cbi-map definition -- ####################################################### -local m = Map("ddns") -m.title = CTRL.app_title_back() -m.description = CTRL.app_description() -m.redirect = DISP.build_url("admin", "services", "ddns") - -function m.commit_handler(self) - if self.changed then -- changes ? - local command = CTRL.luci_helper .. " -- reload" - os.execute(command) -- reload configuration - end -end - --- cbi-section definition -- ################################################### -local ns = m:section( NamedSection, "global", "ddns", - translate("Global Settings"), - translate("Configure here the details for all Dynamic DNS services including this LuCI application.") - .. [[
      ]] - .. translate("It is NOT recommended for casual users to change settings on this page.") - .. [[
      ]] - .. [[]] - .. translate("For detailed information about parameter settings look here.") - .. [[]] - ) - --- section might not exist -function ns.cfgvalue(self, section) - if not self.map:get(section) then - self.map:set(section, nil, self.sectiontype) - end - return self.map:get(section) -end - --- upd_privateip -- ########################################################### -local ali = ns:option(Flag, "upd_privateip") -ali.title = translate("Allow non-public IP's") -ali.description = translate("Non-public and by default blocked IP's") .. ":" - .. [[
      IPv4: ]] - .. "0/8, 10/8, 100.64/10, 127/8, 169.254/16, 172.16/12, 192.168/16" - .. [[
      IPv6: ]] - .. "::/32, f000::/4" -ali.default = "0" - --- ddns_dateformat -- ######################################################### -local df = ns:option(Value, "ddns_dateformat") -df.title = translate("Date format") -df.description = [[]] - .. translate("For supported codes look here") - .. [[]] -df.template = "ddns/global_value" -df.default = "%F %R" -df.date_string = "" -function df.cfgvalue(self, section) - local value = AbstractValue.cfgvalue(self, section) or self.default - local epoch = os.time() - self.date_string = DDNS.epoch2date(epoch, value) - return value -end -function df.parse(self, section, novld) - DDNS.value_parse(self, section, novld) -end - --- ddns_rundir -- ############################################################# -local rd = ns:option(Value, "ddns_rundir") -rd.title = translate("Status directory") -rd.description = translate("Directory contains PID and other status information for each running section") -rd.default = "/var/run/ddns" --- no need to validate. if empty default is used everything else created by dns-scripts -function rd.parse(self, section, novld) - DDNS.value_parse(self, section, novld) -end - --- ddns_logdir -- ############################################################# -local ld = ns:option(Value, "ddns_logdir") -ld.title = translate("Log directory") -ld.description = translate("Directory contains Log files for each running section") -ld.default = "/var/log/ddns" --- no need to validate. if empty default is used everything else created by dns-scripts -function ld.parse(self, section, novld) - DDNS.value_parse(self, section, novld) -end - --- ddns_loglines -- ########################################################### -local ll = ns:option(Value, "ddns_loglines") -ll.title = translate("Log length") -ll.description = translate("Number of last lines stored in log files") -ll.default = "250" -function ll.validate(self, value) - local n = tonumber(value) - if not n or math.floor(n) ~= n or n < 1 then - return nil, self.title .. ": " .. translate("minimum value '1'") - end - return value -end -function ll.parse(self, section, novld) - DDNS.value_parse(self, section, novld) -end - --- use_curl -- ################################################################ -if (SYS.call([[ grep -i "\+ssl" /usr/bin/wget >/dev/null 2>&1 ]]) == 0) -and NXFS.access("/usr/bin/curl") then - local pc = ns:option(Flag, "use_curl") - pc.title = translate("Use cURL") - pc.description = translate("If both cURL and GNU Wget are installed, Wget is used by default.") - .. [[
      ]] - .. translate("To use cURL activate this option.") - pc.orientation = "horizontal" - pc.default = "0" -end - -return m diff --git a/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/model/cbi/ddns/hints.lua b/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/model/cbi/ddns/hints.lua deleted file mode 100644 index df39a3a..0000000 --- a/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/model/cbi/ddns/hints.lua +++ /dev/null @@ -1,166 +0,0 @@ --- Copyright 2014-2016 Christian Schoenebeck --- Licensed to the public under the Apache License 2.0. - -local DISP = require "luci.dispatcher" -local SYS = require "luci.sys" -local CTRL = require "luci.controller.ddns" -- this application's controller -local DDNS = require "luci.tools.ddns" -- ddns multiused functions - --- html constants -font_red = [[]] -font_off = [[]] -bold_on = [[]] -bold_off = [[]] - --- cbi-map definition -- ####################################################### -m = Map("ddns") -m.title = CTRL.app_title_back() -m.description = CTRL.app_description() -m.redirect = DISP.build_url("admin", "services", "ddns") - --- SimpleSection definition -- ################################################# --- show Hints to optimize installation and script usage -s = m:section( SimpleSection, - translate("Hints"), - translate("Below a list of configuration tips for your system to run Dynamic DNS updates without limitations") ) - --- ddns-scripts needs to be updated for full functionality -if not CTRL.service_ok() then - local so = s:option(DummyValue, "_update_needed") - so.titleref = DISP.build_url("admin", "system", "packages") - so.rawhtml = true - so.title = font_red .. bold_on .. - translate("Software update required") .. bold_off .. font_off - so.value = translate("The currently installed 'ddns-scripts' package did not support all available settings.") .. - "
      " .. - translate("Please update to the current version!") -end - --- DDNS Service disabled -if not SYS.init.enabled("ddns") then - local se = s:option(DummyValue, "_not_enabled") - se.titleref = DISP.build_url("admin", "system", "startup") - se.rawhtml = true - se.title = bold_on .. - translate("DDNS Autostart disabled") .. bold_off - se.value = translate("Currently DDNS updates are not started at boot or on interface events." .. "
      " .. - "This is the default if you run DDNS scripts by yourself (i.e. via cron with force_interval set to '0')" ) -end - --- No IPv6 support -if not DDNS.has_ipv6 then - local v6 = s:option(DummyValue, "_no_ipv6") - v6.titleref = 'http://www.openwrt.org" target="_blank' - v6.rawhtml = true - v6.title = bold_on .. - translate("IPv6 not supported") .. bold_off - v6.value = translate("IPv6 is currently not (fully) supported by this system" .. "
      " .. - "Please follow the instructions on OpenWrt's homepage to enable IPv6 support" .. "
      " .. - "or update your system to the latest OpenWrt Release") -end - --- No HTTPS support -if not DDNS.has_ssl then - local sl = s:option(DummyValue, "_no_https") - sl.titleref = DISP.build_url("admin", "system", "packages") - sl.rawhtml = true - sl.title = bold_on .. - translate("HTTPS not supported") .. bold_off - sl.value = translate("Neither GNU Wget with SSL nor cURL installed to support secure updates via HTTPS protocol.") .. - "
      - " .. - translate("You should install 'wget' or 'curl' or 'uclient-fetch' with 'libustream-*ssl' package.") .. - "
      - " .. - translate("In some versions cURL/libcurl in OpenWrt is compiled without proxy support.") -end - --- No bind_network -if not DDNS.has_bindnet then - local bn = s:option(DummyValue, "_no_bind_network") - bn.titleref = DISP.build_url("admin", "system", "packages") - bn.rawhtml = true - bn.title = bold_on .. - translate("Binding to a specific network not supported") .. bold_off - bn.value = translate("Neither GNU Wget with SSL nor cURL installed to select a network to use for communication.") .. - "
      - " .. - translate("You should install 'wget' or 'curl' package.") .. - "
      - " .. - translate("GNU Wget will use the IP of given network, cURL will use the physical interface.") .. - "
      - " .. - translate("In some versions cURL/libcurl in OpenWrt is compiled without proxy support.") -end - --- currently only cURL possibly without proxy support -if not DDNS.has_proxy then - local px = s:option(DummyValue, "_no_proxy") - px.titleref = DISP.build_url("admin", "system", "packages") - px.rawhtml = true - px.title = bold_on .. - translate("cURL without Proxy Support") .. bold_off - px.value = translate("cURL is installed, but libcurl was compiled without proxy support.") .. - "
      - " .. - translate("You should install 'wget' or 'uclient-fetch' package or replace libcurl.") .. - "
      - " .. - translate("In some versions cURL/libcurl in OpenWrt is compiled without proxy support.") -end - --- "Force IP Version not supported" -if not DDNS.has_forceip then - local fi = s:option(DummyValue, "_no_force_ip") - fi.titleref = DISP.build_url("admin", "system", "packages") - fi.rawhtml = true - fi.title = bold_on .. - translate("Force IP Version not supported") .. bold_off - local value = translate("BusyBox's nslookup and Wget do not support to specify " .. - "the IP version to use for communication with DDNS Provider!") - if not (DDNS.has_wgetssl or DDNS.has_curl or DDNS.has_fetch) then - value = value .. "
      - " .. - translate("You should install 'wget' or 'curl' or 'uclient-fetch' package.") - end - if not DDNS.has_bindhost then - value = value .. "
      - " .. - translate("You should install 'bind-host' or 'knot-host' or 'drill' package for DNS requests.") - end - fi.value = value -end - --- "DNS requests via TCP not supported" -if not DDNS.has_bindhost then - local dt = s:option(DummyValue, "_no_dnstcp") - dt.titleref = DISP.build_url("admin", "system", "packages") - dt.rawhtml = true - dt.title = bold_on .. - translate("DNS requests via TCP not supported") .. bold_off - dt.value = translate("BusyBox's nslookup and hostip do not support to specify to use TCP " .. - "instead of default UDP when requesting DNS server!") .. - "
      - " .. - translate("You should install 'bind-host' or 'knot-host' or 'drill' package for DNS requests.") -end - --- nslookup compiled with musl produce problems when using -if not DDNS.has_dnsserver then - local ds = s:option(DummyValue, "_no_dnsserver") - ds.titleref = DISP.build_url("admin", "system", "packages") - ds.rawhtml = true - ds.title = bold_on .. - translate("Using specific DNS Server not supported") .. bold_off - ds.value = translate("BusyBox's nslookup in the current compiled version " .. - "does not handle given DNS Servers correctly!") .. - "
      - " .. - translate("You should install 'bind-host' or 'knot-host' or 'drill' or 'hostip' package, " .. - "if you need to specify a DNS server to detect your registered IP.") -end - --- certificates installed -if DDNS.has_ssl and not DDNS.has_cacerts then - local ca = s:option(DummyValue, "_no_certs") - ca.titleref = DISP.build_url("admin", "system", "packages") - ca.rawhtml = true - ca.title = bold_on .. - translate("No certificates found") .. bold_off - ca.value = translate("If using secure communication you should verify server certificates!") .. - "
      - " .. - translate("Install 'ca-certificates' package or needed certificates " .. - "by hand into /etc/ssl/certs default directory") -end - -return m diff --git a/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/model/cbi/ddns/overview.lua b/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/model/cbi/ddns/overview.lua deleted file mode 100644 index 337c6e7..0000000 --- a/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/model/cbi/ddns/overview.lua +++ /dev/null @@ -1,219 +0,0 @@ --- Copyright 2014-2016 Christian Schoenebeck --- Licensed to the public under the Apache License 2.0. - -local NXFS = require "nixio.fs" -local DISP = require "luci.dispatcher" -local HTTP = require "luci.http" -local SYS = require "luci.sys" -local CTRL = require "luci.controller.ddns" -- this application's controller -local DDNS = require "luci.tools.ddns" -- ddns multiused functions - -local show_hints = not (DDNS.has_ipv6 -- IPv6 support - and DDNS.has_ssl -- HTTPS support - and DDNS.has_proxy -- Proxy support - and DDNS.has_bindhost -- DNS TCP support - and DDNS.has_forceip -- Force IP version - and DDNS.has_dnsserver -- DNS server support - and DDNS.has_bindnet -- Bind to network/interface - and DDNS.has_cacerts -- certificates installed at /etc/ssl/certs - ) -local not_enabled = not SYS.init.enabled("ddns") -local need_update = not CTRL.service_ok() - --- html constants -font_red = [[]] -font_off = [[]] -bold_on = [[]] -bold_off = [[]] - --- cbi-map definition -- ####################################################### -m = Map("ddns") -m.title = CTRL.app_title_main() -m.description = CTRL.app_description() - -m.on_after_commit = function(self) - if self.changed then -- changes ? - local command = CTRL.luci_helper - if SYS.init.enabled("ddns") then -- ddns service enabled, restart all - command = command .. " -- restart" - os.execute(command) - else -- ddns service disabled, send SIGHUP to running - command = command .. " -- reload" - os.execute(command) - end - end -end - --- SimpleSection definition -- ################################################## --- with all the JavaScripts we need for "a good Show" -a = m:section( SimpleSection ) -a.template = "ddns/overview_status" - --- SimpleSection definition -- ################################################# --- show Hints to optimize installation and script usage -if not_enabled then - - s = m:section( SimpleSection, translate("Hints") ) - - -- DDNS Service disabled - if not_enabled then - local dv = s:option(DummyValue, "_not_enabled") - dv.titleref = DISP.build_url("admin", "system", "startup") - dv.rawhtml = true - dv.title = bold_on .. - translate("DDNS Autostart disabled") .. bold_off - dv.value = translate("Currently DDNS updates are not started at boot or on interface events." .. "
      " .. - "You can start/stop each configuration here. It will run until next reboot.") - end - -end - -local_web="

       

       

      " - --- TableSection definition -- ################################################## -ts = m:section( TypedSection, "service", - translate("Overview"), - translate("Below is a list of DDNS configurations and their current state.") - .. "
      " - .. "
      " .. local_web ) -ts.sectionhead = translate("Configuration") -ts.template = "cbi/tblsection" -ts.addremove = true -ts.extedit = DISP.build_url("admin", "services", "ddns", "detail", "%s") -function ts.create(self, name) - AbstractSection.create(self, name) - HTTP.redirect( self.extedit:format(name) ) -end - --- Lookup_Host and registered IP -- ################################################# -dom = ts:option(DummyValue, "_lookupIP", - translate("Lookup Hostname") .. "
      " .. translate("Registered IP") ) -dom.template = "ddns/overview_doubleline" -function dom.set_one(self, section) - local lookup = self.map:get(section, "lookup_host") or "" - if lookup ~= "" then - return lookup - else - return [[]] .. translate("config error") .. [[]] - end -end -function dom.set_two(self, section) - local lookup_host = self.map:get(section, "lookup_host") or "" - if lookup_host == "" then return "" end - local dnsserver = self.map:get(section, "dnsserver") or "" - local use_ipv6 = tonumber(self.map:get(section, "use_ipv6") or 0) - local force_ipversion = tonumber(self.map:get(section, "force_ipversion") or 0) - local force_dnstcp = tonumber(self.map:get(section, "force_dnstcp") or 0) - local is_glue = tonumber(self.map:get(section, "is_glue") or 0) - local command = CTRL.luci_helper .. [[ -]] - if (use_ipv6 == 1) then command = command .. [[6]] end - if (force_ipversion == 1) then command = command .. [[f]] end - if (force_dnstcp == 1) then command = command .. [[t]] end - if (is_glue == 1) then command = command .. [[g]] end - command = command .. [[l ]] .. lookup_host - if (#dnsserver > 0) then command = command .. [[ -d ]] .. dnsserver end - command = command .. [[ -- get_registered_ip]] - local ip = SYS.exec(command) - if ip == "" then ip = translate("no data") end - return ip -end - --- enabled -ena = ts:option( Flag, "enabled", - translate("Enabled")) -ena.template = "ddns/overview_enabled" -ena.rmempty = false - --- show PID and next update -upd = ts:option( DummyValue, "_update", - translate("Last Update") .. "
      " .. translate("Next Update")) -upd.template = "ddns/overview_doubleline" -function upd.set_one(self, section) -- fill Last Update - -- get/validate last update - local uptime = SYS.uptime() - local lasttime = DDNS.get_lastupd(section) - if lasttime > uptime then -- /var might not be linked to /tmp and cleared on reboot - lasttime = 0 - end - - -- no last update happen - if lasttime == 0 then - return translate("never") - - -- we read last update - else - -- calc last update - -- os.epoch - sys.uptime + lastupdate(uptime) - local epoch = os.time() - uptime + lasttime - -- use linux date to convert epoch - return DDNS.epoch2date(epoch) - end -end -function upd.set_two(self, section) -- fill Next Update - -- get enabled state - local enabled = tonumber(self.map:get(section, "enabled") or 0) - local datenext = translate("unknown error") -- formatted date of next update - - -- get force seconds - local force_interval = tonumber(self.map:get(section, "force_interval") or 72) - local force_unit = self.map:get(section, "force_unit") or "hours" - local force_seconds = DDNS.calc_seconds(force_interval, force_unit) - - -- get last update and get/validate PID - local uptime = SYS.uptime() - local lasttime = DDNS.get_lastupd(section) - if lasttime > uptime then -- /var might not be linked to /tmp and cleared on reboot - lasttime = 0 - end - local pid = DDNS.get_pid(section) - - -- calc next update - if lasttime > 0 then - local epoch = os.time() - uptime + lasttime + force_seconds - -- use linux date to convert epoch - datelast = DDNS.epoch2date(epoch) - end - - -- process running but update needs to happen - if pid > 0 and ( lasttime + force_seconds - uptime ) < 0 then - datenext = translate("Verify") - - -- run once - elseif force_seconds == 0 then - datenext = translate("Run once") - - -- no process running and NOT enabled - elseif pid == 0 and enabled == 0 then - datenext = translate("Disabled") - - -- no process running and NOT - elseif pid == 0 and enabled ~= 0 then - datenext = translate("Stopped") - end - - return datenext -end - --- start/stop button -btn = ts:option( Button, "_startstop", - translate("Process ID") .. "
      " .. translate("Start / Stop") ) -btn.template = "ddns/overview_startstop" -function btn.cfgvalue(self, section) - local pid = DDNS.get_pid(section) - if pid > 0 then - btn.inputtitle = "PID: " .. pid - btn.inputstyle = "reset" - btn.disabled = false - elseif (self.map:get(section, "enabled") or "0") ~= "0" then - btn.inputtitle = translate("Start") - btn.inputstyle = "apply" - btn.disabled = false - else - btn.inputtitle = "----------" - btn.inputstyle = "button" - btn.disabled = true - end - return true -end - -return m diff --git a/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/tools/ddns.lua b/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/tools/ddns.lua deleted file mode 100644 index 209d9c3..0000000 --- a/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/tools/ddns.lua +++ /dev/null @@ -1,315 +0,0 @@ --- Copyright 2014-2016 Christian Schoenebeck --- Licensed to the public under the Apache License 2.0. - -module("luci.tools.ddns", package.seeall) - -local NX = require "nixio" -local NXFS = require "nixio.fs" -local OPKG = require "luci.model.ipkg" -local UCI = require "luci.model.uci" -local SYS = require "luci.sys" -local UTIL = require "luci.util" - -local function _check_certs() - local _, v = NXFS.glob("/etc/ssl/certs/*.crt") - if ( v == 0 ) then _, v = NXFS.glob("/etc/ssl/certs/*.pem") end - return (v > 0) -end - -has_wgetssl = (SYS.call( [[which wget-ssl >/dev/null 2>&1]] ) == 0) -- and true or nil -has_curl = (SYS.call( [[which curl >/dev/null 2>&1]] ) == 0) -has_curlssl = (SYS.call( [[$(which curl) -V 2>&1 | grep "Protocols:" | grep -qF "https"]] ) ~= 0) -has_curlpxy = (SYS.call( [[grep -i "all_proxy" /usr/lib/libcurl.so* >/dev/null 2>&1]] ) == 0) -has_fetch = (SYS.call( [[which uclient-fetch >/dev/null 2>&1]] ) == 0) -has_fetchssl = NXFS.access("/lib/libustream-ssl.so") -has_bbwget = (SYS.call( [[$(which wget) -V 2>&1 | grep -iqF "busybox"]] ) == 0) -has_bindhost = (SYS.call( [[which host >/dev/null 2>&1]] ) == 0) - or (SYS.call( [[which khost >/dev/null 2>&1]] ) == 0) - or (SYS.call( [[which drill >/dev/null 2>&1]] ) == 0) -has_hostip = (SYS.call( [[which hostip >/dev/null 2>&1]] ) == 0) -has_nslookup = (SYS.call( [[$(which nslookup) localhost 2>&1 | grep -qF "(null)"]] ) ~= 0) -has_ipv6 = (NXFS.access("/proc/net/ipv6_route") and NXFS.access("/usr/sbin/ip6tables")) -has_ssl = (has_wgetssl or has_curlssl or (has_fetch and has_fetchssl)) -has_proxy = (has_wgetssl or has_curlpxy or has_fetch or has_bbwget) -has_forceip = (has_wgetssl or has_curl or has_fetch) -- only really needed for transfer -has_dnsserver = (has_bindhost or has_hostip or has_nslookup) -has_bindnet = (has_wgetssl or has_curl) -has_cacerts = _check_certs() - --- function to calculate seconds from given interval and unit -function calc_seconds(interval, unit) - if not tonumber(interval) then - return nil - elseif unit == "days" then - return (tonumber(interval) * 86400) -- 60 sec * 60 min * 24 h - elseif unit == "hours" then - return (tonumber(interval) * 3600) -- 60 sec * 60 min - elseif unit == "minutes" then - return (tonumber(interval) * 60) -- 60 sec - elseif unit == "seconds" then - return tonumber(interval) - else - return nil - end -end - --- convert epoch date to given format -function epoch2date(epoch, format) - if not format or #format < 2 then - local uci = UCI.cursor() - format = uci:get("ddns", "global", "ddns_dateformat") or "%F %R" - uci:unload("ddns") - end - format = format:gsub("%%n", "
      ") -- replace newline - format = format:gsub("%%t", " ") -- replace tab - return os.date(format, epoch) -end - --- read lastupdate from [section].update file -function get_lastupd(section) - local uci = UCI.cursor() - local rdir = uci:get("ddns", "global", "ddns_rundir") or "/var/run/ddns" - local etime = tonumber(NXFS.readfile("%s/%s.update" % { rdir, section } ) or 0 ) - uci:unload("ddns") - return etime -end - --- read PID from run file and verify if still running -function get_pid(section) - local uci = UCI.cursor() - local rdir = uci:get("ddns", "global", "ddns_rundir") or "/var/run/ddns" - local pid = tonumber(NXFS.readfile("%s/%s.pid" % { rdir, section } ) or 0 ) - if pid > 0 and not NX.kill(pid, 0) then - pid = 0 - end - uci:unload("ddns") - return pid -end - --- replacement of build-in read of UCI option --- modified AbstractValue.cfgvalue(self, section) from cbi.lua --- needed to read from other option then current value definition -function read_value(self, section, option) - local value - if self.tag_error[section] then - value = self:formvalue(section) - else - value = self.map:get(section, option) - end - - if not value then - return nil - elseif not self.cast or self.cast == type(value) then - return value - elseif self.cast == "string" then - if type(value) == "table" then - return value[1] - end - elseif self.cast == "table" then - return { value } - end -end - --- replacement of build-in parse of "Value" --- modified AbstractValue.parse(self, section, novld) from cbi.lua --- validate is called if rmempty/optional true or false --- before write check if forcewrite, value eq default, and more -function value_parse(self, section, novld) - local fvalue = self:formvalue(section) - local fexist = ( fvalue and (#fvalue > 0) ) -- not "nil" and "not empty" - local cvalue = self:cfgvalue(section) - local rm_opt = ( self.rmempty or self.optional ) - local eq_cfg -- flag: equal cfgvalue - - -- If favlue and cvalue are both tables and have the same content - -- make them identical - if type(fvalue) == "table" and type(cvalue) == "table" then - eq_cfg = (#fvalue == #cvalue) - if eq_cfg then - for i=1, #fvalue do - if cvalue[i] ~= fvalue[i] then - eq_cfg = false - end - end - end - if eq_cfg then - fvalue = cvalue - end - end - - -- removed parameter "section" from function call because used/accepted nowhere - -- also removed call to function "transfer" - local vvalue, errtxt = self:validate(fvalue) - - -- error handling; validate return "nil" - if not vvalue then - if novld then -- and "novld" set - return -- then exit without raising an error - end - - if fexist then -- and there is a formvalue - self:add_error(section, "invalid", errtxt or self.title .. ": invalid") - return -- so data are invalid - elseif not rm_opt then -- and empty formvalue but NOT (rmempty or optional) set - self:add_error(section, "missing", errtxt or self.title .. ": missing") - return -- so data is missing - elseif errtxt then - self:add_error(section, "invalid", errtxt) - return - end --- error ("\n option: " .. self.option .. --- "\n fvalue: " .. tostring(fvalue) .. --- "\n fexist: " .. tostring(fexist) .. --- "\n cvalue: " .. tostring(cvalue) .. --- "\n vvalue: " .. tostring(vvalue) .. --- "\n vexist: " .. tostring(vexist) .. --- "\n rm_opt: " .. tostring(rm_opt) .. --- "\n eq_cfg: " .. tostring(eq_cfg) .. --- "\n eq_def: " .. tostring(eq_def) .. --- "\n novld : " .. tostring(novld) .. --- "\n errtxt: " .. tostring(errtxt) ) - end - - -- lets continue with value returned from validate - eq_cfg = ( vvalue == cvalue ) -- update equal_config flag - local vexist = ( vvalue and (#vvalue > 0) ) and true or false -- not "nil" and "not empty" - local eq_def = ( vvalue == self.default ) -- equal_default flag - - -- (rmempty or optional) and (no data or equal_default) - if rm_opt and (not vexist or eq_def) then - if self:remove(section) then -- remove data from UCI - self.section.changed = true -- and push events - end - return - end - - -- not forcewrite and no changes, so nothing to write - if not self.forcewrite and eq_cfg then - return - end - - -- we should have a valid value here - assert (vvalue, "\n option: " .. self.option .. - "\n fvalue: " .. tostring(fvalue) .. - "\n fexist: " .. tostring(fexist) .. - "\n cvalue: " .. tostring(cvalue) .. - "\n vvalue: " .. tostring(vvalue) .. - "\n vexist: " .. tostring(vexist) .. - "\n rm_opt: " .. tostring(rm_opt) .. - "\n eq_cfg: " .. tostring(eq_cfg) .. - "\n eq_def: " .. tostring(eq_def) .. - "\n errtxt: " .. tostring(errtxt) ) - - -- write data to UCI; raise event only on changes - if self:write(section, vvalue) and not eq_cfg then - self.section.changed = true - end -end - ------------------------------------------------------------------------------ --- copied from https://svn.nmap.org/nmap/nselib/url.lua --- @author Diego Nehab --- @author Eddie Bell ---[[ - URI parsing, composition and relative URL resolution - LuaSocket toolkit. - Author: Diego Nehab - RCS ID: $Id: url.lua,v 1.37 2005/11/22 08:33:29 diego Exp $ - parse_query and build_query added For nmap (Eddie Bell ) -]]-- ---- --- Parses a URL and returns a table with all its parts according to RFC 2396. --- --- The following grammar describes the names given to the URL parts. --- --- ::= :///;?# --- ::= @: --- ::= [:] --- :: = {/} --- --- --- The leading / in / is considered part of --- . --- @param url URL of request. --- @param default Table with default values for each field. --- @return A table with the following fields, where RFC naming conventions have --- been preserved: --- scheme, authority, userinfo, --- user, password, host, --- port, path, params, --- query, and fragment. ------------------------------------------------------------------------------ -function parse_url(url) --, default) - -- initialize default parameters - local parsed = {} --- for i,v in base.pairs(default or parsed) do --- parsed[i] = v --- end - - -- remove whitespace --- url = string.gsub(url, "%s", "") - -- get fragment - url = string.gsub(url, "#(.*)$", - function(f) - parsed.fragment = f - return "" - end) - -- get scheme. Lower-case according to RFC 3986 section 3.1. - url = string.gsub(url, "^([%w][%w%+%-%.]*)%:", - function(s) - parsed.scheme = string.lower(s); - return "" - end) - -- get authority - url = string.gsub(url, "^//([^/]*)", - function(n) - parsed.authority = n - return "" - end) - -- get query stringing - url = string.gsub(url, "%?(.*)", - function(q) - parsed.query = q - return "" - end) - -- get params - url = string.gsub(url, "%;(.*)", - function(p) - parsed.params = p - return "" - end) - -- path is whatever was left - parsed.path = url - - local authority = parsed.authority - if not authority then - return parsed - end - authority = string.gsub(authority,"^([^@]*)@", - function(u) - parsed.userinfo = u; - return "" - end) - authority = string.gsub(authority, ":([0-9]*)$", - function(p) - if p ~= "" then - parsed.port = p - end; - return "" - end) - if authority ~= "" then - parsed.host = authority - end - - local userinfo = parsed.userinfo - if not userinfo then - return parsed - end - userinfo = string.gsub(userinfo, ":([^:]*)$", - function(p) - parsed.password = p; - return "" - end) - parsed.user = userinfo - return parsed -end diff --git a/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/view/admin_status/index/ddns.htm b/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/view/admin_status/index/ddns.htm deleted file mode 100644 index 9791065..0000000 --- a/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/view/admin_status/index/ddns.htm +++ /dev/null @@ -1 +0,0 @@ -<%+ddns/system_status%> diff --git a/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/view/ddns/detail_logview.htm b/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/view/ddns/detail_logview.htm deleted file mode 100644 index fd1d5be..0000000 --- a/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/view/ddns/detail_logview.htm +++ /dev/null @@ -1,56 +0,0 @@ - - - - -<%+cbi/valueheader%> - -
      - -<% --- one button on top, one at the buttom -%> - /> - -

      - -<% --- set a readable style taken from openwrt theme for textarea#syslog --- in openwrt theme there are problems with a width of 100 so we check for theme and set to lower value -%> - -

      - -<% --- one button on top, one at the buttom -%> - /> - -<%+cbi/valuefooter%> - diff --git a/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/view/ddns/detail_lvalue.htm b/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/view/ddns/detail_lvalue.htm deleted file mode 100644 index b69d780..0000000 --- a/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/view/ddns/detail_lvalue.htm +++ /dev/null @@ -1,23 +0,0 @@ - - - -  -<% if self.widget == "select" then %> - -<% elseif self.widget == "radio" then - local c = 0 - for i, key in pairs(self.keylist) do - c = c + 1 -%> - /> - > - ><%=self.vallist[i]%> -<% if c == self.size then c = 0 %><% if self.orientation == "horizontal" then %> <% else %>
      <% end %> -<% end end %> -<% end %> -<%+cbi/valuefooter%> - diff --git a/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/view/ddns/detail_value.htm b/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/view/ddns/detail_value.htm deleted file mode 100644 index cbe76ab..0000000 --- a/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/view/ddns/detail_value.htm +++ /dev/null @@ -1,9 +0,0 @@ - - -<%+cbi/valueheader%> - /> - - diff --git a/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/view/ddns/global_value.htm b/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/view/ddns/global_value.htm deleted file mode 100644 index 23ec059..0000000 --- a/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/view/ddns/global_value.htm +++ /dev/null @@ -1,34 +0,0 @@ - - -<%+cbi/valueheader%> - - - -/> -
      -
      - <%:help%><%=self.description%> -
      - <%:Current setting%>: <%=self.date_string%> -
      -
      - - diff --git a/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/view/ddns/overview_doubleline.htm b/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/view/ddns/overview_doubleline.htm deleted file mode 100644 index 1d1b4be..0000000 --- a/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/view/ddns/overview_doubleline.htm +++ /dev/null @@ -1,10 +0,0 @@ - - -<%+cbi/valueheader%> - -<%=self:set_one(section)%> -
      -<%=self:set_two(section)%> - -<%+cbi/valuefooter%> - diff --git a/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/view/ddns/overview_enabled.htm b/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/view/ddns/overview_enabled.htm deleted file mode 100644 index 2efc125..0000000 --- a/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/view/ddns/overview_enabled.htm +++ /dev/null @@ -1,16 +0,0 @@ - - -<%+cbi/valueheader%> - - /> - - /> -> - -<%+cbi/valuefooter%> - diff --git a/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/view/ddns/overview_startstop.htm b/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/view/ddns/overview_startstop.htm deleted file mode 100644 index 327028c..0000000 --- a/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/view/ddns/overview_startstop.htm +++ /dev/null @@ -1,17 +0,0 @@ - - -<%+cbi/valueheader%> - -<% if self:cfgvalue(section) ~= false then --- We need to garantie that function cfgvalue run first to set missing parameters -%> - - - " style="font-size: 100%;" type="button" onclick="onclick_startstop(this.id)" - <%= - attr("name", section) .. attr("id", cbid) .. attr("value", self.inputtitle) .. ifattr(self.disabled, "disabled") - %> /> -<% end %> - -<%+cbi/valuefooter%> - diff --git a/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/view/ddns/overview_status.htm b/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/view/ddns/overview_status.htm deleted file mode 100644 index b409ed0..0000000 --- a/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/view/ddns/overview_status.htm +++ /dev/null @@ -1,180 +0,0 @@ - - - - - - diff --git a/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/view/ddns/system_status.htm b/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/view/ddns/system_status.htm deleted file mode 100644 index 5bdcb03..0000000 --- a/rooter/0optionalapps/luci-app-rooterddns/files/usr/lib/lua/luci/view/ddns/system_status.htm +++ /dev/null @@ -1,144 +0,0 @@ - - - - -
      - <%:Dynamic DNS%> - - - - - - - - - - - - -
      <%:Configuration%><%:Next Update%><%:Lookup Hostname%><%:Registered IP%><%:Network%>

      <%:Collecting data...%>
      -
      - diff --git a/rooter/0optionalapps/luci-app-rootervpn/files/usr/lib/lua/luci/view/easyrsa/easyrsa.htm b/rooter/0optionalapps/luci-app-rootervpn/files/usr/lib/lua/luci/view/easyrsa/easyrsa.htm index 25fe654..998a866 100644 --- a/rooter/0optionalapps/luci-app-rootervpn/files/usr/lib/lua/luci/view/easyrsa/easyrsa.htm +++ b/rooter/0optionalapps/luci-app-rootervpn/files/usr/lib/lua/luci/view/easyrsa/easyrsa.htm @@ -46,22 +46,22 @@ if (parseInt(status) > 1) { indx = 1; - select.options[select.options.length] = new Option("Generating RSA Private Server key", indx); + select.options[select.options.length] = new Option("<%:Generating RSA Private Server key%>", indx); } if (parseInt(status) > 2) { indx = 2; - select.options[select.options.length] = new Option("Generating RSA Private Client key", indx); + select.options[select.options.length] = new Option("<%:Generating RSA Private Client key%>", indx); } if (parseInt(status) > 3) { indx = 3; - select.options[select.options.length] = new Option("Create the Diffie-Hellman parameters", indx); + select.options[select.options.length] = new Option("<%:Create the Diffie-Hellman parameters%>", indx); } if (parseInt(status) > 4) { indx = 4; - select.options[select.options.length] = new Option("Finished", indx); + select.options[select.options.length] = new Option("<%:Finished%>", indx); } if (parseInt(status) != 0) { @@ -102,7 +102,7 @@ genrate = "1"; clearListBox("status"); select = document.getElementById("status"); - select.options[select.options.length] = new Option("Starting Key Generation Process", 0); + select.options[select.options.length] = new Option("<%:Starting Key Generation Process%>", 0); XHR.get('<%=luci.dispatcher.build_url("admin", "vpn", "rsagenerate")%>', null, function(x, rv) diff --git a/rooter/0optionalapps/nft-qos/Makefile b/rooter/0optionalapps/nft-qos/Makefile deleted file mode 100644 index 78e0ec2..0000000 --- a/rooter/0optionalapps/nft-qos/Makefile +++ /dev/null @@ -1,59 +0,0 @@ -# -# Copyright (C) 2018 rosysong@rosinson.com -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - -include $(TOPDIR)/rules.mk - -PKG_NAME:=nft-qos -PKG_VERSION:=1.0.6 -PKG_RELEASE:=1 -PKG_LICENSE:=GPL-2.0 - -PKG_MAINTAINER:=Rosy Song - -PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) - -include $(INCLUDE_DIR)/package.mk - -define Package/nft-qos - SECTION:=utils - CATEGORY:=Base system - DEPENDS:=+nftables +kmod-nft-netdev +kmod-nft-bridge - TITLE:=QoS scripts over nftables - PKGARCH:=all -endef - -define Package/nft-qos/description - This package provides implementation for qos over nftables. - Currently, static/dynamic qos and traffic shaping are supported. -endef - -define Package/nft-qos/conffiles -/etc/config/nft-qos -endef - -define Build/Prepare -endef - -define Build/Configure -endef - -define Build/Compile -endef - -define Package/nft-qos/install - $(INSTALL_DIR) $(1)/lib/nft-qos - $(INSTALL_DATA) ./files/lib/* $(1)/lib/nft-qos/ - $(INSTALL_DIR) $(1)/etc/config - $(INSTALL_CONF) ./files/nft-qos.config $(1)/etc/config/nft-qos - $(INSTALL_DIR) $(1)/etc/init.d - $(INSTALL_BIN) ./files/nft-qos.init $(1)/etc/init.d/nft-qos - $(INSTALL_DIR) $(1)/etc/hotplug.d/dhcp - $(INSTALL_BIN) ./files/nft-qos-monitor.hotplug $(1)/etc/hotplug.d/dhcp/00-nft-qos-monitor - $(INSTALL_BIN) ./files/nft-qos-dynamic.hotplug $(1)/etc/hotplug.d/dhcp/01-nft-qos-dynamic -endef - -$(eval $(call BuildPackage,nft-qos)) diff --git a/rooter/0optionalapps/nft-qos/files/lib/core.sh b/rooter/0optionalapps/nft-qos/files/lib/core.sh deleted file mode 100644 index d3c9d64..0000000 --- a/rooter/0optionalapps/nft-qos/files/lib/core.sh +++ /dev/null @@ -1,93 +0,0 @@ -#!/bin/sh -# -# Copyright (C) 2018 rosysong@rosinson.com -# - -# for uci_validate_section() -. /lib/functions/procd.sh - -NFT_QOS_HAS_BRIDGE= -NFT_QOS_INET_FAMILY=ip -NFT_QOS_SCRIPT_TEXT= -NFT_QOS_SCRIPT_FILE=/tmp/qos.nft - -qosdef_appendx() { # - NFT_QOS_SCRIPT_TEXT="$NFT_QOS_SCRIPT_TEXT""$1" -} - -qosdef_append_chain_def() { # - qosdef_appendx "\t\ttype $1 hook $2 priority $3; policy $4;\n" -} - -qosdef_append_chain_ingress() { # - qosdef_appendx "\t\ttype $1 hook ingress device $2 priority $3; policy $4;\n" -} - -# qosdef_append_rule_{MATCH}_{STATEMENT} -qosdef_append_rule_ip_limit() { # - local ipaddr=$1 - local operator=$2 - local unit=$3 - local rate=$4 - - qosdef_appendx \ - "\t\tip $operator $ipaddr limit rate over $rate $unit/second drop\n" -} - -# qosdef_append_rule_{MATCH}_{POLICY} -qosdef_append_rule_ip_policy() { # - qosdef_appendx "\t\tip $1 $2 $3\n" -} - -_handle_limit_whitelist() { # - local ipaddr=$1 - local operator - - [ -z "$ipaddr" ] && return - - case "$2" in - download) operator="daddr";; - upload) operator="saddr";; - esac - - qosdef_append_rule_ip_policy $operator $ipaddr accept -} - -qosdef_append_rule_limit_whitelist() { # - config_list_foreach default limit_whitelist _handle_limit_whitelist $1 -} - -qosdef_flush_table() { # - nft flush table $1 $2 2>/dev/null -} - -qosdef_remove_table() { #
      - nft delete table $1 $2 2>/dev/null -} - -qosdef_init_header() { # add header for nft script - qosdef_appendx "#!/usr/sbin/nft -f\n" - qosdef_appendx "# Copyright (C) 2018 rosysong@rosinson.com\n" - qosdef_appendx "#\n\n" -} - -qosdef_init_env() { - # check interface type of lan - local lt="$(uci_get "network.lan.type")" - [ "$lt" = "bridge" ] && export NFT_QOS_HAS_BRIDGE="y" - - # check if ipv6 support - [ -e /proc/sys/net/ipv6 ] && export NFT_QOS_INET_FAMILY="inet" -} - -qosdef_clean_cache() { - rm -f $NFT_QOS_SCRIPT_FILE -} - -qosdef_init_done() { - echo -e $NFT_QOS_SCRIPT_TEXT > $NFT_QOS_SCRIPT_FILE 2>/dev/null -} - -qosdef_start() { - nft -f $NFT_QOS_SCRIPT_FILE 2>/dev/null -} diff --git a/rooter/0optionalapps/nft-qos/files/lib/dynamic.sh b/rooter/0optionalapps/nft-qos/files/lib/dynamic.sh deleted file mode 100644 index 207daca..0000000 --- a/rooter/0optionalapps/nft-qos/files/lib/dynamic.sh +++ /dev/null @@ -1,90 +0,0 @@ -#!/bin/sh -# -# Copyright (C) 2018 rosysong@rosinson.com -# - -. /lib/nft-qos/core.sh - -qosdef_validate_dynamic() { - uci_load_validate nft-qos default "$1" "$2" \ - 'limit_enable:bool:0' \ - 'limit_type:maxlength(8)' \ - 'dynamic_bw_up:uinteger:100' \ - 'dynamic_bw_down:uinteger:100' -} - -# return average rate for dhcp leases -qosdef_dynamic_rate() { # - local c=0 c6=0 - - [ ! -e /tmp/dhcp.leases -a \ - ! -e /var/dhcp6.leases ] && return - - [ -e /tmp/dhcp.leases ] && \ - c=$(wc -l < /tmp/dhcp.leases 2>/dev/null) - [ -e /var/dhcp6.leases ] && \ - c6=$(wc -l < /var/dhcp6.leases 2>/dev/null) - [ $c -eq 0 -a $c6 -eq 0 ] && \ - { echo 12500; return; } - - echo $(($1 / ($c + $c6))) -} - -qosdef_append_chain_dym() { # - local cidr cidr6 - local operator rate - local hook=$1 name=$2 bandwidth=$3 - - config_get cidr default 'dynamic_cidr' - config_get cidr6 default 'dynamic_cidr6' - - [ -z "$cidr" -a -z "$cidr6" ] && return - - case "$2" in - download) operator=daddr;; - upload) operator=saddr;; - esac - - rate=$(qosdef_dynamic_rate $bandwidth) - - qosdef_appendx "\tchain $name {\n" - qosdef_append_chain_def filter $hook 0 accept - qosdef_append_rule_limit_whitelist $name - [ -n "$cidr" ] && \ - qosdef_append_rule_ip_limit $cidr $operator kbytes $rate - [ -n "$cidr6" ] && \ - qosdef_append_rule_ip_limit $cidr6 $operator kbytes $rate - qosdef_appendx "\t}\n" -} - -qosdef_flush_dynamic() { - qosdef_flush_table "$NFT_QOS_INET_FAMILY" nft-qos-dynamic -} - -# init dynamic qos -qosdef_init_dynamic() { - local hook_ul="prerouting" hook_dl="postrouting" - - [ "$2" = 0 ] || { - logger -t nft-qos-dynamic "validation failed" - return 1 - } - - [ $limit_enable -eq 0 -o \ - "$limit_type" = "static" ] && return 1 - - # Transfer mbits/s to mbytes/s - # e.g. 100,000 kbits == 12,500 kbytes - dynamic_bw_up=$(($dynamic_bw_up * 1000 / 8)) - dynamic_bw_down=$(($dynamic_bw_down * 1000 / 8)) - - [ -z "$NFT_QOS_HAS_BRIDGE" ] && { - hook_ul="postrouting" - hook_dl="prerouting" - } - - qosdef_appendx "table $NFT_QOS_INET_FAMILY nft-qos-dynamic {\n" - qosdef_append_chain_dym $hook_ul upload $dynamic_bw_up - qosdef_append_chain_dym $hook_dl download $dynamic_bw_down - qosdef_appendx "}\n" -} diff --git a/rooter/0optionalapps/nft-qos/files/lib/monitor.sh b/rooter/0optionalapps/nft-qos/files/lib/monitor.sh deleted file mode 100644 index 54de88e..0000000 --- a/rooter/0optionalapps/nft-qos/files/lib/monitor.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/sh -# -# Copyright (C) 2018 rosysong@rosinson.com -# - -. /lib/nft-qos/core.sh - -qosdef_monitor_get_ip_handle() { # - echo $(nft list chain $1 nft-qos-monitor $2 -a 2>/dev/null | grep $3 | awk '{print $11}') -} - -qosdef_monitor_add() { # - handle_dl=$(qosdef_monitor_get_ip_handle $NFT_QOS_INET_FAMILY download $2) - [ -z "$handle_dl" ] && nft add rule $NFT_QOS_INET_FAMILY nft-qos-monitor download ip daddr $2 counter - handle_ul=$(qosdef_monitor_get_ip_handle $NFT_QOS_INET_FAMILY upload $2) - [ -z "$handle_ul" ] && nft add rule $NFT_QOS_INET_FAMILY nft-qos-monitor upload ip saddr $2 counter -} - -qosdef_monitor_del() { # - local handle_dl handle_ul - handle_dl=$(qosdef_monitor_get_ip_handle $NFT_QOS_INET_FAMILY download $2) - handle_ul=$(qosdef_monitor_get_ip_handle $NFT_QOS_INET_FAMILY upload $2) - [ -n "$handle_dl" ] && nft delete handle $handle_dl - [ -n "$handle_ul" ] && nft delete handle $handle_ul -} - -# init qos monitor -qosdef_init_monitor() { - local hook_ul="prerouting" hook_dl="postrouting" - - [ -z "$NFT_QOS_HAS_BRIDGE" ] && { - hook_ul="postrouting" - hook_dl="prerouting" - } - - nft add table $NFT_QOS_INET_FAMILY nft-qos-monitor - nft add chain $NFT_QOS_INET_FAMILY nft-qos-monitor upload { type filter hook $hook_ul priority 0\; } - nft add chain $NFT_QOS_INET_FAMILY nft-qos-monitor download { type filter hook $hook_dl priority 0\; } -} diff --git a/rooter/0optionalapps/nft-qos/files/lib/priority.sh b/rooter/0optionalapps/nft-qos/files/lib/priority.sh deleted file mode 100644 index 081b13f..0000000 --- a/rooter/0optionalapps/nft-qos/files/lib/priority.sh +++ /dev/null @@ -1,93 +0,0 @@ -#!/bin/sh -# -# Copyright (C) 2018 rosysong@rosinson.com -# - -. /lib/functions/network.sh -. /lib/nft-qos/core.sh - -P1=""; P2=""; P3=""; P4=""; P5=""; P6=""; -P7=""; P8=""; P9=""; P10=""; P11=""; - -qosdef_validate_priority() { - uci_load_validate nft-qos default "$1" "$2" \ - 'priority_enable:bool:0' \ - 'priority_netdev:maxlength(8)' -} - -_qosdef_handle_protox() { # - case "$1" in - -400) P1="$P1""$2";; - -300) P2="$P2""$2";; - -225) P3="$P3""$2";; - -200) P4="$P4""$2";; - -150) P5="$P5""$2";; - -100) P6="$P6""$2";; - 0) P7="$P7""$2";; - 50) P8="$P8""$2";; - 100) P9="$P9""$2";; - 225) P10="$P10""$2";; - 300) P11="$P11""$2";; - esac -} - -qosdef_handle_protox() { #
      - local proto prio srv - - config_get proto $1 'protocol' - config_get prio $1 'priority' - config_get srv $1 'service' - - [ -z "$proto" -o \ - -z "$prio" -o \ - -z "$srv" ] && return - - _qosdef_handle_protox $prio \ - "\t\t$proto dport { $srv } accept\n" -} - -qosdef_append_rule_protox() { #
      - config_foreach qosdef_handle_protox $1 - qosdef_appendx \ - "${P1}${P2}${P3}${P4}${P5}${P6}${P7}${P8}${P9}${P10}${P11}" -} - -qosdef_append_chain_priority() { #
      - local name=$1 device=$3 - - qosdef_appendx "\tchain $name {\n" - qosdef_append_chain_ingress filter $device 0 accept - qosdef_append_rule_protox $2 - qosdef_appendx "\t}\n" -} - -qosdef_remove_priority() { - qosdef_remove_table netdev nft-qos-priority -} - -# init traffic priority -qosdef_init_priority() { - local ifname="br-lan" - - [ "$2" = 0 ] || { - logger -t nft-qos-priority "validation failed" - return 1 - } - - [ $priority_enable -eq 0 ] && return 1 - - case "$priority_netdev" in - lan) [ "$(uci_get network.lan.type)" != "bridge" ] && { - network_get_device ifname "$priority_netdev" || \ - ifname="$(uci_get network.lan.ifname)" - } - ;; - wan*) network_get_device ifname "$priority_netdev" || \ - ifname="$(uci_get network.$priority_netdev.ifname)" - ;; - esac - - qosdef_appendx "table netdev nft-qos-priority {\n" - qosdef_append_chain_priority filter priority $ifname - qosdef_appendx "}\n" -} diff --git a/rooter/0optionalapps/nft-qos/files/lib/static.sh b/rooter/0optionalapps/nft-qos/files/lib/static.sh deleted file mode 100644 index 051c0ba..0000000 --- a/rooter/0optionalapps/nft-qos/files/lib/static.sh +++ /dev/null @@ -1,74 +0,0 @@ -#!/bin/sh -# -# Copyright (C) 2018 rosysong@rosinson.com -# - -. /lib/nft-qos/core.sh - -qosdef_validate_static() { - uci_load_validate nft-qos default "$1" "$2" \ - 'limit_enable:bool:0' \ - 'limit_type:maxlength(8)' \ - 'static_unit_dl:string:kbytes' \ - 'static_unit_ul:string:kbytes' \ - 'static_rate_dl:uinteger:50' \ - 'static_rate_ul:uinteger:50' -} - -# append rule for static qos -qosdef_append_rule_sta() { #
      - local ipaddr unit rate - local operator=$2 - - config_get ipaddr $1 ipaddr - config_get unit $1 unit $3 - config_get rate $1 rate $4 - - [ -z "$ipaddr" ] && return - - qosdef_append_rule_ip_limit $ipaddr $operator $unit $rate -} - -# append chain for static qos -qosdef_append_chain_sta() { #
      - local hook=$1 name=$2 - local config=$3 operator - - case "$name" in - download) operator="daddr";; - upload) operator="saddr";; - esac - - qosdef_appendx "\tchain $name {\n" - qosdef_append_chain_def filter $hook 0 accept - qosdef_append_rule_limit_whitelist $name - config_foreach qosdef_append_rule_sta $config $operator $4 $5 - qosdef_appendx "\t}\n" -} - -qosdef_flush_static() { - qosdef_flush_table "$NFT_QOS_INET_FAMILY" nft-qos-static -} - -# static limit rate init -qosdef_init_static() { - local hook_ul="prerouting" hook_dl="postrouting" - - [ "$2" = 0 ] || { - logger -t nft-qos-static "validation failed" - return 1 - } - - [ $limit_enable -eq 0 -o \ - $limit_type = "dynamic" ] && return 1 - - [ -z "$NFT_QOS_HAS_BRIDGE" ] && { - hook_ul="postrouting" - hook_dl="prerouting" - } - - qosdef_appendx "table $NFT_QOS_INET_FAMILY nft-qos-static {\n" - qosdef_append_chain_sta $hook_ul upload upload $static_unit_ul $static_rate_ul - qosdef_append_chain_sta $hook_dl download download $static_unit_dl $static_rate_dl - qosdef_appendx "}\n" -} diff --git a/rooter/0optionalapps/nft-qos/files/nft-qos-dynamic.hotplug b/rooter/0optionalapps/nft-qos/files/nft-qos-dynamic.hotplug deleted file mode 100644 index b81fa94..0000000 --- a/rooter/0optionalapps/nft-qos/files/nft-qos-dynamic.hotplug +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/sh -# -# Copyright 2018 rosysong@rosinson.com -# - -export initscript="nft-qos-dynamic" - -. /lib/functions.sh -. /lib/nft-qos/core.sh -. /lib/nft-qos/dynamic.sh - -NFT_QOS_DYNAMIC_ON= - -qosdef_check_if_dynamic() { - [ $limit_enable -eq 1 -a \ - "$limit_type" = "dynamic" ] && \ - NFT_QOS_DYNAMIC_ON="y" -} - - -logger -t nft-qos-dynamic "ACTION=$ACTION, MACADDR=$MACADDR, IPADDR=$IPADDR, HOSTNAME=$HOSTNAME" - -case "$ACTION" in - add | update | remove) - qosdef_validate_dynamic default qosdef_check_if_dynamic - [ -z "$NFT_QOS_DYNAMIC_ON" ] && return - - qosdef_init_env - qosdef_flush_dynamic - - qosdef_init_header - qosdef_validate_dynamic default qosdef_init_dynamic - qosdef_init_done - qosdef_start - ;; -esac diff --git a/rooter/0optionalapps/nft-qos/files/nft-qos-monitor.hotplug b/rooter/0optionalapps/nft-qos/files/nft-qos-monitor.hotplug deleted file mode 100644 index 5868bb1..0000000 --- a/rooter/0optionalapps/nft-qos/files/nft-qos-monitor.hotplug +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/sh -# -# Copyright 2018 rosysong@rosinson.com -# - -export initscript="nft-qos-monitor" - -. /lib/nft-qos/monitor.sh - -logger -t nft-qos-monitor "ACTION=$ACTION, MACADDR=$MACADDR, IPADDR=$IPADDR, HOSTNAME=$HOSTNAME" - -case "$ACTION" in - add | update) - qosdef_init_env - qosdef_init_monitor - qosdef_monitor_add $MACADDR $IPADDR $HOSTNAME - ;; - remove) - qosdef_init_env - qosdef_init_monitor - qosdef_monitor_del $MACADDR $IPADDR $HOSTNAME - ;; -esac diff --git a/rooter/0optionalapps/nft-qos/files/nft-qos.config b/rooter/0optionalapps/nft-qos/files/nft-qos.config deleted file mode 100644 index 82e3b39..0000000 --- a/rooter/0optionalapps/nft-qos/files/nft-qos.config +++ /dev/null @@ -1,107 +0,0 @@ -# -# Copyright (C) 2018 rosysong@rosinson.com -# -# This is the sample for nft-qos configuration file, -# which will generate a nftables script in /tmp/qos.nft -# - -# Getting Started -# Official site : -# https://netfilter.org/projects/nftables/index.html -# What is nftables : -# https://wiki.nftables.org/wiki-nftables/index.php/Main_Page -# - -# Basic Operations -# Configuring Tables : -# https://wiki.nftables.org/wiki-nftables/index.php/Configuring_tables -# Configuring Chains : -# https://wiki.nftables.org/wiki-nftables/index.php/Configuring_chains -# Configuring Rules : -# https://wiki.nftables.org/wiki-nftables/index.php/Simple_rule_management -# Quick Reference (recommended) : -# https://wiki.nftables.org/wiki-nftables/index.php/Quick_reference-nftables_in_10_minutes -# https://netfilter.org/projects/nftables/manpage.html -# - -config default default - # Enable Flag for limit rate - option limit_enable '1' - - # Options for enable Static QoS (rate limit) - option limit_type 'static' - # Options for Static QoS (rate limit) - option static_unit_dl 'kbytes' - option static_unit_ul 'kbytes' - option static_rate_dl '50' - option static_rate_ul '50' - - # Options for enable Dynamic QoS - # This option can not compatible with Static QoS - # option limit_type 'dynamic' - - # For Dynamic QoS Samples (unit of bandwidth is Mbps): - option dynamic_cidr '192.168.1.0/24' - option dynamic_cidr6 'AAAA:BBBB::1/64' - option dynamic_bw_up '100' - option dynamic_bw_down '100' - - # White list for static/dynamic limit - # list limit_whitelist '192.168.1.225' - # list limit_whitelist '192.168.1.0/24' - # list limit_whitelist 'ABCD:CDEF::1/64' - - # Options for Traffic Priority - option priority_enable '0' - option priority_netdev 'lan' - - -# -# For Static QoS Rate Limit Samples : -# -# For Download : -#config download -# option hostname 'My PC' -# option unit 'kbytes' -# option ipaddr '192.168.1.224' -# option rate '128' -# -# For Upload : -#config upload -# option hostname 'office-pc' -# option unit 'mbytes' -# option ipaddr 'ABCD:FFED::1/64' -# option rate '1024' -# -# -# Traffic Priority Samples : -# -# protocol : tcp, udp, udplite, sctp, dccp, tcp is default -# priority : integer between 1-11, 1 is default and the highest -# service : you can input a integer or service name, -# e.g. '22', '11-22', 'telnet', 'ssh, http, ftp', etc -# -#config priority -# option protocol 'tcp' -# option priority '-400' -# option service '23' -# option comment '?' -# -#config priority -# option protocol 'udp' -# option priority '-400' -# option service 'https' -# option comment '?' -# -#config priority -# option protocol 'dccp' -# option priority '0' -# option service '22-35' -# option comment '?' -# -#config priority -# option protocol 'dccp' -# option priority '300' -# option service 'ftp,ssh,http' -# option comment '?' -# diff --git a/rooter/0optionalapps/nft-qos/files/nft-qos.init b/rooter/0optionalapps/nft-qos/files/nft-qos.init deleted file mode 100644 index 7a56ec7..0000000 --- a/rooter/0optionalapps/nft-qos/files/nft-qos.init +++ /dev/null @@ -1,47 +0,0 @@ -#!/bin/sh /etc/rc.common -# -# Copyright (C) 2018 rosysong@rosinson.com -# - -. /lib/nft-qos/core.sh -. /lib/nft-qos/monitor.sh -. /lib/nft-qos/dynamic.sh -. /lib/nft-qos/static.sh -. /lib/nft-qos/priority.sh - -START=99 -USE_PROCD=1 - -service_triggers() { - procd_add_reload_trigger nft-qos - - procd_open_validate - qosdef_validate_dynamic - qosdef_validate_static - qosdef_validate_priority - procd_close_validate -} - -start_service() { - config_load nft-qos - - qosdef_init_env - qosdef_flush_static - qosdef_flush_dynamic - qosdef_remove_priority - - qosdef_init_header - qosdef_init_monitor - qosdef_validate_dynamic default qosdef_init_dynamic - qosdef_validate_static default qosdef_init_static - qosdef_validate_priority default qosdef_init_priority - qosdef_init_done - qosdef_start -} - -stop_service() { - qosdef_flush_dynamic - qosdef_flush_static - qosdef_remove_priority - qosdef_clean_cache -} diff --git a/rooter/0optionalapps/pingtest/files/etc/config/ping b/rooter/0optionalapps/pingtest/files/etc/config/ping deleted file mode 100644 index 6fa2bfc..0000000 --- a/rooter/0optionalapps/pingtest/files/etc/config/ping +++ /dev/null @@ -1,6 +0,0 @@ -config ping 'ping' - option enable '0' - option delay '40' - option conn '1' - option interval '20' - option type '1' \ No newline at end of file diff --git a/rooter/0optionalapps/pingtest/files/usr/lib/lua/luci/model/cbi/ping.lua b/rooter/0optionalapps/pingtest/files/usr/lib/lua/luci/model/cbi/ping.lua index caa3bf6..bb52017 100644 --- a/rooter/0optionalapps/pingtest/files/usr/lib/lua/luci/model/cbi/ping.lua +++ b/rooter/0optionalapps/pingtest/files/usr/lib/lua/luci/model/cbi/ping.lua @@ -10,9 +10,9 @@ m = Map("ping", translate("Custom Ping Test"), translate("Enable/Disable Custom d = m:section(TypedSection, "ping", " ") d.anonymous = true -c1 = d:option(ListValue, "enable", "Ping Test Status : ", "Ping every 20 seconds and, if it fails, restart modem or reboot router"); -c1:value("0", "Disabled") -c1:value("1", "Enabled") +c1 = d:option(ListValue, "enable", translate("Ping Test Status : "), translate("Ping every 20 seconds and, if it fails, restart modem or reboot router")); +c1:value("0", translate("Disabled")) +c1:value("1", translate("Enabled")) c1.default=0 interval = d:option(Value, "interval", translate("Test Interval :"), translate("Number of seconds between testing the connection. Range is 20 to 120 secs.")); @@ -21,12 +21,12 @@ interval.optional=false; interval.datatype = 'range(20,120)'; interval.default="20"; -type = d:option(ListValue, "type", "Test Type :", "Type of test - Page Retrieval or Ping"); -type:value("0", "Ping") -type:value("1", "Page Retrieval") +type = d:option(ListValue, "type", translate("Test Type :"), translate("Type of test - Page Retrieval or Ping")); +type:value("0", translate("Ping")) +type:value("1", translate("Page Retrieval")) type.default=1 -d1 = d:option(ListValue, "delay", "Reconnection Delay","Delay in seconds after restarting modem before checking for connection"); +d1 = d:option(ListValue, "delay", translate("Reconnection Delay"),translate("Delay in seconds after restarting modem before checking for connection")); d1:value("40", "40 seconds") d1:value("45", "45 seconds") d1:value("50", "50 seconds") diff --git a/rooter/0optionalapps/qfirehose/src/firehose_protocol.c b/rooter/0optionalapps/qfirehose/src/firehose_protocol.c index 7116cde..25c6ea1 100644 --- a/rooter/0optionalapps/qfirehose/src/firehose_protocol.c +++ b/rooter/0optionalapps/qfirehose/src/firehose_protocol.c @@ -20,9 +20,8 @@ #define error_return() do {dbg_time("%s %s %d fail\n", __FILE__, __func__, __LINE__); return __LINE__; } while(0) int recv_sc600y_configure_num = 1; -extern const char *q_device_type; -static int fh_recv_cmd_sk[2]; - +extern int g_is_sc600y_chip; + extern unsigned q_erase_all_before_download; extern int update_transfer_bytes(long long bytes_cur); extern int show_progress(); @@ -42,12 +41,12 @@ struct fh_configure_cmd { struct fh_erase_cmd { const char *type; - //uint32_t PAGES_PER_BLOCK; - //uint32_t SECTOR_SIZE_IN_BYTES; - //char label[32]; + uint32_t PAGES_PER_BLOCK; + uint32_t SECTOR_SIZE_IN_BYTES; + char label[32]; uint32_t last_sector; uint32_t num_partition_sectors; - //uint32_t physical_partition_number; + uint32_t physical_partition_number; uint32_t start_sector; }; @@ -55,12 +54,12 @@ struct fh_program_cmd { const char *type; char *filename; uint32_t filesz; - //uint32_t PAGES_PER_BLOCK; + uint32_t PAGES_PER_BLOCK; uint32_t SECTOR_SIZE_IN_BYTES; - //char label[32]; - //uint32_t last_sector; + char label[32]; + uint32_t last_sector; uint32_t num_partition_sectors; - //uint32_t physical_partition_number; + uint32_t physical_partition_number; uint32_t start_sector; }; @@ -89,6 +88,7 @@ struct fh_cmd_header { struct fh_vendor_defines { const char *type; // "vendor" + char buffer[256]; }; struct fh_cmd { @@ -103,7 +103,7 @@ struct fh_cmd { struct fh_vendor_defines vdef; }; int part_upgrade; - char xml_original_data[512]; + char xml_original_data[300]; }; struct fh_data { @@ -111,9 +111,8 @@ struct fh_data { const void *usb_handle; unsigned MaxPayloadSizeToTargetInBytes; unsigned fh_cmd_count; - unsigned fh_patch_count; unsigned ZlpAwareHost; - struct fh_cmd fh_cmd_table[256]; //AG525 have more than 64 partition + struct fh_cmd fh_cmd_table[128]; //AG525 have more than 64 partition unsigned xml_tx_size; unsigned xml_rx_size; @@ -121,7 +120,9 @@ struct fh_data { char xml_rx_buf[1024]; }; -static const char * fh_xml_find_value(const char *xml_line, const char *key, char **ppend) { +static const char * fh_xml_get_value(const char *xml_line, const char *key) { + static char value[64]; + char *pchar = strstr(xml_line, key); char *pend; @@ -142,69 +143,45 @@ static const char * fh_xml_find_value(const char *xml_line, const char *key, cha dbg_time("%s: no end %s in %s\n", __func__, "\"", xml_line); return NULL; } - - *ppend = pend; - return pchar; -} - -static const char * fh_xml_get_value(const char *xml_line, const char *key) { - static char value[64]; - char *pend; - const char *pchar = fh_xml_find_value(xml_line, key, &pend); - - if (!pchar) { - return NULL; - } strncpy(value, pchar, pend - pchar); value[pend - pchar] = '\0'; + //dbg_time("%s=%s\n", key, value); + return value; } -static void fh_xml_set_value(char *xml_line, const char *key, unsigned value) { - char *pend; - const char *pchar = fh_xml_find_value(xml_line, key, &pend); - char *tmp_line = strdup(xml_line); - char value_str[32]; - - if (!pchar || !tmp_line) { - return; - } - - snprintf(value_str, sizeof(value_str), "%u", value); - tmp_line[pchar - xml_line] = '\0'; - strcat(tmp_line, value_str); - strcat(tmp_line, pend); - - strcpy(xml_line, tmp_line); - free(tmp_line); -} - static int fh_parse_xml_line(const char *xml_line, struct fh_cmd *fh_cmd) { const char *pchar = NULL; - size_t len = strlen(xml_line); + char *pret; memset(fh_cmd, 0, sizeof( struct fh_cmd)); - strcpy(fh_cmd->xml_original_data, xml_line); - if (fh_cmd->xml_original_data[len - 1] == '\n') - fh_cmd->xml_original_data[len - 1] = '\0'; - if (strstr(xml_line, "vendor=\"quectel\"")) { fh_cmd->vdef.type = "vendor"; + snprintf(fh_cmd->vdef.buffer, sizeof(fh_cmd->vdef.buffer), "%.255s", xml_line); return 0; } else if (!strncmp(xml_line, "erase.type = "erase"; + if ((pchar = fh_xml_get_value(xml_line, "PAGES_PER_BLOCK"))) + fh_cmd->erase.PAGES_PER_BLOCK = atoi(pchar); + if ((pchar = fh_xml_get_value(xml_line, "SECTOR_SIZE_IN_BYTES"))) + fh_cmd->erase.SECTOR_SIZE_IN_BYTES = atoi(pchar); if (strstr(xml_line, "last_sector")) { - if ((pchar = fh_xml_get_value(xml_line, "last_sector"))) + if ((pchar = fh_xml_get_value(xml_line, "last_sector"))) fh_cmd->erase.last_sector = atoi(pchar); + if (strstr(xml_line, "label")) { + if ((pchar = fh_xml_get_value(xml_line, "label"))) + strcpy(fh_cmd->erase.label, pchar); + } } + if ((pchar = fh_xml_get_value(xml_line, "num_partition_sectors"))) + fh_cmd->erase.num_partition_sectors = strtoul(pchar, &pret, 10); + if ((pchar = fh_xml_get_value(xml_line, "physical_partition_number"))) + fh_cmd->erase.physical_partition_number = atoi(pchar); if ((pchar = fh_xml_get_value(xml_line, "start_sector"))) fh_cmd->erase.start_sector = atoi(pchar); - if ((pchar = fh_xml_get_value(xml_line, "num_partition_sectors"))) - fh_cmd->erase.num_partition_sectors = atoi(pchar); - return 0; } else if (!strncmp(xml_line, "program.start_sector = atoi(pchar); - if ((pchar = fh_xml_get_value(xml_line, "num_partition_sectors"))) - fh_cmd->program.num_partition_sectors = atoi(pchar); - if ((pchar = fh_xml_get_value(xml_line, "SECTOR_SIZE_IN_BYTES"))) - fh_cmd->program.SECTOR_SIZE_IN_BYTES = atoi(pchar); + } + if (!g_is_sc600y_chip) + { + if ((pchar = fh_xml_get_value(xml_line, "PAGES_PER_BLOCK"))) + fh_cmd->program.PAGES_PER_BLOCK = atoi(pchar); + if ((pchar = fh_xml_get_value(xml_line, "SECTOR_SIZE_IN_BYTES"))) + fh_cmd->program.SECTOR_SIZE_IN_BYTES = atoi(pchar); + if (strstr(xml_line, "last_sector")) { + if ((pchar = fh_xml_get_value(xml_line, "last_sector"))) + fh_cmd->program.last_sector = atoi(pchar); + if (strstr(xml_line, "label")) { + if ((pchar = fh_xml_get_value(xml_line, "label"))) + strcpy(fh_cmd->program.label, pchar); + } + } + if ((pchar = fh_xml_get_value(xml_line, "num_partition_sectors"))) + fh_cmd->program.num_partition_sectors = atoi(pchar); + if ((pchar = fh_xml_get_value(xml_line, "physical_partition_number"))) + fh_cmd->program.physical_partition_number = atoi(pchar); + if ((pchar = fh_xml_get_value(xml_line, "start_sector"))) + fh_cmd->program.start_sector = atoi(pchar); + } + else + { + if ((pchar = fh_xml_get_value(xml_line, "start_sector"))) + fh_cmd->program.start_sector = atoi(pchar); + if ((pchar = fh_xml_get_value(xml_line, "num_partition_sectors"))) + fh_cmd->program.num_partition_sectors = atoi(pchar); + if ((pchar = fh_xml_get_value(xml_line, "SECTOR_SIZE_IN_BYTES"))) + fh_cmd->program.SECTOR_SIZE_IN_BYTES = atoi(pchar); + strcpy(fh_cmd->xml_original_data, xml_line); + } return 0; } else if (!strncmp(xml_line, "patch.type = "patch"; - pchar = fh_xml_get_value(xml_line, "filename"); - if (pchar && strcmp(pchar, "DISK")) - return -1; + if ((pchar = fh_xml_get_value(xml_line, "filename"))) + { + fh_cmd->patch.filename = strdup(pchar); + if(fh_cmd->patch.filename[0] == '\0' || strncasecmp(fh_cmd->patch.filename, "DISK",4)) + {//some fw version have blank program line, ignore it. + return -1; + } + } + strcpy(fh_cmd->xml_original_data, xml_line); + return 0; } else if (!strncmp(xml_line, "xml_tx_buf, fh_data->xml_tx_size, fp)) { char *xml_line = strstr(fh_data->xml_tx_buf, "<"); - char *c_start = NULL; + + if (xml_line && strstr(xml_line, "")) { + if (strstr(xml_line, "/>") < strstr(xml_line, "") && strstr(xml_line, ""); - - if (c_end) { - /* - - - - */ - char *tmp = strstr(xml_line, "/>"); - if (tmp && (tmp < c_start || tmp > c_end)) { - memset(c_start, ' ', c_end - c_start + strlen("-->")); - goto __fh_parse_xml_line; - } - - continue; - } - else { - /* - - --> - */ - do { - if (fgets(fh_data->xml_tx_buf, fh_data->xml_tx_size, fp) == NULL) { break; }; - xml_line = fh_data->xml_tx_buf; - } while (!strstr(xml_line, "-->") && strstr(xml_line, ">(sMB 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 diff --git a/rooter/0routerspecfic/rd05a1/files/lib/firmware/ath10k/QCA9887/hw1.0/firmware-5.bin b/rooter/0routerspecfic/rd05a1/files/lib/firmware/ath10k/QCA9887/hw1.0/firmware-5.bin deleted file mode 100644 index 2109698c778ab8721111a8ea45780372b2e289c9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 236104 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 A52+c*i}PWP{AQCH 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μ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 diff --git a/rooter/0routerspecfic/rd05a1/files/lib/firmware/ath10k/cal-pci-0000_00_00.0.bin b/rooter/0routerspecfic/rd05a1/files/lib/firmware/ath10k/cal-pci-0000_00_00.0.bin deleted file mode 100644 index 4588a060625ee5c5dc7c2d7bf857c83653aab65a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2116 zcmZ?a&~RX3Jn?QB*Aztt26={1PbLnR91aEs22mgu1Y!`VU|>i9QV~u@CdRr3h6W%p zC`f=Ys7doP3NQ*VC@C>92!J62g90^;r;1tp44y2U3^QkPQpGf?7{bWN$RH{z${;Ev z1U8S0i;Dq-DF9~~7##k0{>N%UWePT7Qbe)o$1YZ|rl4;P0}RW+fs~Yt3h9%ZXk=<`Wy8QwP&#)J3|G}po&jP*=rubEN|&zz;i`I& z8U&3^+@{9Hh8h@q7-5P^$;c^?f*BZmA~Ghd*n9LW3&#Y8SqwsA9Sk#I#{Q~hVBwg| zFc&O36E0fKz|7tSR3$7vkzpQOv<4{J2^O8eFb7GLg`<_B4`@O+lDRbuY+M}-y+F}s zh6zY&*|~cdCIQXuVVI62%E8mYFa;>u0hEJ+U)3-c*>prqM$dx1n52f9iV`*~B_;Ll zT$kILj3ZrcgM@u%O@>OB+oB8=pnJ$>3y4WbO3OO9d3bvJ8kkvFTH6BCL`*`@mK}S~ z!f3y^w7zxQ_8$*QnzU%sVT3$P+y@kl6Epfpo@c4LJ))ose69@8ZKnf5vOf^UaruiT /sys/class/gpio/export +echo out > /sys/class/gpio/gpio$wd_gpio/direction +echo 14 > /sys/class/gpio/export +echo out > /sys/class/gpio/gpio14/direction +echo 255 >/sys/class/gpio/gpio14/value + +while [ 1 ] +do + echo 255 >/sys/class/gpio/gpio$wd_gpio/value + sleep 1 + echo 0 >/sys/class/gpio/gpio$wd_gpio/value + sleep 1 +done diff --git a/rooter/0routerspecfic/we826q/files/usr/lib/rooter/changedevice.sh b/rooter/0routerspecfic/we826q/files/usr/lib/rooter/changedevice.sh deleted file mode 100644 index 507c479..0000000 --- a/rooter/0routerspecfic/we826q/files/usr/lib/rooter/changedevice.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh - -ROOTER=/usr/lib/rooter - -log() { - logger -t "Change Device" "$@" -} - -uci set system.led_wan.dev=$1 -uci commit system -/etc/init.d/led restart \ No newline at end of file diff --git a/rooter/0routerspecfic/wg1602/Makefile b/rooter/0routerspecfic/wg1602/Makefile new file mode 100644 index 0000000..bc608a7 --- /dev/null +++ b/rooter/0routerspecfic/wg1602/Makefile @@ -0,0 +1,36 @@ +#Owned by DairyMan@Whirlpool +# +#Copyright GNU act. +include $(TOPDIR)/rules.mk + +PKG_NAME:=wg1602 +PKG_VERSION:=1.000 +PKG_RELEASE:=1 + +PKG_MAINTAINER:=Created by DM/makefile by Cobia@whirlpool +include $(INCLUDE_DIR)/package.mk + +define Package/wg1602 + SECTION:=utils + CATEGORY:=ROOter + SUBMENU:=Router Specific + DEPENDS:=+kmod-mt7615e +kmod-mt76 +kmod-mt7603 +kmod-mt7615-firmware \ + +kmod-mt7615e +kmod-mt7663-firmware-ap +kmod-mt7663-firmware-sta \ + +kmod-mt76x2 + TITLE:=Install scripts for WG1602 + PKGARCH:=all +endef + +define Package/wg1602/description + Helper scripts to install scripts for WG1602 +endef + + +define Build/Compile +endef + +define Package/wg1602/install + $(CP) ./files/* $(1)/ +endef + +$(eval $(call BuildPackage,wg1602)) diff --git a/rooter/0routerspecfic/wg1602/files/etc/init.d/sw-init b/rooter/0routerspecfic/wg1602/files/etc/init.d/sw-init new file mode 100644 index 0000000..552a708 --- /dev/null +++ b/rooter/0routerspecfic/wg1602/files/etc/init.d/sw-init @@ -0,0 +1,15 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2013 OpenWrt.org + +START=50 +USE_PROCD=1 + +log() { + logger -t "WatchDog" "$@" +} + +start_service() +{ + log "WG1602 USB Hub switch to USB3.0 infterface" + echo 0 > /sys/class/gpio/ext-usb/value +} diff --git a/rooter/0routerspecfic/wg1602/files/usr/lib/rooter/special.sh b/rooter/0routerspecfic/wg1602/files/usr/lib/rooter/special.sh new file mode 100644 index 0000000..11a7fde --- /dev/null +++ b/rooter/0routerspecfic/wg1602/files/usr/lib/rooter/special.sh @@ -0,0 +1,28 @@ +#!/bin/sh + +LED=0 +SM=$(uci get system.4G1) +if [ -z $SM ]; then + uci set system.4G1=led + uci set system.4G1.name="4G1" + uci set system.4G1.sysfs="green:4g1" + uci set system.4G1.trigger="netdev" + uci set system.4G1.dev="wwan0" + uci set system.4G1.mode="link tx rx" + LED=1 +fi +SM=$(uci get system.4G2) +if [ -z $SM ]; then + uci set system.4G2=led + uci set system.4G2.name="4G2" + uci set system.4G2.sysfs="green:4g2" + uci set system.4G2.trigger="netdev" + uci set system.4G2.dev="wwan1" + uci set system.4G2.mode="link tx rx" + LED=1 +fi + +if [ $LED -eq 1 ]; then + uci commit system + /etc/init.d/led restart +fi diff --git a/rooter/0routerspecfic/wg1608/Makefile b/rooter/0routerspecfic/wg1608/Makefile new file mode 100644 index 0000000..0e5ab8a --- /dev/null +++ b/rooter/0routerspecfic/wg1608/Makefile @@ -0,0 +1,36 @@ +#Owned by DairyMan@Whirlpool +# +#Copyright GNU act. +include $(TOPDIR)/rules.mk + +PKG_NAME:=wg1608 +PKG_VERSION:=1.000 +PKG_RELEASE:=1 + +PKG_MAINTAINER:=Created by DM/makefile by Cobia@whirlpool +include $(INCLUDE_DIR)/package.mk + +define Package/wg1608 + SECTION:=utils + CATEGORY:=ROOter + SUBMENU:=Router Specific + DEPENDS:=+kmod-mt7615e +kmod-mt76 +kmod-mt7603 +kmod-mt7615-firmware \ + +kmod-mt7615e +kmod-mt7663-firmware-ap +kmod-mt7663-firmware-sta \ + +kmod-mt76x2 + TITLE:=Install scripts for WG1608 + PKGARCH:=all +endef + +define Package/wg1608/description + Helper scripts to install scripts for WG1608 +endef + + +define Build/Compile +endef + +define Package/wg1608/install + $(CP) ./files/* $(1)/ +endef + +$(eval $(call BuildPackage,wg1608)) diff --git a/rooter/0routerspecfic/wg1608/files/etc/init.d/wd-init b/rooter/0routerspecfic/wg1608/files/etc/init.d/wd-init new file mode 100644 index 0000000..465976c --- /dev/null +++ b/rooter/0routerspecfic/wg1608/files/etc/init.d/wd-init @@ -0,0 +1,15 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2013 OpenWrt.org + +START=50 +USE_PROCD=1 + +log() { + logger -t "WatchDog" "$@" +} + +start_service() +{ + /usr/lib/custom/watchdog.sh & + log "Start watchdog" +} diff --git a/rooter/0routerspecfic/wg1608/files/usr/lib/custom/watchdog.sh b/rooter/0routerspecfic/wg1608/files/usr/lib/custom/watchdog.sh new file mode 100644 index 0000000..befbcd7 --- /dev/null +++ b/rooter/0routerspecfic/wg1608/files/usr/lib/custom/watchdog.sh @@ -0,0 +1,23 @@ +#!/bin/sh + +dis=493 +echo $dis > /sys/class/gpio/export +echo out > /sys/class/gpio/gpio$dis/direction +echo 255 >/sys/class/gpio/gpio$dis/value + +echo none > /sys/class/leds/watchdog/trigger +while [ 1 ] +do + echo 1 >/sys/class/leds/watchdog/brightness + sleep 1 + echo 0 >/sys/class/leds/watchdog/brightness + sleep 1 + echo 1 >/sys/class/leds/watchdog/brightness + sleep 1 + echo 0 >/sys/class/leds/watchdog/brightness + sleep 1 + echo 1 >/sys/class/leds/watchdog/brightness + sleep 1 + echo 0 >/sys/class/leds/watchdog/brightness + sleep 5 +done diff --git a/rooter/0routerspecfic/wg1608/files/usr/lib/rooter/modem-led.sh b/rooter/0routerspecfic/wg1608/files/usr/lib/rooter/modem-led.sh new file mode 100644 index 0000000..25b0fa1 --- /dev/null +++ b/rooter/0routerspecfic/wg1608/files/usr/lib/rooter/modem-led.sh @@ -0,0 +1,51 @@ +#!/bin/sh + +log() { + logger -t "modem-led " "$@" +} + +CURRMODEM=$1 +COMMD=$2 + + case $COMMD in + "0" ) + echo none > /sys/class/leds/green:globe/trigger + echo 0 > /sys/class/leds/green:globe/brightness + echo none > /sys/class/leds/green:signal/trigger + echo 0 > /sys/class/leds/green:signal/brightness + ;; + "1" ) + echo timer > /sys/class/leds/green:globe/trigger + echo 500 > /sys/class/leds/green:globe/delay_on + echo 500 > /sys/class/leds/green:globe/delay_off + ;; + "2" ) + echo timer > /sys/class/leds/green:globe/trigger + echo 200 > /sys/class/leds/green:globe/delay_on + echo 200 > /sys/class/leds/green:globe/delay_off + ;; + "3" ) + echo timer > /sys/class/leds/green:globe/trigger + echo 1000 > /sys/class/leds/green:globe/delay_on + echo 0 > /sys/class/leds/green:globe/delay_off + ;; + "4" ) + echo none > /sys/class/leds/green:globe/trigger + echo 1 > /sys/class/leds/green:globe/brightness + sig2=$3 + echo timer > /sys/class/leds/green:signal/trigger + if [ $sig2 -lt 18 -a $sig2 -gt 0 ] 2>/dev/null;then + echo 500 > /sys/class/leds/green:signal/delay_on + echo 500 > /sys/class/leds/green:signal/delay_off + elif [ $sig2 -ge 18 -a $sig2 -lt 31 ] 2>/dev/null;then + echo 150 > /sys/class/leds/green:signal/delay_on + echo 150 > /sys/class/leds/green:signal/delay_off + elif [ $sig2 -eq 31 ] 2>/dev/null;then + echo 0 > /sys/class/leds/green:signal/delay_on + echo 1000 > /sys/class/leds/green:signal/delay_off + else + echo 950 > /sys/class/leds/green:signal/delay_on + echo 950 > /sys/class/leds/green:signal/delay_off + fi + ;; + esac diff --git a/rooter/0routerspecfic/wg1608/files/usr/lib/rooter/special.sh b/rooter/0routerspecfic/wg1608/files/usr/lib/rooter/special.sh new file mode 100644 index 0000000..92f36d5 --- /dev/null +++ b/rooter/0routerspecfic/wg1608/files/usr/lib/rooter/special.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +LED=0 +SM=$(uci get system.wifi) +if [ -z $SM ]; then + uci set system.wifi=led + uci set system.wifi.name="5Ghzwifi" + uci set system.wifi.sysfs="wifi" + uci set system.wifi.trigger="netdev" + uci set system.wifi.dev="wlan1" + uci set system.wifi.mode="link tx rx" + uci commit system + /etc/init.d/led restart +fi + diff --git a/rooter/0routerspecfic/wg209/Makefile b/rooter/0routerspecfic/wg209/Makefile new file mode 100644 index 0000000..34852dd --- /dev/null +++ b/rooter/0routerspecfic/wg209/Makefile @@ -0,0 +1,33 @@ +#Owned by DairyMan@Whirlpool +# +#Copyright GNU act. +include $(TOPDIR)/rules.mk + +PKG_NAME:=wg209 +PKG_VERSION:=1.000 +PKG_RELEASE:=1 + +PKG_MAINTAINER:=Created by DM/makefile by Cobia@whirlpool +include $(INCLUDE_DIR)/package.mk + +define Package/wg209 + SECTION:=utils + CATEGORY:=ROOter + SUBMENU:=Router Specific + TITLE:=Install scripts for WG209 + PKGARCH:=all +endef + +define Package/wg209/description + Helper scripts to install scripts for WG209 +endef + + +define Build/Compile +endef + +define Package/wg209/install + $(CP) ./files/* $(1)/ +endef + +$(eval $(call BuildPackage,wg209)) diff --git a/rooter/0routerspecfic/wg209/files/usr/lib/rooter/modem-led.sh b/rooter/0routerspecfic/wg209/files/usr/lib/rooter/modem-led.sh new file mode 100644 index 0000000..9cdace0 --- /dev/null +++ b/rooter/0routerspecfic/wg209/files/usr/lib/rooter/modem-led.sh @@ -0,0 +1,76 @@ +#!/bin/sh + +log() { + logger -t "modem-led " "$@" +} + +CURRMODEM=$1 +COMMD=$2 + + case $COMMD in + "0" ) + echo none > /sys/class/leds/green:signal1/trigger + echo 0 > /sys/class/leds/green:signal1/brightness + echo none > /sys/class/leds/green:signal2/trigger + echo 0 > /sys/class/leds/green:signal2/brightness + echo none > /sys/class/leds/green:signal3/trigger + echo 0 > /sys/class/leds/green:signal3/brightness + echo none > /sys/class/leds/green:internet/trigger + echo 0 > /sys/class/leds/green:internet/brightness + ;; + "1" ) + echo timer > /sys/class/leds/green:internet/trigger + echo 500 > /sys/class/leds/green:internet/delay_on + echo 500 > /sys/class/leds/green:internet/delay_off + ;; + "2" ) + echo timer > /sys/class/leds/green:internet/trigger + echo 200 > /sys/class/leds/green:internet/delay_on + echo 200 > /sys/class/leds/green:internet/delay_off + ;; + "3" ) + echo timer > /sys/class/leds/green:internet/trigger + echo 1000 > /sys/class/leds/green:internet/delay_on + echo 0 > /sys/class/leds/green:internet/delay_off + ;; + "4" ) + sig2=$3 + if [ $sig2 -lt 8 -a $sig2 -gt 0 ] 2>/dev/null;then + echo none > /sys/class/leds/green:internet/trigger + echo 1 > /sys/class/leds/green:internet/brightness + echo none > /sys/class/leds/green:signal3/trigger + echo 0 > /sys/class/leds/green:signal3/brightness + echo none > /sys/class/leds/green:signal2/trigger + echo 0 > /sys/class/leds/green:signal2/brightness + echo none > /sys/class/leds/green:signal1/trigger + echo 0 > /sys/class/leds/green:signal1/brightness + elif [ $sig2 -ge 8 -a $sig2 -lt 16 ] 2>/dev/null;then + echo none > /sys/class/leds/green:internet/trigger + echo 1 > /sys/class/leds/green:internet/brightness + echo none > /sys/class/leds/green:signal3/trigger + echo 1 > /sys/class/leds/green:signal3/brightness + echo none > /sys/class/leds/green:signal2/trigger + echo 0 > /sys/class/leds/green:signal2/brightness + echo none > /sys/class/leds/green:signal1/trigger + echo 0 > /sys/class/leds/green:signal1/brightness + elif [ $sig2 -ge 16 -a $sig2 -lt 24 ] 2>/dev/null;then + echo none > /sys/class/leds/green:internet/trigger + echo 1 > /sys/class/leds/green:internet/brightness + echo none > /sys/class/leds/green:signal3/trigger + echo 1 > /sys/class/leds/green:signal3/brightness + echo none > /sys/class/leds/green:signal2/trigger + echo 1 > /sys/class/leds/green:signal2/brightness + echo none > /sys/class/leds/green:signal1/trigger + echo 0 > /sys/class/leds/green:signal1/brightness + elif [ $sig2 -ge 24 ] 2>/dev/null;then + echo none > /sys/class/leds/green:internet/trigger + echo 1 > /sys/class/leds/green:internet/brightness + echo none > /sys/class/leds/green:signal3/trigger + echo 1 > /sys/class/leds/green:signal3/brightness + echo none > /sys/class/leds/green:signal2/trigger + echo 1 > /sys/class/leds/green:signal2/brightness + echo none > /sys/class/leds/green:signal1/trigger + echo 1 > /sys/class/leds/green:signal1/brightness + fi + ;; + esac diff --git a/rooter/0routerspecfic/wg259/Makefile b/rooter/0routerspecfic/wg259/Makefile new file mode 100644 index 0000000..c0a41ae --- /dev/null +++ b/rooter/0routerspecfic/wg259/Makefile @@ -0,0 +1,34 @@ +#Owned by DairyMan@Whirlpool +# +#Copyright GNU act. +include $(TOPDIR)/rules.mk + +PKG_NAME:=wg259 +PKG_VERSION:=1.000 +PKG_RELEASE:=1 + +PKG_MAINTAINER:=Created by DM/makefile by Cobia@whirlpool +include $(INCLUDE_DIR)/package.mk + +define Package/wg259 + SECTION:=utils + CATEGORY:=ROOter + SUBMENU:=Router Specific + DEPENDS:=+kmod-mt76 +kmod-mt7603 +kmod-mt76x2 + TITLE:=Install scripts for WG259 + PKGARCH:=all +endef + +define Package/wg259/description + Helper scripts to install scripts for WG259 +endef + + +define Build/Compile +endef + +define Package/wg259/install + $(CP) ./files/* $(1)/ +endef + +$(eval $(call BuildPackage,wg259)) diff --git a/rooter/0routerspecfic/wg259/files/usr/lib/rooter/special.sh b/rooter/0routerspecfic/wg259/files/usr/lib/rooter/special.sh new file mode 100644 index 0000000..94ee31a --- /dev/null +++ b/rooter/0routerspecfic/wg259/files/usr/lib/rooter/special.sh @@ -0,0 +1,23 @@ +#!/bin/sh + +SM=$(uci get system.4g5g) +if [ -z $SM ]; then + uci set system.4g5g=led + uci set system.4g5g.name="4G5G" + uci set system.4g5g.sysfs="green:usb" + uci set system.4g5g.trigger="netdev" + uci set system.4g5g.dev="wwan0" + uci set system.4g5g.mode="link tx rx" + uci set system.4g5g.default='0' + + uci set system.sys=led + uci set system.sys.name="SYS" + uci set system.sys.sysfs="green:status" + uci set system.sys.trigger="netdev" + uci set system.sys.dev="br-lan" + uci set system.sys.mode="link tx rx" + uci set system.sys.default='0' + + uci commit system + /etc/init.d/led restart +fi diff --git a/rooter/0routerspecfic/wg3526/Makefile b/rooter/0routerspecfic/wg3526/Makefile new file mode 100644 index 0000000..8cb384e --- /dev/null +++ b/rooter/0routerspecfic/wg3526/Makefile @@ -0,0 +1,33 @@ +#Owned by DairyMan@Whirlpool +# +#Copyright GNU act. +include $(TOPDIR)/rules.mk + +PKG_NAME:=wg3526 +PKG_VERSION:=1.000 +PKG_RELEASE:=1 + +PKG_MAINTAINER:=Created by DM/makefile by Cobia@whirlpool +include $(INCLUDE_DIR)/package.mk + +define Package/wg3526 + SECTION:=utils + CATEGORY:=ROOter + SUBMENU:=Router Specific + TITLE:=Install scripts for wg3526 + PKGARCH:=all +endef + +define Package/wg3526/description + Helper scripts to install scripts for wg3526 +endef + + +define Build/Compile +endef + +define Package/wg3526/install + $(CP) ./files/* $(1)/ +endef + +$(eval $(call BuildPackage,wg3526)) diff --git a/rooter/0routerspecfic/wg3526/files/usr/lib/rooter/special.sh b/rooter/0routerspecfic/wg3526/files/usr/lib/rooter/special.sh new file mode 100644 index 0000000..e27a0b3 --- /dev/null +++ b/rooter/0routerspecfic/wg3526/files/usr/lib/rooter/special.sh @@ -0,0 +1,19 @@ +#!/bin/sh + + +echo none > /sys/class/leds/green:status/trigger +echo 0 > /sys/class/leds/green:status/brightness + +SM=$(uci get system.4g5g) +if [ -z $SM ]; then + uci set system.4g5g=led + uci set system.4g5g.name="4G5G" + uci set system.4g5g.sysfs="green:status" + uci set system.4g5g.trigger="netdev" + uci set system.4g5g.dev="wwan0" + uci set system.4g5g.mode="link tx rx" + uci set system.4g5g.default='0' + + uci commit system + /etc/init.d/led restart +fi \ No newline at end of file diff --git a/rooter/0routerspecfic/wg827/Makefile b/rooter/0routerspecfic/wg827/Makefile new file mode 100644 index 0000000..c8a419f --- /dev/null +++ b/rooter/0routerspecfic/wg827/Makefile @@ -0,0 +1,36 @@ +#Owned by DairyMan@Whirlpool +# +#Copyright GNU act. +include $(TOPDIR)/rules.mk + +PKG_NAME:=wg827 +PKG_VERSION:=1.000 +PKG_RELEASE:=1 + +PKG_MAINTAINER:=Created by DM/makefile by Cobia@whirlpool +include $(INCLUDE_DIR)/package.mk + +define Package/wg827 + SECTION:=utils + CATEGORY:=ROOter + SUBMENU:=Router Specific + DEPENDS:=+kmod-mt7615e +kmod-mt76 +kmod-mt7603 +kmod-mt7615-firmware \ + +kmod-mt7615e +kmod-mt7663-firmware-ap +kmod-mt7663-firmware-sta \ + +kmod-mt76x2 + TITLE:=Install scripts for WG827 + PKGARCH:=all +endef + +define Package/wg827/description + Helper scripts to install scripts for WG827 +endef + + +define Build/Compile +endef + +define Package/wg827/install + $(CP) ./files/* $(1)/ +endef + +$(eval $(call BuildPackage,wg827)) diff --git a/rooter/0routerspecfic/wg827/files/usr/lib/rooter/modem-led.sh b/rooter/0routerspecfic/wg827/files/usr/lib/rooter/modem-led.sh new file mode 100644 index 0000000..cdf5b4c --- /dev/null +++ b/rooter/0routerspecfic/wg827/files/usr/lib/rooter/modem-led.sh @@ -0,0 +1,38 @@ +#!/bin/sh + +log() { + logger -t "modem-led " "$@" +} + +CURRMODEM=$1 +COMMD=$2 + + case $COMMD in + "0" ) + echo none > /sys/class/leds/rgb:blue/trigger + echo 0 > /sys/class/leds/rgb:blue/brightness + echo none > /sys/class/leds/rgb:green/trigger + echo 1 > /sys/class/leds/rgb:green/brightness + ;; + "1" ) + echo timer > /sys/class/leds/rgb:blue/trigger + echo 500 > /sys/class/leds/rgb:blue/delay_on + echo 500 > /sys/class/leds/rgb:blue/delay_off + ;; + "2" ) + echo timer > /sys/class/leds/rgb:blue/trigger + echo 200 > /sys/class/leds/rgb:blue/delay_on + echo 200 > /sys/class/leds/rgb:blue/delay_off + ;; + "3" ) + echo timer > /sys/class/leds/rgb:blue/trigger + echo 1000 > /sys/class/leds/rgb:blue/delay_on + echo 0 > /sys/class/leds/rgb:blue/delay_off + ;; + "4" ) + echo none > /sys/class/leds/rgb:blue/trigger + echo 1 > /sys/class/leds/rgb:blue/brightness + echo none > /sys/class/leds/rgb:green/trigger + echo 0 > /sys/class/leds/rgb:green/brightness + ;; + esac diff --git a/rooter/0routerspecfic/wrt1900/Makefile b/rooter/0routerspecfic/wrt1900/Makefile new file mode 100644 index 0000000..843e6a6 --- /dev/null +++ b/rooter/0routerspecfic/wrt1900/Makefile @@ -0,0 +1,35 @@ +#Owned by DairyMan@Whirlpool +# +#Copyright GNU act. +include $(TOPDIR)/rules.mk + +PKG_NAME:=wrt1900 +PKG_VERSION:=1.000 +PKG_RELEASE:=1 + +PKG_MAINTAINER:=Created by DM/makefile by Cobia@whirlpool +include $(INCLUDE_DIR)/package.mk + +define Package/wrt1900 + SECTION:=utils + CATEGORY:=ROOter + SUBMENU:=Router Specific + TITLE:=Install scripts for WRT1900 + PKGARCH:=all +endef + +define Package/wrt1900/description + Helper scripts to install scripts for WRT1900 +endef + + +define Build/Compile +endef + +define Package/wrt1900/install + $(CP) ./files/* $(1)/ + + +endef + +$(eval $(call BuildPackage,wrt1900)) diff --git a/rooter/0routerspecfic/wrt1900/files/etc/init.d/amsdu b/rooter/0routerspecfic/wrt1900/files/etc/init.d/amsdu new file mode 100644 index 0000000..aa39594 --- /dev/null +++ b/rooter/0routerspecfic/wrt1900/files/etc/init.d/amsdu @@ -0,0 +1,14 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2013 OpenWrt.org + +START=70 + +log() { + logger -t "AMSDU" "$@" +} + +start_service() +{ + echo 0 > /sys/kernel/debug/ieee80211/phy0/mwlwifi/tx_amsdu + echo 0 > /sys/kernel/debug/ieee80211/phy1/mwlwifi/tx_amsdu +} diff --git a/rooter/0routerspecfic/x750/Makefile b/rooter/0routerspecfic/x750/Makefile new file mode 100644 index 0000000..ad8caca --- /dev/null +++ b/rooter/0routerspecfic/x750/Makefile @@ -0,0 +1,33 @@ +#Owned by DairyMan@Whirlpool +# +#Copyright GNU act. +include $(TOPDIR)/rules.mk + +PKG_NAME:=x750 +PKG_VERSION:=1.000 +PKG_RELEASE:=1 + +PKG_MAINTAINER:=Created by DM/makefile by Cobia@whirlpool +include $(INCLUDE_DIR)/package.mk + +define Package/x750 + SECTION:=utils + CATEGORY:=ROOter + SUBMENU:=Router Specific + TITLE:=Install scripts for x750 + PKGARCH:=all +endef + +define Package/x750/description + Helper scripts to install scripts for x750 +endef + + +define Build/Compile +endef + +define Package/x750/install + $(CP) ./files/* $(1)/ +endef + +$(eval $(call BuildPackage,x750)) diff --git a/rooter/0routerspecfic/x750/files/usr/lib/rooter/special.sh b/rooter/0routerspecfic/x750/files/usr/lib/rooter/special.sh new file mode 100644 index 0000000..9787a19 --- /dev/null +++ b/rooter/0routerspecfic/x750/files/usr/lib/rooter/special.sh @@ -0,0 +1,23 @@ +#!/bin/sh + +SM=$(uci get system.4g5g) +if [ -z $SM ]; then + uci set system.4g5g=led + uci set system.4g5g.name="4G5G" + uci set system.4g5g.sysfs="green:4g" + uci set system.4g5g.trigger="netdev" + uci set system.4g5g.dev="wwan0" + uci set system.4g5g.mode="link tx rx" + uci set system.4g5g.default='0' + + uci commit system + /etc/init.d/led restart +fi + +uci set system.gpio2=gpio_switch +uci set system.gpio2.name='gpio2' +uci set system.gpio2.gpio_pin='2' +uci set system.gpio2.value='0' +uci commit system +/etc/init.d/system restart + diff --git a/rooter/0splash/ext-splash/files/usr/lib/iframe/mframe.html b/rooter/0splash/ext-splash/files/usr/lib/iframe/mframe.html deleted file mode 100644 index 589c857..0000000 --- a/rooter/0splash/ext-splash/files/usr/lib/iframe/mframe.html +++ /dev/null @@ -1,111 +0,0 @@ - - - - - - - - - - -

      -

      Modem 1

      -
      -
      -
      Strength (%)
      - #PER# -
      -
      -
      CSQ
      - #CSQ# -
      -
      -
      RSSI (dBm)
      - #RSSI# -
      -
      -
      RSCP (dBm) RSRP
      - #RSCP# -
      -
      -
      ECIO (dB) RSRQ
      - #RSRQ# -
      -
      -
      SINR (dB)
      - #SINR# -
      -
      - -
      -

      Network

      - -
      -
      -
      Mode
      - #MODE# -
      -
      -
      MCC
      - #MCC# -
      -
      -
      MNC
      - #MNC# -
      -
      -
      RNC/eNB ID
      - #RNC# #RNCN# -
      - -
      -
      LAC
      - #LAC# #LACN# -
      -
      -
      Channel (EARFCN)
      - #CHAN# -
      -
      -
      PCI
      - #CELLID# -
      -
      -
      Bands
      - #BAND# -
      -
      -
      -
      -

      Device

      - -
      -
      -
      Router
      - #ROUTER# -
      -
      -
      Modem
      - #MODEM# -
      -
      -
      Provider
      - #PROVIDER# -
      -
      -
      Protocol
      - #PROTO# -
      -
      -
      Port
      - #PORT# -
      -
      -
      Temperature
      - #TEMP# -
      -
      -
      -
      - - diff --git a/rooter/0splash/ext-splash/files/usr/lib/iframe/status.html b/rooter/0splash/ext-splash/files/usr/lib/iframe/status.html index 7c7c33d..ddb0c69 100644 --- a/rooter/0splash/ext-splash/files/usr/lib/iframe/status.html +++ b/rooter/0splash/ext-splash/files/usr/lib/iframe/status.html @@ -136,10 +136,6 @@
      Temperature
      #TEMP# -
      -
      External IP
      - #EXTERNAL# -
      #MODEM2# diff --git a/rooter/0splash/ext-splash/files/usr/lib/iframe/stupdate.sh b/rooter/0splash/ext-splash/files/usr/lib/iframe/stupdate.sh index 656a8f2..e66f255 100644 --- a/rooter/0splash/ext-splash/files/usr/lib/iframe/stupdate.sh +++ b/rooter/0splash/ext-splash/files/usr/lib/iframe/stupdate.sh @@ -5,12 +5,12 @@ log() { logger -t "Status Update" "$@" } -levelsper="101,85,70,55,40,25,0" +levelsper="101,85,70,55,40,25,10,1,0" namesper="Perfect,Excellent,Good,Medium,Low,Bad,Dead" -levelsrssi="1,70,90,100,119,113,0" -namesrssi="Perfect,High,Medium,Poor,Bad,None" -levelsrscp="50,70,90,100,112,136,140,0" -namesrscp='High (3G) :High (4G),Medium (3G) : High (4G),Poor (3G) : Good (4G),Weak (3G) : Medium (4G),None (3G) : Poor (4G)' +levelsrssi="113,119,100,90,70,1,0" +namesrssi="None,Bad,Poor,Medium,High,Perfect" +levelsrscp="140,136,112,100,90,70,50,1,0" +namesrscp='None,None (3G) : Poor (4G),Weak (3G) : Medium (4G),Poor (3G) : Good (4G),Medium (3G) : High (4G),High (3G) :High (4G)' level2txt() { tmp="$1" @@ -25,29 +25,6 @@ level2txt() { tmp=$(echo "$tmp" | sed -e "s/%//g") level=$levelsper namev=$namesper - namez=$namev - cindex=1 - nindex=0 - namev="-" - while [ true ] - do - levelv=$(echo "$level" | cut -d, -f$cindex) - if [ $levelv = "0" ]; then - namev="-" - break - fi - if [ "$tmp" -ge "$levelv" ]; then - nind=$((${nindex}+1)) - namev=$(echo "$namez" | cut -d, -f$nind) - break - fi - cindex=$((${cindex}+1)) - nindex=$((${nindex}+1)) - done - css="level_"$nindex - desc="
      "$namev"
      " - namev="""$front$tmp1"""$desc - return fi if [ $key = "rssi" ]; then front="-" @@ -56,29 +33,6 @@ level2txt() { tmp1="$tmp"" " level=$levelsrssi namev=$namesrssi - namez=$namev - cindex=1 - nindex=0 - namev="-" - while [ true ] - do - levelv=$(echo "$level" | cut -d, -f$cindex) - if [ $levelv = "0" ]; then - namev="-" - break - fi - if [ "$tmp" -le "$levelv" ]; then - nindex=$((${nindex}+1)) - namev=$(echo "$namez" | cut -d, -f$nindex) - break - fi - cindex=$((${cindex}+1)) - nindex=$((${nindex}+1)) - done - css="level_"$nindex - desc="
      "$namev"
      " - namev="""$front$tmp1"""$desc - return fi if [ $key = "rscp" ]; then front="" @@ -90,29 +44,6 @@ level2txt() { tmp=$(printf %.0f "$tmp") level=$levelsrscp namev=$namesrscp - namez=$namev - cindex=1 - nindex=0 - namev="-" - while [ true ] - do - levelv=$(echo "$level" | cut -d, -f$cindex) - if [ $levelv = "0" ]; then - namev="-" - break - fi - if [ "$tmp" -le "$levelv" ]; then - namev=$(echo "$namez" | cut -d, -f$nindex) - nindex=$((${nindex}-1)) - break - fi - cindex=$((${cindex}+1)) - nindex=$((${nindex}+1)) - done - css="level_"$nindex - desc="
      "$namev"
      " - namev="""$front$tmp1"""$desc - return fi if [ $key = "single" ]; then @@ -128,6 +59,30 @@ level2txt() { namev="""$tmp"""$desc return fi + + namez=$namev + cindex=1 + nindex=6 + namev="-" + + while [ true ] + do + levelv=$(echo "$level" | cut -d, -f$cindex) + if [ $levelv = "0" ]; then + namev="-" + break + fi + if [ "$tmp" -lt "$levelv" ]; then + namev=$(echo "$namez" | cut -d, -f$nindex) + break + fi + cindex=$((${cindex}+1)) + nindex=$((${nindex}-1)) + done + + css="level_"$nindex + desc="
      "$namev"
      " + namev="""$front$tmp1"""$desc } readstatus() { @@ -300,20 +255,13 @@ if [ $splash = "1" ]; then sed -i -e "s!#MODEM#!$namev!g" $STEMP level2txt "$cops" "single" namev=$(echo "$namev" | tr -d '&') - sed -i -e "s~#PROVIDER#~$namev~g" $STEMP + sed -i -e "s!#PROVIDER#!$namev!g" $STEMP level2txt "$proto" "single" sed -i -e "s!#PROTO#!$namev!g" $STEMP level2txt "$port" "single" sed -i -e "s!#PORT#!$namev!g" $STEMP level2txt "$tempur" "single" sed -i -e "s!#TEMP#!$namev!g" $STEMP - rm -f /tmp/spip; wget -O /tmp/spip http://ipecho.net/plain > /dev/null 2>&1 - extr=$(cat /tmp/spip) - if [ -z "$extr" ]; then - extr="-" - fi - level2txt "$extr" "single" - sed -i -e "s!#EXTERNAL#!$namev!g" $STEMP dual=$(uci -q get iframe.iframe.dual) if [ $dual = "1" ]; then diff --git a/rooter/0splash/ext-splash/files/usr/lib/iframe/update.sh b/rooter/0splash/ext-splash/files/usr/lib/iframe/update.sh index e6cb8df..bf67d98 100644 --- a/rooter/0splash/ext-splash/files/usr/lib/iframe/update.sh +++ b/rooter/0splash/ext-splash/files/usr/lib/iframe/update.sh @@ -1,163 +1,6 @@ #!/bin/sh . /lib/functions.sh -log() { - logger -t "Status Update" "$@" -} - -levelsper="101,85,70,55,40,25,10,1,0" -namesper="Perfect,Excellent,Good,Medium,Low,Bad,Dead" -levelsrssi="113,119,100,90,70,1,0" -namesrssi="None,Bad,Poor,Medium,High,Perfect" -levelsrscp="140,136,112,100,90,70,50,1,0" -namesrscp='None,None (3G) : Poor (4G),Weak (3G) : Medium (4G),Poor (3G) : Good (4G),Medium (3G) : High (4G),High (3G) :High (4G)' - -level2txt() { - tmp="$1" - key=$2 - front="" - tmp1="$tmp"" " - if [ "$tmp" = "-" ]; then - namev="""--""" - return - fi - if [ $key = "per" ]; then - tmp=$(echo "$tmp" | sed -e "s/%//g") - level=$levelsper - namev=$namesper - fi - if [ $key = "rssi" ]; then - front="-" - tmp=$(echo "$tmp" | sed -e "s/-//g") - tmp=$(echo "$tmp" | sed -e "s/dBm//g") - tmp1="$tmp"" " - level=$levelsrssi - namev=$namesrssi - fi - if [ $key = "rscp" ]; then - front="" - tmp=$(echo "$tmp" | sed -e "s/dBm//g") - tmp=$(echo "$tmp" | sed -e "s/([^)]*)//g") - tmp1="$tmp"" " - tmp=$(echo "$tmp" | sed -e "s/-//g") - tmp=$(echo "$tmp" | tr " " "," | cut -d, -f1 ) - tmp=$(printf %.0f "$tmp") - level=$levelsrscp - namev=$namesrscp - fi - - if [ $key = "single" ]; then - desc="" - tmp=$(echo "$tmp" | sed -e "s/dBm//g") - tmp=$(echo "$tmp" | sed -e "s/dB//g") - if [ $3 != "1" ];then - tmp=$(echo "$tmp" | sed -e "s/-//g") - fi - if [ $3 = "1" -o $3 = "0" ];then - desc="
      "."
      " - fi - namev="""$tmp"""$desc - return - fi - - namez=$namev - cindex=1 - nindex=0 - namev="-" - - while [ true ] - do - levelv=$(echo "$level" | cut -d, -f$cindex) - if [ $levelv = "0" ]; then - namev="-" - break - fi - if [ "$tmp" -ge "$levelv" ]; then - namev=$(echo "$namez" | cut -d, -f$nindex) - break - fi - cindex=$((${cindex}+1)) - nindex=$((${nindex}+1)) - done - - css="level_"$nindex - desc="
      "$namev"
      " - namev="""$front$tmp1"""$desc -} - -readstatus() { -modd=$1 - while IFS= read -r line; do - port="$line" - read -r line - csq="$line" - read -r line - per="$line" - read -r line - rssi="$line" - read -r line - modem="$line" - read -r line - cops="$line" - read -r line - mode="$line" - read -r line - lac="$line" - read -r line - lacn="$line" - read -r line - cid="$line" - - read -r line - cidn="$line" - read -r line - mcc="$line" - read -r line - mnc="$line" - read -r line - rnc="$line" - read -r line - rncn="$line" - read -r line - down="$line" - read -r line - up="$line" - read -r line - ecio="$line" - read -r line - rscp="$line" - read -r line - ecio1="$line" - - read -r line - rscp1="$line" - read -r line - netmode="$line" - read -r line - cell="$line" - read -r line - modtype="$line" - read -r line - conntype="$line" - read -r line - channel="$line" - read -r line - phone="$line" - read -r line - read -r line - lband="$line" - read -r line - tempur="$line" - - read -r line - proto="$line" - read -r line - pci="$line" - read -r line - sinr="$line" - break - done < /tmp/status$modd.file -} bwdata() { while IFS= read -r line; do if [ $line = '0' ]; then @@ -186,68 +29,19 @@ bwdata() { logtype=$(uci -q get iframe.login.logtype) if [ $logtype = "1" ]; then STEMP="/tmp/www/itemp.html" - STATUS="/usr/lib/iframe/mframe.html" + STATUS="/usr/lib/iframe/iframe.html" IFSTATUS="/tmp/www/display.html" rm -f $STEMP cp $STATUS $STEMP - readstatus 1 - level2txt "$csq" "single" 0 - sed -i -e "s!#CSQ#!$namev!g" $STEMP - level2txt "$per" "per" - sed -i -e "s!#PER#!$namev!g" $STEMP - level2txt "$rssi" "rssi" - sed -i -e "s!#RSSI#!$namev!g" $STEMP - level2txt "$rscp" "rscp" - sed -i -e "s!#RSCP#!$namev!g" $STEMP - level2txt "$ecio" "single" 1 - sed -i -e "s!#RSRQ#!$namev!g" $STEMP - level2txt "$sinr" "single" 1 - sed -i -e "s!#SINR#!$namev!g" $STEMP - - level2txt "$mode" "single" - sed -i -e "s!#MODE#!$namev!g" $STEMP - level2txt "$mcc" "single" - sed -i -e "s!#MCC#!$namev!g" $STEMP - level2txt "$mnc" "single" - sed -i -e "s!#MNC#!$namev!g" $STEMP - level2txt "$rnc" "single" - sed -i -e "s!#RNC#!$namev!g" $STEMP - level2txt "$rncn" "single" - sed -i -e "s!#RNCN#!$namev!g" $STEMP - level2txt "$lac" "single" - sed -i -e "s!#LAC#!$namev!g" $STEMP - level2txt "$lacn" "single" - sed -i -e "s!#LACN#!$namev!g" $STEMP - level2txt "$pci" "single" - sed -i -e "s!#CELLID#!$namev!g" $STEMP - level2txt "$channel" "single" - sed -i -e "s!#CHAN#!$namev!g" $STEMP - level2txt "$lband" "single" - sed -i -e "s!#BAND#!$namev!g" $STEMP - - if [ -e /etc/custom ]; then - mod="/etc/custom" - else - mod="/tmp/sysinfo/model" - fi - while IFS= read -r line; do - ROUTER=$line - break - done < $mod - level2txt "$ROUTER" "single" - sed -i -e "s!#ROUTER#!$namev!g" $STEMP - level2txt "$modem" "single" - sed -i -e "s!#MODEM#!$namev!g" $STEMP - level2txt "$cops" "single" - namev=$(echo "$namev" | tr -d '&') - sed -i -e "s!#PROVIDER#!$namev!g" $STEMP - level2txt "$proto" "single" - sed -i -e "s!#PROTO#!$namev!g" $STEMP - level2txt "$port" "single" - sed -i -e "s!#PORT#!$namev!g" $STEMP - level2txt "$tempur" "single" - sed -i -e "s!#TEMP#!$namev!g" $STEMP + bwdata + + sed -i -e "s!#TITLE#!Bandwidth Usage!g" $STEMP + sed -i -e "s!#DAYS#!$days!g" $STEMP + sed -i -e "s!#TOTAL#!$tused!g" $STEMP + sed -i -e "s!#DOWN#!$tdwn!g" $STEMP + sed -i -e "s!#UP#!$tup!g" $STEMP + sed -i -e "s!#PROJ#!$project!g" $STEMP mv $STEMP $IFSTATUS fi diff --git a/rooter/0splash/ext-splashconfig/files/usr/lib/lua/luci/controller/splash.lua b/rooter/0splash/ext-splashconfig/files/usr/lib/lua/luci/controller/splash.lua index 40b8960..84f6b85 100644 --- a/rooter/0splash/ext-splashconfig/files/usr/lib/lua/luci/controller/splash.lua +++ b/rooter/0splash/ext-splashconfig/files/usr/lib/lua/luci/controller/splash.lua @@ -4,7 +4,10 @@ ext-theme module("luci.controller.splash", package.seeall) +I18N = require "luci.i18n" +translate = I18N.translate + function index() - entry({"admin", "splash"}, firstchild(), "Splash Screen", 82).dependent=false - entry({"admin", "splash", "splash"}, cbi("splashm"), _("Configuration"), 20) + entry({"admin", "splash"}, firstchild(), translate("Splash Screen"), 99).dependent=false + entry({"admin", "splash", "splash"}, cbi("splashm"), _(translate("Configuration")), 20) end diff --git a/rooter/0splash/ext-splashconfig/files/usr/lib/lua/luci/model/cbi/splashm.lua b/rooter/0splash/ext-splashconfig/files/usr/lib/lua/luci/model/cbi/splashm.lua index 0073acb..4703b22 100644 --- a/rooter/0splash/ext-splashconfig/files/usr/lib/lua/luci/model/cbi/splashm.lua +++ b/rooter/0splash/ext-splashconfig/files/usr/lib/lua/luci/model/cbi/splashm.lua @@ -5,38 +5,38 @@ local zones = require "luci.sys.zoneinfo" local fs = require "nixio.fs" local conf = require "luci.config" -m = Map("iframe", "Splash Screen Configuration",translate("Change the configuration of the Splash and Login screen.")) +m = Map("iframe", translate("Splash Screen Configuration"),translate("Change the configuration of the Splash and Login screen.")) m:chain("luci") -s = m:section(TypedSection, "iframe", "Status Page Configuration") +s = m:section(TypedSection, "iframe", translate("Status Page Configuration")) s.anonymous = true s.addremove = false -c1 = s:option(ListValue, "splashpage", "Enable Network Status Page Before Login :"); -c1:value("0", "Disabled") -c1:value("1", "Enabled") +c1 = s:option(ListValue, "splashpage", translate("Enable Network Status Page Before Login :")); +c1:value("0", translate("Disabled")) +c1:value("1", translate("Enabled")) c1.default=0 -a1 = s:option(Value, "splashtitle", "Network Status Title :"); +a1 = s:option(Value, "splashtitle", translate("Network Status Title :")); a1.optional=false; -a1.default = "ROOter Status" +a1.default = translate("ROOter Status") a1:depends("splashpage", "1") -dc1 = s:option(ListValue, "dual", "Enable Modem 2 Status :"); -dc1:value("0", "Disabled") -dc1:value("1", "Enabled") +dc1 = s:option(ListValue, "dual", translate("Enable Modem 2 Status :")); +dc1:value("0", translate("Disabled")) +dc1:value("1", translate("Enabled")) dc1.default=0 dc1:depends("splashpage", "1") -cc1 = s:option(ListValue, "speed", "Enable OpenSpeedTest :"); -cc1:value("0", "Disabled") -cc1:value("1", "Enabled") +cc1 = s:option(ListValue, "speed", translate("Enable OpenSpeedTest :")); +cc1:value("0", translate("Disabled")) +cc1:value("1", translate("Enabled")) cc1.default=0 cc1:depends("splashpage", "1") -ec1 = s:option(ListValue, "band", "Enable Bandwidth Summary :"); -ec1:value("0", "Disabled") -ec1:value("1", "Enabled") +ec1 = s:option(ListValue, "band", translate("Enable Bandwidth Summary :")); +ec1:value("0", translate("Disabled")) +ec1:value("1", translate("Enabled")) ec1.default=0 ec1:depends("splashpage", "1") diff --git a/rooter/0splash/status/files/etc/config/splash b/rooter/0splash/status/files/etc/config/splash index 1d6102f..6088b27 100644 --- a/rooter/0splash/status/files/etc/config/splash +++ b/rooter/0splash/status/files/etc/config/splash @@ -1,4 +1,4 @@ config settings 'settings' - option enabled '1' - option full '1' + option enabled '0' + option full '0' \ No newline at end of file diff --git a/rooter/0splash/status/files/usr/lib/lua/luci/controller/splashset.lua b/rooter/0splash/status/files/usr/lib/lua/luci/controller/splashset.lua index 7500383..37b2799 100644 --- a/rooter/0splash/status/files/usr/lib/lua/luci/controller/splashset.lua +++ b/rooter/0splash/status/files/usr/lib/lua/luci/controller/splashset.lua @@ -2,10 +2,10 @@ luci-app-argon-config ]]-- -module("luci.controller.splashset", package.seeall) +module("luci.controller.splash", package.seeall) function index() if nixio.fs.access("/etc/config/splash") then - entry({"admin", "theme", "splashset"}, cbi("splash"), _("Splash Screen"), 71) + entry({"admin", "theme", "splash"}, cbi("splash"), _("Splash Screen"), 71) end end diff --git a/rooter/0splash/status/files/www/splash_files/check.gif b/rooter/0splash/status/files/www/splash_files/check.gif deleted file mode 100644 index 75b945d2553848b8b6f41fe5e24599c0687b8472..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49 zcmZ?wbhEHbWMp7unE0RJ|Ns9C3=9Vj8~~DvKUo+V7?>DzfNY>Fh|Ltj$Y2csQN9XW diff --git a/rooter/0splash/status/files/www/splash_files/full.gif b/rooter/0splash/status/files/www/splash_files/full.gif deleted file mode 100644 index 75b945d2553848b8b6f41fe5e24599c0687b8472..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49 zcmZ?wbhEHbWMp7unE0RJ|Ns9C3=9Vj8~~DvKUo+V7?>DzfNY>Fh|Ltj$Y2csQN9XW diff --git a/rooter/ext-rooter-basic/Makefile b/rooter/ext-rooter-basic/Makefile index 3b04cb2..1b84b8a 100644 --- a/rooter/ext-rooter-basic/Makefile +++ b/rooter/ext-rooter-basic/Makefile @@ -21,7 +21,7 @@ define Package/ext-rooter-basic +kmod-usb-net-sierrawireless +kmod-usb-ohci +kmod-usb-serial +kmod-nls-utf8 \ +kmod-usb-serial-option +kmod-usb-serial-sierrawireless +luci-proto-3x \ +kmod-usb-uhci +kmod-usb2 +luci-proto-3g \ - +usb-modeswitch +wireless-tools +rmbim +rqmi +ext-sms +ext-buttons + +usb-modeswitch +wireless-tools +rmbim +rqmi +ext-sms +ext-buttons TITLE:=ROOter support for usbmodems PKGARCH:=all endef