22 | PKGARCH:=all
23 | DEPENDS:=+!wget&&!curl:wget
24 | endef
25 |
26 | define Package/luci-app-adguardhome/description
27 | LuCI support for adguardhome
28 | endef
29 |
30 | define Build/Prepare
31 | endef
32 |
33 | define Build/Compile
34 | endef
35 |
36 | define Package/luci-app-adguardhome/conffiles
37 | /usr/share/AdGuardHome/links.txt
38 | /etc/config/adGuardConfig/AdGuardHome
39 | endef
40 |
41 | define Package/luci-app-adguardhome/install
42 | $(INSTALL_DIR) $(1)/usr/lib/lua/luci
43 | cp -pR ./luasrc/* $(1)/usr/lib/lua/luci
44 | $(INSTALL_DIR) $(1)/
45 | cp -pR ./root/* $(1)/
46 | $(INSTALL_DIR) $(1)/usr/lib/lua/luci/i18n
47 | po2lmo ./po/zh-cn/AdGuardHome.po $(1)/usr/lib/lua/luci/i18n/AdGuardHome.zh-cn.lmo
48 | endef
49 |
50 | define Package/luci-app-adguardhome/postinst
51 | #!/bin/sh
52 | /etc/init.d/AdGuardHome enable >/dev/null 2>&1
53 | enable=$(uci get AdGuardHome.AdGuardHome.enabled 2>/dev/null)
54 | if [ "$enable" == "1" ]; then
55 | /etc/init.d/AdGuardHome reload
56 | fi
57 | rm -f /tmp/luci-indexcache
58 | rm -f /tmp/luci-modulecache/*
59 | exit 0
60 | endef
61 |
62 | define Package/luci-app-adguardhome/prerm
63 | #!/bin/sh
64 | if [ -z "$${IPKG_INSTROOT}" ]; then
65 | /etc/init.d/AdGuardHome disable
66 | /etc/init.d/AdGuardHome stop
67 | uci -q batch <<-EOF >/dev/null 2>&1
68 | delete ucitrack.@AdGuardHome[-1]
69 | commit ucitrack
70 | EOF
71 | fi
72 | exit 0
73 | endef
74 |
75 | $(eval $(call BuildPackage,luci-app-adguardhome))
76 |
--------------------------------------------------------------------------------
/luci-app-adguardhome/luasrc/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaoxiao29/luci-app-adguardhome/1497e52aa13fca2851accef13c96b8c558e33911/luci-app-adguardhome/luasrc/.DS_Store
--------------------------------------------------------------------------------
/luci-app-adguardhome/luasrc/controller/AdGuardHome.lua:
--------------------------------------------------------------------------------
1 | module("luci.controller.AdGuardHome",package.seeall)
2 | local fs=require"nixio.fs"
3 | local http=require"luci.http"
4 | local uci=require"luci.model.uci".cursor()
5 | function index()
6 | entry({"admin", "services", "AdGuardHome"},alias("admin", "services", "AdGuardHome", "base"),_("AdGuard Home"), 10).dependent = true
7 | entry({"admin","services","AdGuardHome","base"},cbi("AdGuardHome/base"),_("Base Setting"),1).leaf = true
8 | entry({"admin","services","AdGuardHome","log"},form("AdGuardHome/log"),_("Log"),2).leaf = true
9 | entry({"admin","services","AdGuardHome","manual"},cbi("AdGuardHome/manual"),_("Manual Config"),3).leaf = true
10 | entry({"admin","services","AdGuardHome","status"},call("act_status")).leaf=true
11 | entry({"admin", "services", "AdGuardHome", "check"}, call("check_update"))
12 | entry({"admin", "services", "AdGuardHome", "doupdate"}, call("do_update"))
13 | entry({"admin", "services", "AdGuardHome", "getlog"}, call("get_log"))
14 | entry({"admin", "services", "AdGuardHome", "dodellog"}, call("do_dellog"))
15 | entry({"admin", "services", "AdGuardHome", "reloadconfig"}, call("reload_config"))
16 | entry({"admin", "services", "AdGuardHome", "gettemplateconfig"}, call("get_template_config"))
17 | end
18 | function get_template_config()
19 | local b
20 | local d=""
21 | for cnt in io.lines("/tmp/resolv.conf.auto") do
22 | b=string.match (cnt,"^[^#]*nameserver%s+([^%s]+)$")
23 | if (b~=nil) then
24 | d=d.." - "..b.."\n"
25 | end
26 | end
27 | local f=io.open("/usr/share/AdGuardHome/AdGuardHome_template.yaml", "r+")
28 | local tbl = {}
29 | local a=""
30 | while (1) do
31 | a=f:read("*l")
32 | if (a=="#bootstrap_dns") then
33 | a=d
34 | elseif (a=="#upstream_dns") then
35 | a=d
36 | elseif (a==nil) then
37 | break
38 | end
39 | table.insert(tbl, a)
40 | end
41 | f:close()
42 | http.prepare_content("text/plain; charset=utf-8")
43 | http.write(table.concat(tbl, "\n"))
44 | end
45 | function reload_config()
46 | fs.remove("/tmp/AdGuardHometmpconfig.yaml")
47 | http.prepare_content("application/json")
48 | http.write('')
49 | end
50 | function act_status()
51 | local e={}
52 | local binpath=uci:get("AdGuardHome","AdGuardHome","binpath")
53 | e.running=luci.sys.call("pgrep "..binpath.." >/dev/null")==0
54 | e.redirect=(fs.readfile("/var/run/AdGredir")=="1")
55 | http.prepare_content("application/json")
56 | http.write_json(e)
57 | end
58 | function do_update()
59 | fs.writefile("/var/run/lucilogpos","0")
60 | http.prepare_content("application/json")
61 | http.write('')
62 | local arg
63 | if luci.http.formvalue("force") == "1" then
64 | arg="force"
65 | else
66 | arg=""
67 | end
68 | if fs.access("/var/run/update_core") then
69 | if arg=="force" then
70 | luci.sys.exec("kill $(pgrep /usr/share/AdGuardHome/update_core.sh) ; sh /usr/share/AdGuardHome/update_core.sh "..arg.." >/tmp/AdGuardHome_update.log 2>&1 &")
71 | end
72 | else
73 | luci.sys.exec("sh /usr/share/AdGuardHome/update_core.sh "..arg.." >/tmp/AdGuardHome_update.log 2>&1 &")
74 | end
75 | end
76 | function get_log()
77 | local logfile=uci:get("AdGuardHome","AdGuardHome","logfile")
78 | if (logfile==nil) then
79 | http.write("no log available\n")
80 | return
81 | elseif (logfile=="syslog") then
82 | if not fs.access("/var/run/AdGuardHomesyslog") then
83 | luci.sys.exec("(/usr/share/AdGuardHome/getsyslog.sh &); sleep 1;")
84 | end
85 | logfile="/tmp/AdGuardHometmp.log"
86 | fs.writefile("/var/run/AdGuardHomesyslog","1")
87 | elseif not fs.access(logfile) then
88 | http.write("")
89 | return
90 | end
91 | http.prepare_content("text/plain; charset=utf-8")
92 | local fdp
93 | if fs.access("/var/run/lucilogreload") then
94 | fdp=0
95 | fs.remove("/var/run/lucilogreload")
96 | else
97 | fdp=tonumber(fs.readfile("/var/run/lucilogpos")) or 0
98 | end
99 | local f=io.open(logfile, "r+")
100 | f:seek("set",fdp)
101 | local a=f:read(2048000) or ""
102 | fdp=f:seek()
103 | fs.writefile("/var/run/lucilogpos",tostring(fdp))
104 | f:close()
105 | http.write(a)
106 | end
107 | function do_dellog()
108 | local logfile=uci:get("AdGuardHome","AdGuardHome","logfile")
109 | fs.writefile(logfile,"")
110 | http.prepare_content("application/json")
111 | http.write('')
112 | end
113 | function check_update()
114 | http.prepare_content("text/plain; charset=utf-8")
115 | local fdp=tonumber(fs.readfile("/var/run/lucilogpos")) or 0
116 | local f=io.open("/tmp/AdGuardHome_update.log", "r+")
117 | f:seek("set",fdp)
118 | local a=f:read(2048000) or ""
119 | fdp=f:seek()
120 | fs.writefile("/var/run/lucilogpos",tostring(fdp))
121 | f:close()
122 | if fs.access("/var/run/update_core") then
123 | http.write(a)
124 | else
125 | http.write(a.."\0")
126 | end
127 | end
128 |
--------------------------------------------------------------------------------
/luci-app-adguardhome/luasrc/model/cbi/AdGuardHome/base.lua:
--------------------------------------------------------------------------------
1 | require("luci.sys")
2 | require("luci.util")
3 | require("io")
4 | local m,s,o,o1
5 | local fs=require"nixio.fs"
6 | local uci=require"luci.model.uci".cursor()
7 | local configpath=uci:get("AdGuardHome","AdGuardHome","configpath") or "/etc/config/adGuardConfig/AdGuardHome.yaml"
8 | local binpath=uci:get("AdGuardHome","AdGuardHome","binpath") or "/etc/config/adGuardConfig/AdGuardHome"
9 | httpport=uci:get("AdGuardHome","AdGuardHome","httpport") or "3000"
10 | m = Map("AdGuardHome", "AdGuard Home")
11 | m.description = translate("Free and open source, powerful network-wide ads & trackers blocking DNS server.")
12 | m:section(SimpleSection).template = "AdGuardHome/AdGuardHome_status"
13 |
14 | s = m:section(TypedSection, "AdGuardHome")
15 | s.anonymous=true
16 | s.addremove=false
17 | ---- enable
18 | o = s:option(Flag, "enabled", translate("Enable"))
19 | o.default = 0
20 | o.optional = false
21 | ---- httpport
22 | o =s:option(Value,"httpport",translate("Browser management port"))
23 | o.placeholder=3000
24 | o.default=3000
25 | o.datatype="port"
26 | o.optional = false
27 | o.description = translate("")
28 | ---- update warning not safe
29 | local binmtime=uci:get("AdGuardHome","AdGuardHome","binmtime") or "0"
30 | local e=""
31 | if not fs.access(configpath) then
32 | e=e.." "..translate("no config")
33 | end
34 | if not fs.access(binpath) then
35 | e=e.." "..translate("no core")
36 | else
37 | local version=uci:get("AdGuardHome","AdGuardHome","version")
38 | local testtime=fs.stat(binpath,"mtime")
39 | if testtime~=tonumber(binmtime) or version==nil then
40 | local tmp=luci.sys.exec(binpath.." -c /dev/null --check-config 2>&1| grep -m 1 -E 'v[0-9.]+' -o")
41 | version=string.sub(tmp, 1, -2)
42 | if version=="" then version="core error" end
43 | uci:set("AdGuardHome","AdGuardHome","version",version)
44 | uci:set("AdGuardHome","AdGuardHome","binmtime",testtime)
45 | uci:save("AdGuardHome")
46 | end
47 | e=version..e
48 | end
49 | o=s:option(Button,"restart",translate("Update"))
50 | o.inputtitle=translate("Update core version")
51 | o.template = "AdGuardHome/AdGuardHome_check"
52 | o.showfastconfig=(not fs.access(configpath))
53 | o.description=string.format(translate("core version:").."%s ",e)
54 | ---- port warning not safe
55 | local port=luci.sys.exec("awk '/ port:/{printf($2);exit;}' "..configpath.." 2>nul")
56 | if (port=="") then port="?" end
57 | ---- Redirect
58 | o = s:option(ListValue, "redirect", port..translate("Redirect"), translate("AdGuardHome redirect mode"))
59 | o.placeholder = "none"
60 | o:value("none", translate("none"))
61 | o:value("dnsmasq-upstream", translate("Run as dnsmasq upstream server"))
62 | o:value("redirect", translate("Redirect 53 port to AdGuardHome"))
63 | o:value("exchange", translate("Use port 53 replace dnsmasq"))
64 | o.default = "none"
65 | o.optional = true
66 | ---- bin path
67 | o = s:option(Value, "binpath", translate("Bin Path"), translate("AdGuardHome Bin path if no bin will auto download"))
68 | o.default = "/etc/config/adGuardConfig/AdGuardHome"
69 | o.datatype = "string"
70 | o.optional = false
71 | o.rmempty=false
72 | o.validate=function(self, value)
73 | if value=="" then return nil end
74 | if fs.stat(value,"type")=="dir" then
75 | fs.rmdir(value)
76 | end
77 | if fs.stat(value,"type")=="dir" then
78 | if (m.message) then
79 | m.message =m.message.."\nerror!bin path is a dir"
80 | else
81 | m.message ="error!bin path is a dir"
82 | end
83 | return nil
84 | end
85 | return value
86 | end
87 | --- upx
88 | o = s:option(ListValue, "upxflag", translate("use upx to compress bin after download"))
89 | o:value("", translate("none"))
90 | o:value("-1", translate("compress faster"))
91 | o:value("-9", translate("compress better"))
92 | o:value("--best", translate("compress best(can be slow for big files)"))
93 | o:value("--brute", translate("try all available compression methods & filters [slow]"))
94 | o:value("--ultra-brute", translate("try even more compression variants [very slow]"))
95 | o.default = ""
96 | o.description=translate("bin use less space,but may have compatibility issues")
97 | o.rmempty = true
98 | ---- config path
99 | o = s:option(Value, "configpath", translate("Config Path"), translate("AdGuardHome config path"))
100 | o.default = "/etc/config/adGuardConfig/AdGuardHome.yaml"
101 | o.datatype = "string"
102 | o.optional = false
103 | o.rmempty=false
104 | o.validate=function(self, value)
105 | if value==nil then return nil end
106 | if fs.stat(value,"type")=="dir" then
107 | fs.rmdir(value)
108 | end
109 | if fs.stat(value,"type")=="dir" then
110 | if m.message then
111 | m.message =m.message.."\nerror!config path is a dir"
112 | else
113 | m.message ="error!config path is a dir"
114 | end
115 | return nil
116 | end
117 | return value
118 | end
119 | ---- work dir
120 | o = s:option(Value, "workdir", translate("Work dir"), translate("AdGuardHome work dir include rules,audit log and database"))
121 | o.default = "/etc/config/adGuardConfig/workspace"
122 | o.datatype = "string"
123 | o.optional = false
124 | o.rmempty=false
125 | o.validate=function(self, value)
126 | if value=="" then return nil end
127 | if fs.stat(value,"type")=="reg" then
128 | if m.message then
129 | m.message =m.message.."\nerror!work dir is a file"
130 | else
131 | m.message ="error!work dir is a file"
132 | end
133 | return nil
134 | end
135 | if string.sub(value, -1)=="/" then
136 | return string.sub(value, 1, -2)
137 | else
138 | return value
139 | end
140 | end
141 | ---- log file
142 | o = s:option(Value, "logfile", translate("Runtime log file"), translate("AdGuardHome runtime Log file if 'syslog': write to system log;if empty no log"))
143 | o.datatype = "string"
144 | o.rmempty = true
145 | o.validate=function(self, value)
146 | if fs.stat(value,"type")=="dir" then
147 | fs.rmdir(value)
148 | end
149 | if fs.stat(value,"type")=="dir" then
150 | if m.message then
151 | m.message =m.message.."\nerror!log file is a dir"
152 | else
153 | m.message ="error!log file is a dir"
154 | end
155 | return nil
156 | end
157 | return value
158 | end
159 | ---- debug
160 | o = s:option(Flag, "verbose", translate("Verbose log"))
161 | o.default = 0
162 | o.optional = true
163 | ---- gfwlist
164 | local a=luci.sys.call("grep -m 1 -q programadd "..configpath)
165 | if (a==0) then
166 | a="Added"
167 | else
168 | a="Not added"
169 | end
170 | o=s:option(Button,"gfwdel",translate("Del gfwlist"),translate(a))
171 | o.optional = true
172 | o.inputtitle=translate("Del")
173 | o.write=function()
174 | luci.sys.exec("sh /usr/share/AdGuardHome/gfw2adg.sh del 2>&1")
175 | luci.http.redirect(luci.dispatcher.build_url("admin","services","AdGuardHome"))
176 | end
177 | o=s:option(Button,"gfwadd",translate("Add gfwlist"),translate(a))
178 | o.optional = true
179 | o.inputtitle=translate("Add")
180 | o.write=function()
181 | luci.sys.exec("sh /usr/share/AdGuardHome/gfw2adg.sh 2>&1")
182 | luci.http.redirect(luci.dispatcher.build_url("admin","services","AdGuardHome"))
183 | end
184 | o = s:option(Value, "gfwupstream", translate("Gfwlist upstream dns server"), translate("Gfwlist domain upstream dns service")..translate(a))
185 | o.default = "tcp://223.5.5.5"
186 | o.datatype = "string"
187 | o.optional = true
188 | ---- chpass
189 | o = s:option(Value, "hashpass", translate("Change browser management password"), translate("Press load culculate model and culculate finally save/apply"))
190 | o.default = ""
191 | o.datatype = "string"
192 | o.template = "AdGuardHome/AdGuardHome_chpass"
193 | o.optional = true
194 | ---- upgrade protect
195 | o = s:option(MultiValue, "upprotect", translate("Keep files when system upgrade"))
196 | o:value("$binpath",translate("core bin"))
197 | o:value("$configpath",translate("config file"))
198 | o:value("$logfile",translate("log file"))
199 | o:value("$workdir/data/sessions.db",translate("sessions.db"))
200 | o:value("$workdir/data/stats.db",translate("stats.db"))
201 | o:value("$workdir/data/querylog.json",translate("querylog.json"))
202 | o:value("$workdir/data/filters",translate("filters"))
203 | o.widget = "checkbox"
204 | o.default = nil
205 | o.optional=true
206 | ---- wait net on boot
207 | o = s:option(Flag, "waitonboot", translate("On boot when network ok restart"))
208 | o.default = 1
209 | o.optional = true
210 | ---- backup workdir on shutdown
211 | local workdir=uci:get("AdGuardHome","AdGuardHome","workdir") or "/usr/bin/AdGuardHome"
212 | o = s:option(MultiValue, "backupfile", translate("Backup workdir files when shutdown"))
213 | o1 = s:option(Value, "backupwdpath", translate("Backup workdir path"))
214 | local name
215 | o:value("filters","filters")
216 | o:value("stats.db","stats.db")
217 | o:value("querylog.json","querylog.json")
218 | o:value("sessions.db","sessions.db")
219 | o1:depends ("backupfile", "filters")
220 | o1:depends ("backupfile", "stats.db")
221 | o1:depends ("backupfile", "querylog.json")
222 | o1:depends ("backupfile", "sessions.db")
223 | for name in fs.glob(workdir.."/data/*")
224 | do
225 | name=fs.basename (name)
226 | if name~="filters" and name~="stats.db" and name~="querylog.json" and name~="sessions.db" then
227 | o:value(name,name)
228 | o1:depends ("backupfile", name)
229 | end
230 | end
231 | o.widget = "checkbox"
232 | o.default = nil
233 | o.optional=false
234 | o.description=translate("Will be restore when workdir/data is empty")
235 | ----backup workdir path
236 |
237 | o1.default = "/etc/config/adGuardConfig/workspace"
238 | o1.datatype = "string"
239 | o1.optional = false
240 | o1.validate=function(self, value)
241 | if fs.stat(value,"type")=="reg" then
242 | if m.message then
243 | m.message =m.message.."\nerror!backup dir is a file"
244 | else
245 | m.message ="error!backup dir is a file"
246 | end
247 | return nil
248 | end
249 | if string.sub(value,-1)=="/" then
250 | return string.sub(value, 1, -2)
251 | else
252 | return value
253 | end
254 | end
255 |
256 | ----Crontab
257 | o = s:option(MultiValue, "crontab", translate("Crontab task"),translate("Please change time and args in crontab"))
258 | o:value("autoupdate",translate("Auto update core"))
259 | o:value("cutquerylog",translate("Auto tail querylog"))
260 | o:value("cutruntimelog",translate("Auto tail runtime log"))
261 | o:value("autohost",translate("Auto update ipv6 hosts and restart adh"))
262 | o:value("autogfw",translate("Auto update gfwlist and restart adh"))
263 | o.widget = "checkbox"
264 | o.default = nil
265 | o.optional=true
266 |
267 | ----downloadpath
268 | o = s:option(TextValue, "downloadlinks",translate("Download links for update"))
269 | o.optional = false
270 | o.rows = 4
271 | o.wrap = "soft"
272 | o.cfgvalue = function(self, section)
273 | return fs.readfile("/usr/share/AdGuardHome/links.txt")
274 | end
275 | o.write = function(self, section, value)
276 | fs.writefile("/usr/share/AdGuardHome/links.txt", value:gsub("\r\n", "\n"))
277 | end
278 | fs.writefile("/var/run/lucilogpos","0")
279 | function m.on_commit(map)
280 | if (fs.access("/var/run/AdGserverdis")) then
281 | io.popen("/etc/init.d/AdGuardHome reload &")
282 | return
283 | end
284 | local ucitracktest=uci:get("AdGuardHome","AdGuardHome","ucitracktest")
285 | if ucitracktest=="1" then
286 | return
287 | elseif ucitracktest=="0" then
288 | io.popen("/etc/init.d/AdGuardHome reload &")
289 | else
290 | if (fs.access("/var/run/AdGlucitest")) then
291 | uci:set("AdGuardHome","AdGuardHome","ucitracktest","0")
292 | io.popen("/etc/init.d/AdGuardHome reload &")
293 | else
294 | fs.writefile("/var/run/AdGlucitest","")
295 | if (ucitracktest=="2") then
296 | uci:set("AdGuardHome","AdGuardHome","ucitracktest","1")
297 | else
298 | uci:set("AdGuardHome","AdGuardHome","ucitracktest","2")
299 | end
300 | end
301 | uci:save("AdGuardHome")
302 | end
303 | end
304 | return m
--------------------------------------------------------------------------------
/luci-app-adguardhome/luasrc/model/cbi/AdGuardHome/log.lua:
--------------------------------------------------------------------------------
1 | local fs=require"nixio.fs"
2 | local uci=require"luci.model.uci".cursor()
3 | local f,t
4 | f=SimpleForm("logview")
5 | f.reset = false
6 | f.submit = false
7 | t=f:field(TextValue,"conf")
8 | t.rmempty=true
9 | t.rows=20
10 | t.template="AdGuardHome/log"
11 | t.readonly="readonly"
12 | local logfile=uci:get("AdGuardHome","AdGuardHome","logfile") or ""
13 | t.timereplace=(logfile~="syslog" and logfile~="" )
14 | t.pollcheck=logfile~=""
15 | fs.writefile("/var/run/lucilogreload","")
16 | return f
17 |
--------------------------------------------------------------------------------
/luci-app-adguardhome/luasrc/model/cbi/AdGuardHome/manual.lua:
--------------------------------------------------------------------------------
1 | local m, s, o
2 | local fs = require "nixio.fs"
3 | local uci=require"luci.model.uci".cursor()
4 | local sys=require"luci.sys"
5 | require("string")
6 | require("io")
7 | require("table")
8 | function gen_template_config()
9 | local b
10 | local d=""
11 | for cnt in io.lines("/tmp/resolv.conf.auto") do
12 | b=string.match (cnt,"^[^#]*nameserver%s+([^%s]+)$")
13 | if (b~=nil) then
14 | d=d.." - "..b.."\n"
15 | end
16 | end
17 | local f=io.open("/usr/share/AdGuardHome/AdGuardHome_template.yaml", "r+")
18 | local tbl = {}
19 | local a=""
20 | while (1) do
21 | a=f:read("*l")
22 | if (a=="#bootstrap_dns") then
23 | a=d
24 | elseif (a=="#upstream_dns") then
25 | a=d
26 | elseif (a==nil) then
27 | break
28 | end
29 | table.insert(tbl, a)
30 | end
31 | f:close()
32 | return table.concat(tbl, "\n")
33 | end
34 | m = Map("AdGuardHome")
35 | local configpath = uci:get("AdGuardHome","AdGuardHome","configpath")
36 | local binpath = uci:get("AdGuardHome","AdGuardHome","binpath")
37 | s = m:section(TypedSection, "AdGuardHome")
38 | s.anonymous=true
39 | s.addremove=false
40 | --- config
41 | o = s:option(TextValue, "escconf")
42 | o.rows = 66
43 | o.wrap = "off"
44 | o.rmempty = true
45 | o.cfgvalue = function(self, section)
46 | return fs.readfile("/tmp/AdGuardHometmpconfig.yaml") or fs.readfile(configpath) or gen_template_config() or ""
47 | end
48 | o.validate=function(self, value)
49 | fs.writefile("/tmp/AdGuardHometmpconfig.yaml", value:gsub("\r\n", "\n"))
50 | if fs.access(binpath) then
51 | if (sys.call(binpath.." -c /tmp/AdGuardHometmpconfig.yaml --check-config 2> /tmp/AdGuardHometest.log")==0) then
52 | return value
53 | end
54 | else
55 | return value
56 | end
57 | luci.http.redirect(luci.dispatcher.build_url("admin","services","AdGuardHome","manual"))
58 | return nil
59 | end
60 | o.write = function(self, section, value)
61 | fs.move("/tmp/AdGuardHometmpconfig.yaml",configpath)
62 | end
63 | o.remove = function(self, section, value)
64 | fs.writefile(configpath, "")
65 | end
66 | --- js and reload button
67 | o = s:option(DummyValue, "")
68 | o.anonymous=true
69 | o.template = "AdGuardHome/yamleditor"
70 | if not fs.access(binpath) then
71 | o.description=translate("WARNING!!! no bin found apply config will not be test")
72 | end
73 | --- log
74 | if (fs.access("/tmp/AdGuardHometmpconfig.yaml")) then
75 | local c=fs.readfile("/tmp/AdGuardHometest.log")
76 | if (c~="") then
77 | o = s:option(TextValue, "")
78 | o.readonly=true
79 | o.rows = 5
80 | o.rmempty = true
81 | o.name=""
82 | o.cfgvalue = function(self, section)
83 | return fs.readfile("/tmp/AdGuardHometest.log")
84 | end
85 | end
86 | end
87 | function m.on_commit(map)
88 | local ucitracktest=uci:get("AdGuardHome","AdGuardHome","ucitracktest")
89 | if ucitracktest=="1" then
90 | return
91 | elseif ucitracktest=="0" then
92 | io.popen("/etc/init.d/AdGuardHome reload &")
93 | else
94 | fs.writefile("/var/run/AdGlucitest","")
95 | end
96 | end
97 | return m
--------------------------------------------------------------------------------
/luci-app-adguardhome/luasrc/view/AdGuardHome/AdGuardHome_check.htm:
--------------------------------------------------------------------------------
1 | <%+cbi/valueheader%>
2 | <%local fs=require"nixio.fs"%>
3 |
4 |
5 | <% if self.showfastconfig then %>
6 |
7 | <%end%>
8 |
9 | <%:reverse%>
10 |
11 |
12 |
78 | <%+cbi/valuefooter%>
--------------------------------------------------------------------------------
/luci-app-adguardhome/luasrc/view/AdGuardHome/AdGuardHome_chpass.htm:
--------------------------------------------------------------------------------
1 | <%+cbi/valueheader%>
2 |
32 | 0, "data-choices", { self.keylist, self.vallist })
46 | %> />
47 | <% if self.password then %>
<% end %>
48 |
49 | <%+cbi/valuefooter%>
--------------------------------------------------------------------------------
/luci-app-adguardhome/luasrc/view/AdGuardHome/AdGuardHome_status.htm:
--------------------------------------------------------------------------------
1 |
22 |
23 |
--------------------------------------------------------------------------------
/luci-app-adguardhome/luasrc/view/AdGuardHome/log.htm:
--------------------------------------------------------------------------------
1 | <%+cbi/valueheader%>
2 | <%:reverse%>
3 | <%if self.timereplace then%>
4 | <%:localtime%>
5 | <%end%>
6 |
7 |
8 |
9 |
110 | <%+cbi/valuefooter%>
--------------------------------------------------------------------------------
/luci-app-adguardhome/luasrc/view/AdGuardHome/yamleditor.htm:
--------------------------------------------------------------------------------
1 | <%+cbi/valueheader%>
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
34 | <%fs=require"nixio.fs"%>
35 | <%if fs.access("/tmp/AdGuardHometmpconfig.yaml") then%>
36 |
37 | <%end%>
38 |
39 | <%+cbi/valuefooter%>
--------------------------------------------------------------------------------
/luci-app-adguardhome/po/zh-cn/AdGuardHome.po:
--------------------------------------------------------------------------------
1 | #/cgi-bin/luci/admin/services/AdGuardHome
2 | msgid "Base Setting"
3 | msgstr "基础设置"
4 |
5 | msgid "Log"
6 | msgstr "日志"
7 |
8 | msgid "Manual Config"
9 | msgstr "手动设置"
10 |
11 | msgid "Free and open source, powerful network-wide ads & trackers blocking DNS server."
12 | msgstr "免费开源,功能强大的全网络广告和跟踪程序拦截DNS服务器"
13 |
14 | msgid "RUNNING"
15 | msgstr "运行中"
16 |
17 | msgid "NOT RUNNING"
18 | msgstr "未运行"
19 |
20 | msgid "Redirected"
21 | msgstr "已重定向"
22 |
23 | msgid "Not redirect"
24 | msgstr "未重定向"
25 |
26 | msgid "Collecting data..."
27 | msgstr "获取数据中..."
28 |
29 | msgid "Enable"
30 | msgstr "启用"
31 |
32 | msgid "Browser management port"
33 | msgstr "网页管理端口"
34 |
35 | msgid "Update"
36 | msgstr "更新"
37 | #button change
38 | msgid "Update core version"
39 | msgstr "更新核心版本"
40 |
41 | msgid "Check..."
42 | msgstr "检查中..."
43 |
44 | msgid "Updated"
45 | msgstr "已更新"
46 |
47 | #button hide
48 | msgid "Force update"
49 | msgstr "强制更新"
50 |
51 | msgid "Fast config"
52 | msgstr "快速配置"
53 | #
54 | msgid "core version:"
55 | msgstr "核心版本:"
56 | #description change
57 | msgid "no config"
58 | msgstr "没有配置文件"
59 | msgid "no core"
60 | msgstr "没有核心"
61 | #
62 | msgid "Redirect"
63 | msgstr "重定向"
64 | #inlist
65 | msgid "none"
66 | msgstr "无"
67 |
68 | msgid "Run as dnsmasq upstream server"
69 | msgstr "作为dnsmasq的上游服务器"
70 |
71 | msgid "Redirect 53 port to AdGuardHome"
72 | msgstr "重定向53端口到AdGuardHome"
73 |
74 | msgid "Use port 53 replace dnsmasq"
75 | msgstr "使用53端口替换dnsmasq"
76 | #
77 | msgid "AdGuardHome redirect mode"
78 | msgstr "AdGuardHome重定向模式"
79 |
80 | msgid "Bin Path"
81 | msgstr "执行文件路径"
82 |
83 | msgid "AdGuardHome Bin path if no bin will auto download"
84 | msgstr "AdGuardHome 执行文件路径 如果没有执行文件将自动下载"
85 |
86 | msgid "use upx to compress bin after download"
87 | msgstr "下载后使用upx压缩执行文件"
88 | #inlist
89 | msgid "compress faster"
90 | msgstr "快速压缩"
91 |
92 | msgid "compress better"
93 | msgstr "更好的压缩"
94 |
95 | msgid "compress best(can be slow for big files)"
96 | msgstr "最好的压缩(大文件可能慢)"
97 |
98 | msgid "try all available compression methods & filters [slow]"
99 | msgstr "尝试所有可能的压缩方法和过滤器[慢]"
100 |
101 | msgid "try even more compression variants [very slow]"
102 | msgstr "尝试更多变体压缩手段[很慢]"
103 |
104 | msgid "bin use less space,but may have compatibility issues"
105 | msgstr "减小执行文件空间占用,但是可能压缩后有兼容性问题"
106 | #
107 | msgid "Config Path"
108 | msgstr "配置文件路径"
109 |
110 | msgid "AdGuardHome config path"
111 | msgstr "AdGuardHome 配置文件路径"
112 |
113 | msgid "Work dir"
114 | msgstr "工作目录"
115 |
116 | msgid "AdGuardHome work dir include rules,audit log and database"
117 | msgstr "AdGuardHome 工作目录包含规则,审计日志和数据库"
118 |
119 | msgid "Runtime log file"
120 | msgstr "运行日志"
121 |
122 | msgid "AdGuardHome runtime Log file if 'syslog': write to system log;if empty no log"
123 | msgstr "AdGuardHome 运行日志 如果填syslog将写入系统日志;如果空则不记录日志"
124 |
125 | msgid "Verbose log"
126 | msgstr "详细日志"
127 | #hide div
128 | msgid "Add gfwlist"
129 | msgstr "加入gfw列表"
130 |
131 | msgid "Add"
132 | msgstr "添加"
133 |
134 | msgid "Added"
135 | msgstr "已添加"
136 |
137 | msgid "Not added"
138 | msgstr "未添加"
139 | #hide div
140 | msgid "Del gfwlist"
141 | msgstr "删除gfw列表"
142 |
143 | msgid "Del"
144 | msgstr "删除"
145 | #hide div
146 | msgid "Gfwlist upstream dns server"
147 | msgstr "gfw列表上游服务器"
148 |
149 | msgid "Gfwlist domain upstream dns service"
150 | msgstr "gfw列表域名上游服务器"
151 | #hide div
152 | msgid "Change browser management password"
153 | msgstr "改变网页登录密码"
154 |
155 | msgid "Culculate"
156 | msgstr "计算"
157 | ##button change
158 | msgid "Load culculate model"
159 | msgstr "载入计算模块"
160 |
161 | msgid "loading..."
162 | msgstr "载入中"
163 |
164 | msgid "Please save/apply"
165 | msgstr "请提交"
166 |
167 | msgid "is empty"
168 | msgstr "为空"
169 |
170 | msgid "Press load culculate model and culculate finally save/apply"
171 | msgstr "按载入计算模块 然后计算 最后保存/提交"
172 | #
173 | msgid "Keep files when system upgrade"
174 | msgstr "系统升级时保留文件"
175 | #checkbox
176 | msgid "core bin"
177 | msgstr "核心执行文件"
178 |
179 | msgid "config file"
180 | msgstr "配置文件"
181 |
182 | msgid "log file"
183 | msgstr "日志文件"
184 |
185 | msgid "querylog.json"
186 | msgstr "审计日志.json"
187 | #
188 | msgid "On boot when network ok restart"
189 | msgstr "开机后网络准备好时重启"
190 |
191 | msgid "Backup workdir files when shutdown"
192 | msgstr "在关机时备份工作目录文件"
193 |
194 | msgid "Will be restore when workdir/data is empty"
195 | msgstr "在工作目录/data为空的时候恢复"
196 |
197 | msgid "Backup workdir path"
198 | msgstr "工作目录备份路径"
199 |
200 | msgid "Crontab task"
201 | msgstr "计划任务"
202 |
203 | msgid "Auto update core"
204 | msgstr "自动升级核心"
205 |
206 | msgid "Auto tail querylog"
207 | msgstr "自动截短查询日志"
208 |
209 | msgid "Auto tail runtime log"
210 | msgstr "自动截短运行日志"
211 |
212 | msgid "Auto update ipv6 hosts and restart adh"
213 | msgstr "自动更新ipv6主机并重启adh"
214 |
215 | msgid "Auto update gfwlist and restart adh"
216 | msgstr "自动更新gfw列表并重启adh"
217 |
218 | msgid "Please change time and args in crontab"
219 | msgstr "请在计划任务中修改时间和参数"
220 |
221 | msgid "Download links for update"
222 | msgstr "升级用的下载链接"
223 |
224 | #/cgi-bin/luci/admin/services/AdGuardHome/log/
225 | msgid "reverse"
226 | msgstr "逆序"
227 |
228 | msgid "localtime"
229 | msgstr "本地时间"
230 |
231 | msgid "Please add log path in config to enable log"
232 | msgstr "请在设置里填写日志路径以启用日志"
233 |
234 | msgid "dellog"
235 | msgstr "删除日志"
236 |
237 | msgid "download log"
238 | msgstr "下载日志"
239 |
240 | #/cgi-bin/luci//admin/services/AdGuardHome/manual/
241 | msgid "Use template"
242 | msgstr "使用模板"
243 | #hide button
244 | msgid "Reload Config"
245 | msgstr "重新载入配置"
246 |
247 | msgid "WARNING!!! no bin found apply config will not be test"
248 | msgstr "警告!!!未找到执行文件,提交配置将不会进行校验"
249 | #unused
250 | msgid "Change browser management username"
251 | msgstr "改变网页登录用户名"
252 |
253 | msgid "Username"
254 | msgstr "用户名"
255 |
256 | msgid "Check Config"
257 | msgstr "检查配置"
258 |
259 | msgid "unknown"
260 | msgstr "未知"
261 |
262 | msgid "Keep database when system upgrade"
263 | msgstr "系统升级时保留数据"
264 |
265 | msgid "Boot delay until network ok"
266 | msgstr "开机时直到网络准备好再启动"
--------------------------------------------------------------------------------
/luci-app-adguardhome/root/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaoxiao29/luci-app-adguardhome/1497e52aa13fca2851accef13c96b8c558e33911/luci-app-adguardhome/root/.DS_Store
--------------------------------------------------------------------------------
/luci-app-adguardhome/root/etc/config/AdGuardHome:
--------------------------------------------------------------------------------
1 | config AdGuardHome 'AdGuardHome'
2 | option enabled '0'
3 | option httpport '3000'
4 | option redirect 'none'
5 | option configpath '/etc/config/adGuardConfig/AdGuardHome.yaml'
6 | option workdir '/etc/config/adGuardConfig/workspace'
7 | option logfile '/tmp/log/AdGuardHome.log'
8 | option verbose '0'
9 | option binpath '/etc/config/adGuardConfig/AdGuardHome'
10 | option upxflag ''
11 |
--------------------------------------------------------------------------------
/luci-app-adguardhome/root/etc/init.d/AdGuardHome:
--------------------------------------------------------------------------------
1 | #!/bin/sh /etc/rc.common
2 |
3 | USE_PROCD=1
4 |
5 | START=95
6 | STOP=01
7 |
8 | CONFIGURATION=AdGuardHome
9 | CRON_FILE=/etc/crontabs/root
10 | EXTRA_COMMANDS="do_redirect testbackup test_crontab force_reload isrunning"
11 | EXTRA_HELP=" do_redirect 0 or 1\
12 | testbackup backup or restore\
13 | test_crontab
14 | force_reload
15 | isrunning"
16 | set_forward_dnsmasq()
17 | {
18 | local PORT="$1"
19 | addr="127.0.0.1#$PORT"
20 | OLD_SERVER="`uci get dhcp.@dnsmasq[0].server 2>/dev/null`"
21 | echo $OLD_SERVER | grep "^$addr" >/dev/null 2>&1
22 | if [ $? -eq 0 ]; then
23 | return
24 | fi
25 | uci delete dhcp.@dnsmasq[0].server 2>/dev/null
26 | uci add_list dhcp.@dnsmasq[0].server=$addr
27 | for server in $OLD_SERVER; do
28 | if [ "$server" = "$addr" ]; then
29 | continue
30 | fi
31 | uci add_list dhcp.@dnsmasq[0].server=$server
32 | done
33 | uci delete dhcp.@dnsmasq[0].resolvfile 2>/dev/null
34 | uci set dhcp.@dnsmasq[0].noresolv=1
35 | uci commit dhcp
36 | /etc/init.d/dnsmasq restart
37 | }
38 |
39 | stop_forward_dnsmasq()
40 | {
41 | local OLD_PORT="$1"
42 | addr="127.0.0.1#$OLD_PORT"
43 | OLD_SERVER="`uci get dhcp.@dnsmasq[0].server 2>/dev/null`"
44 | echo $OLD_SERVER | grep "^$addr" >/dev/null 2>&1
45 | if [ $? -ne 0 ]; then
46 | return
47 | fi
48 |
49 | uci del_list dhcp.@dnsmasq[0].server=$addr 2>/dev/null
50 | addrlist="`uci get dhcp.@dnsmasq[0].server 2>/dev/null`"
51 | if [ -z "$addrlist" ] ; then
52 | uci set dhcp.@dnsmasq[0].resolvfile=/tmp/resolv.conf.auto 2>/dev/null
53 | uci delete dhcp.@dnsmasq[0].noresolv 2>/dev/null
54 | fi
55 | uci commit dhcp
56 | /etc/init.d/dnsmasq restart
57 | }
58 |
59 | set_iptable()
60 | {
61 | local ipv6_server=$1
62 | local tcp_server=$2
63 | uci -q batch <<-EOF >/dev/null 2>&1
64 | delete firewall.AdGuardHome
65 | set firewall.AdGuardHome=include
66 | set firewall.AdGuardHome.type=script
67 | set firewall.AdGuardHome.path=/usr/share/AdGuardHome/firewall.start
68 | set firewall.AdGuardHome.reload=1
69 | commit firewall
70 | EOF
71 |
72 | IPS="`ifconfig | grep "inet addr" | grep -v ":127" | grep "Bcast" | awk '{print $2}' | awk -F : '{print $2}'`"
73 | for IP in $IPS
74 | do
75 | if [ "$tcp_server" == "1" ]; then
76 | iptables -t nat -A PREROUTING -p tcp -d $IP --dport 53 -j REDIRECT --to-ports $AdGuardHome_PORT >/dev/null 2>&1
77 | fi
78 | iptables -t nat -A PREROUTING -p udp -d $IP --dport 53 -j REDIRECT --to-ports $AdGuardHome_PORT >/dev/null 2>&1
79 | done
80 |
81 | if [ "$ipv6_server" == 0 ]; then
82 | return
83 | fi
84 |
85 | IPS="`ifconfig | grep "inet6 addr" | grep -v " fe80::" | grep -v " ::1" | grep "Global" | awk '{print $3}'`"
86 | for IP in $IPS
87 | do
88 | if [ "$tcp_server" == "1" ]; then
89 | ip6tables -t nat -A PREROUTING -p tcp -d $IP --dport 53 -j REDIRECT --to-ports $AdGuardHome_PORT >/dev/null 2>&1
90 | fi
91 | ip6tables -t nat -A PREROUTING -p udp -d $IP --dport 53 -j REDIRECT --to-ports $AdGuardHome_PORT >/dev/null 2>&1
92 | done
93 |
94 | }
95 |
96 | clear_iptable()
97 | {
98 | uci -q batch <<-EOF >/dev/null 2>&1
99 | delete firewall.AdGuardHome
100 | commit firewall
101 | EOF
102 | local OLD_PORT="$1"
103 | local ipv6_server=$2
104 | IPS="`ifconfig | grep "inet addr" | grep -v ":127" | grep "Bcast" | awk '{print $2}' | awk -F : '{print $2}'`"
105 | for IP in $IPS
106 | do
107 | iptables -t nat -D PREROUTING -p udp -d $IP --dport 53 -j REDIRECT --to-ports $OLD_PORT >/dev/null 2>&1
108 | iptables -t nat -D PREROUTING -p tcp -d $IP --dport 53 -j REDIRECT --to-ports $OLD_PORT >/dev/null 2>&1
109 | done
110 |
111 | if [ "$ipv6_server" == 0 ]; then
112 | return
113 | fi
114 | echo "warn ip6tables nat mod is needed"
115 | IPS="`ifconfig | grep "inet6 addr" | grep -v " fe80::" | grep -v " ::1" | grep "Global" | awk '{print $3}'`"
116 | for IP in $IPS
117 | do
118 | ip6tables -t nat -D PREROUTING -p udp -d $IP --dport 53 -j REDIRECT --to-ports $OLD_PORT >/dev/null 2>&1
119 | ip6tables -t nat -D PREROUTING -p tcp -d $IP --dport 53 -j REDIRECT --to-ports $OLD_PORT >/dev/null 2>&1
120 | done
121 |
122 | }
123 |
124 | service_triggers() {
125 | procd_add_reload_trigger "$CONFIGURATION"
126 | [ "$(uci get AdGuardHome.AdGuardHome.redirect)" == "redirect" ] && procd_add_reload_trigger firewall
127 | }
128 | isrunning(){
129 | config_load "${CONFIGURATION}"
130 | _isrunning
131 | local r=$?
132 | ([ "$r" == "0" ] && echo "running") || ([ "$r" == "1" ] && echo "not run" ) || echo "no bin"
133 | return $r
134 | }
135 | _isrunning(){
136 | config_get binpath $CONFIGURATION binpath "/etc/config/adGuardConfig/AdGuardHome"
137 | [ ! -f "$binpath" ] && return 2
138 | pgrep $binpath 2>&1 >/dev/null && return 0
139 | return 1
140 | }
141 | force_reload(){
142 | config_load "${CONFIGURATION}"
143 | _isrunning && procd_send_signal "$CONFIGURATION" || start
144 | }
145 | get_tz()
146 | {
147 | SET_TZ=""
148 |
149 | if [ -e "/etc/localtime" ]; then
150 | return
151 | fi
152 |
153 | for tzfile in /etc/TZ /var/etc/TZ
154 | do
155 | if [ ! -e "$tzfile" ]; then
156 | continue
157 | fi
158 |
159 | tz="`cat $tzfile 2>/dev/null`"
160 | done
161 |
162 | if [ -z "$tz" ]; then
163 | return
164 | fi
165 |
166 | SET_TZ=$tz
167 | }
168 |
169 | rm_port53()
170 | {
171 | local AdGuardHome_PORT=$(config_editor "dns.port" "" "$configpath" "1")
172 | dnsmasq_port=$(uci get dhcp.@dnsmasq[0].port 2>/dev/null)
173 | if [ -z "$dnsmasq_port" ]; then
174 | dnsmasq_port="53"
175 | fi
176 | if [ "$dnsmasq_port" == "$AdGuardHome_PORT" ]; then
177 | if [ "$dnsmasq_port" == "53" ]; then
178 | dnsmasq_port="1745"
179 | fi
180 | elif [ "$dnsmasq_port" == "53" ]; then
181 | return
182 | fi
183 | config_editor "dns.port" "$dnsmasq_port" "$configpath"
184 | uci set dhcp.@dnsmasq[0].port="53"
185 | uci commit dhcp
186 | /etc/init.d/dnsmasq reload
187 | }
188 |
189 | use_port53()
190 | {
191 | local AdGuardHome_PORT=$(config_editor "dns.port" "" "$configpath" "1")
192 | dnsmasq_port=$(uci get dhcp.@dnsmasq[0].port 2>/dev/null)
193 | if [ -z "$dnsmasq_port" ]; then
194 | dnsmasq_port="53"
195 | fi
196 | if [ "$dnsmasq_port" == "$AdGuardHome_PORT" ]; then
197 | if [ "$dnsmasq_port" == "53" ]; then
198 | AdGuardHome_PORT="1745"
199 | fi
200 | elif [ "$AdGuardHome_PORT" == "53" ]; then
201 | return
202 | fi
203 | config_editor "dns.port" "53" "$configpath"
204 | uci set dhcp.@dnsmasq[0].port="$AdGuardHome_PORT"
205 | uci commit dhcp
206 | /etc/init.d/dnsmasq reload
207 | }
208 | do_redirect()
209 | {
210 | config_load "${CONFIGURATION}"
211 | _do_redirect $1
212 | }
213 | _do_redirect()
214 | {
215 | local section="$CONFIGURATION"
216 | args=""
217 | ipv6_server=1
218 | tcp_server=0
219 | enabled=$1
220 | if [ "$enabled" == "1" ]; then
221 | echo -n "1">/var/run/AdGredir
222 | else
223 | echo -n "0">/var/run/AdGredir
224 | fi
225 | config_get configpath $CONFIGURATION configpath "/etc/config/adGuardConfig/AdGuardHome.yaml"
226 | AdGuardHome_PORT=$(config_editor "dns.port" "" "$configpath" "1")
227 | if [ -z "$AdGuardHome_PORT" ]; then
228 | AdGuardHome_PORT="0"
229 | fi
230 | config_get "redirect" "$section" "redirect" "none"
231 | config_get "old_redirect" "$section" "old_redirect" "none"
232 | config_get "old_port" "$section" "old_port" "0"
233 | config_get "old_enabled" "$section" "old_enabled" "0"
234 | uci get dhcp.@dnsmasq[0].port >/dev/null 2>&1 || uci set dhcp.@dnsmasq[0].port="53" >/dev/null 2>&1
235 | if [ "$old_enabled" = "1" -a "$old_redirect" == "exchange" ]; then
236 | AdGuardHome_PORT=$(uci get dhcp.@dnsmasq[0].port 2>/dev/null)
237 | fi
238 |
239 | if [ "$old_redirect" != "$redirect" ] || [ "$old_port" != "$AdGuardHome_PORT" ] || [ "$old_enabled" = "1" -a "$enabled" = "0" ]; then
240 | if [ "$old_redirect" != "none" ]; then
241 | if [ "$old_redirect" == "redirect" -a "$old_port" != "0" ]; then
242 | clear_iptable "$old_port" "$ipv6_server"
243 | elif [ "$old_redirect" == "dnsmasq-upstream" ]; then
244 | stop_forward_dnsmasq "$old_port"
245 | elif [ "$old_redirect" == "exchange" ]; then
246 | rm_port53
247 | fi
248 | fi
249 | elif [ "$old_enabled" = "1" -a "$enabled" = "1" ]; then
250 | if [ "$old_redirect" == "redirect" -a "$old_port" != "0" ]; then
251 | clear_iptable "$old_port" "$ipv6_server"
252 | fi
253 | fi
254 | uci delete AdGuardHome.@AdGuardHome[0].old_redirect 2>/dev/null
255 | uci delete AdGuardHome.@AdGuardHome[0].old_port 2>/dev/null
256 | uci delete AdGuardHome.@AdGuardHome[0].old_enabled 2>/dev/null
257 | uci add_list AdGuardHome.@AdGuardHome[0].old_redirect="$redirect" 2>/dev/null
258 | uci add_list AdGuardHome.@AdGuardHome[0].old_port="$AdGuardHome_PORT" 2>/dev/null
259 | uci add_list AdGuardHome.@AdGuardHome[0].old_enabled="$enabled" 2>/dev/null
260 | uci commit AdGuardHome
261 | [ "$enabled" == "0" ] && return 1
262 | if [ "$AdGuardHome_PORT" == "0" ]; then
263 | return 1
264 | fi
265 | if [ "$redirect" = "redirect" ]; then
266 | set_iptable $ipv6_server $tcp_server
267 | elif [ "$redirect" = "dnsmasq-upstream" ]; then
268 | set_forward_dnsmasq "$AdGuardHome_PORT"
269 | elif [ "$redirect" == "exchange" -a "$(uci get dhcp.@dnsmasq[0].port 2>/dev/null)" == "53" ]; then
270 | use_port53
271 | fi
272 | }
273 | get_filesystem()
274 | {
275 | # print out path filesystem
276 | echo $1 | awk '
277 | BEGIN{
278 | while (("mount"| getline ret) > 0)
279 | {
280 | split(ret,d);
281 | fs[d[3]]=d[5];
282 | m=index(d[1],":")
283 | if (m==0)
284 | {
285 | pt[d[3]]=d[1]
286 | }else{
287 | pt[d[3]]=substr(d[1],m+1)
288 | }}}{
289 | split($0,d,"/");
290 | if ("/" in fs)
291 | {
292 | result1=fs["/"];
293 | }
294 | if ("/" in pt)
295 | {
296 | result2=pt["/"];
297 | }
298 | for (i=2;i<=length(d);i++)
299 | {
300 | p[i]=p[i-1]"/"d[i];
301 | if (p[i] in fs)
302 | {
303 | result1=fs[p[i]];
304 | result2=pt[p[i]];
305 | }
306 | }
307 | if (result2 in fs){
308 | result=fs[result2]}
309 | else{
310 | result=result1}
311 | print(result);}'
312 | }
313 |
314 | config_editor()
315 | {
316 | awk -v yaml="$1" -v value="$2" -v file="$3" -v ro="$4" '
317 | BEGIN{split(yaml,part,"\.");s="";i=1;l=length(part);}
318 | {
319 | if (match($0,s""part[i]":"))
320 | {
321 | if (i==l)
322 | {
323 | split($0,t,": ");
324 | if (ro==""){
325 | system("sed -i '\''"FNR"c \\"t[1]": "value"'\'' "file);
326 | }else{
327 | print(t[2]);
328 | }
329 | exit;
330 | }
331 | s=s"[- ]{2}";
332 | i++;
333 | }
334 | }' $3
335 | }
336 |
337 | boot_service() {
338 | rm /var/run/AdGserverdis >/dev/null 2>&1
339 | config_load "${CONFIGURATION}"
340 | config_get waitonboot $CONFIGURATION waitonboot "0"
341 | config_get_bool enabled $CONFIGURATION enabled 0
342 | config_get binpath $CONFIGURATION binpath "/etc/config/adGuardConfig/AdGuardHome"
343 | [ -f "$binpath" ] && start_service
344 | if [ "$enabled" == "1" ] && [ "$waitonboot" == "1" ]; then
345 | procd_open_instance "waitnet"
346 | procd_set_param command "/usr/share/AdGuardHome/waitnet.sh"
347 | procd_close_instance
348 | echo "no net start pinging"
349 | fi
350 | }
351 |
352 | testbackup(){
353 | config_load "${CONFIGURATION}"
354 | if [ "$1" == "backup" ]; then
355 | backup
356 | elif [ "$1" == "restore" ]; then
357 | restore
358 | fi
359 | }
360 | restore()
361 | {
362 | config_get workdir $CONFIGURATION workdir "/etc/config/adGuardConfig/workspace"
363 | config_get backupwdpath $CONFIGURATION backupwdpath "/etc/config/adGuardConfig/workspace"
364 | cp -u -r -f $backupwdpath/data $workdir
365 | }
366 | backup() {
367 | config_get backupwdpath $CONFIGURATION backupwdpath "/etc/config/adGuardConfig/workspace"
368 | mkdir -p $backupwdpath/data
369 | config_get workdir $CONFIGURATION workdir "/etc/config/adGuardConfig/workspace"
370 | config_get backupfile $CONFIGURATION backupfile ""
371 | for one in $backupfile;
372 | do
373 | while :
374 | do
375 | if [ -d "$backupwdpath/data/$one" ]; then
376 | cpret=$(cp -u -r -f $workdir/data/$one $backupwdpath/data 2>&1)
377 | else
378 | cpret=$(cp -u -r -f $workdir/data/$one $backupwdpath/data/$one 2>&1)
379 | fi
380 | echo "$cpret"
381 | echo "$cpret" | grep "no space left on device"
382 | if [ "$?" == "0" ]; then
383 | echo "磁盘已满,删除log重试中"
384 | del_querylog && continue
385 | rm -f -r $backupwdpath/data/filters
386 | rm -f -r $workdir/data/filters && continue
387 | echo "backup failed"
388 | fi
389 | break
390 | done
391 | done
392 | }
393 | start_service() {
394 | # Reading config
395 | rm /var/run/AdGserverdis >/dev/null 2>&1
396 | config_load "${CONFIGURATION}"
397 | # update password
398 | config_get hashpass $CONFIGURATION hashpass ""
399 | config_get configpath $CONFIGURATION configpath "/etc/config/adGuardConfig/AdGuardHome.yaml"
400 | if [ -n "$hashpass" ]; then
401 | config_editor "users.password" "$hashpass" "$configpath"
402 | uci set $CONFIGURATION.$CONFIGURATION.hashpass=""
403 | fi
404 | local enabled
405 | config_get_bool enabled $CONFIGURATION enabled 0
406 | # update crontab
407 | do_crontab
408 | if [ "$enabled" == "0" ]; then
409 | _do_redirect 0
410 | return
411 | fi
412 | #what need to do before reload
413 | config_get workdir $CONFIGURATION workdir "/etc/config/adGuardConfig/workspace"
414 |
415 | config_get backupfile $CONFIGURATION backupfile ""
416 | mkdir -p $workdir/data
417 | if [ -n "$backupfile" ] && [ ! -d "$workdir/data" ]; then
418 | restore
419 | fi
420 | # for overlay data-stk-oo not suppport
421 | local cwdfs=$(get_filesystem $workdir)
422 | echo "workdir is a $cwdfs filesystem"
423 | if [ "$cwdfs" == "jffs2" ]; then
424 | echo "fs error ln db to tmp $workdir $cwdfs"
425 | logger "AdGuardHome" "warning db redirect to tmp"
426 | touch $workdir/data/stats.db
427 | if [ ! -L $workdir/data/stats.db ]; then
428 | mv -f $workdir/data/stats.db /tmp/stats.db 2>/dev/null
429 | ln -s /tmp/stats.db $workdir/data/stats.db 2>/dev/null
430 | fi
431 | touch $workdir/data/sessions.db
432 | if [ ! -L $workdir/data/sessions.db ]; then
433 | mv -f $workdir/data/sessions.db /tmp/sessions.db 2>/dev/null
434 | ln -s /tmp/sessions.db $workdir/data/sessions.db 2>/dev/null
435 | fi
436 | fi
437 | local ADDITIONAL_ARGS=""
438 | config_get binpath $CONFIGURATION binpath "/etc/config/adGuardConfig/AdGuardHome"
439 |
440 | mkdir -p ${binpath%/*}
441 | ADDITIONAL_ARGS="$ADDITIONAL_ARGS -c $configpath"
442 | ADDITIONAL_ARGS="$ADDITIONAL_ARGS -w $workdir"
443 | config_get httpport $CONFIGURATION httpport 3000
444 | ADDITIONAL_ARGS="$ADDITIONAL_ARGS -p $httpport"
445 |
446 | # hack to save config file when upgrade system
447 | config_get upprotect $CONFIGURATION upprotect ""
448 | eval upprotect=${upprotect// /\\\\n}
449 | echo -e "$upprotect">/lib/upgrade/keep.d/luci-app-adguardhome
450 |
451 | config_get logfile $CONFIGURATION logfile ""
452 | if [ -n "$logfile" ]; then
453 | ADDITIONAL_ARGS="$ADDITIONAL_ARGS -l $logfile"
454 | fi
455 |
456 | if [ ! -f "$binpath" ]; then
457 | _do_redirect 0
458 | /usr/share/AdGuardHome/update_core.sh 2>&1 >/tmp/AdGuardHome_update.log &
459 | exit 0
460 | fi
461 |
462 | config_get_bool verbose $CONFIGURATION verbose 0
463 | if [ "$verbose" -eq 1 ]; then
464 | ADDITIONAL_ARGS="$ADDITIONAL_ARGS -v"
465 | fi
466 |
467 | procd_open_instance
468 | get_tz
469 | if [ -n "$SET_TZ" ]; then
470 | procd_set_param env TZ="$SET_TZ"
471 | fi
472 | procd_set_param respawn ${respawn_threshold:-3600} ${respawn_timeout:-5} ${respawn_retry:-5}
473 | procd_set_param limits core="unlimited" nofile="65535 65535"
474 | procd_set_param stderr 1
475 | procd_set_param command $binpath $ADDITIONAL_ARGS
476 | procd_set_param file "$configpath" "/etc/hosts" "/etc/config/AdGuardHome"
477 | procd_close_instance
478 | if [ -f "$configpath" ]; then
479 | _do_redirect 1
480 | else
481 | _do_redirect 0
482 | config_get "redirect" "AdGuardHome" "redirect" "none"
483 | if [ "$redirect" != "none" ]; then
484 | procd_open_instance "waitconfig"
485 | procd_set_param command "/usr/share/AdGuardHome/watchconfig.sh"
486 | procd_close_instance
487 | echo "no config start watching"
488 | fi
489 | fi
490 | echo "AdGuardHome service enabled"
491 | echo "luci enable switch=$enabled"
492 | (sleep 10 && [ -z "$(pgrep $binpath)" ] && logger "AdGuardHome" "no process in 10s cancel redirect" && _do_redirect 0 )&
493 | }
494 | reload_service()
495 | {
496 | rm /var/run/AdGlucitest >/dev/null 2>&1
497 | echo "AdGuardHome reloading"
498 | start
499 | }
500 |
501 | del_querylog(){
502 | local btarget=$(ls $backupwdpath/data | grep -F "querylog.json" | sort -r | head -n 1)
503 | local wtarget=$(ls $workdir/data | grep -F "querylog.json" | sort -r | head -n 1)
504 | if [ "$btarget"x == "$wtarget"x ]; then
505 | [ -z "$btarget" ] && return 1
506 | rm -f $workdir/data/$wtarget
507 | rm -f $backupwdpath/data/$btarget
508 | return 0
509 | fi
510 | if [ "$btarget" \> "$wtarget" ]; then
511 | rm -f $backupwdpath/data/$btarget
512 | return 0
513 | else
514 | rm -f $workdir/data/$wtarget
515 | return 0
516 | fi
517 | }
518 | stop_service()
519 | {
520 | config_load "${CONFIGURATION}"
521 | _do_redirect 0
522 | do_crontab
523 | if [ "$1" != "nobackup" ]; then
524 | config_get backupfile $CONFIGURATION backupfile "0"
525 | if [ -n "$backupfile" ]; then
526 | backup
527 | fi
528 | fi
529 | echo "AdGuardHome service disabled"
530 | touch /var/run/AdGserverdis
531 | }
532 | boot() {
533 | rc_procd boot_service "$@"
534 | if eval "type service_started" 2>/dev/null >/dev/null; then
535 | service_started
536 | fi
537 | }
538 | test_crontab(){
539 | config_load "${CONFIGURATION}"
540 | do_crontab
541 | }
542 | do_crontab(){
543 | config_get_bool enabled $CONFIGURATION enabled 0
544 | config_get crontab $CONFIGURATION crontab ""
545 | local findstr default cronenable replace commit
546 | local cronreload=0
547 | local commit=0
548 | findstr="/usr/share/AdGuardHome/update_core.sh"
549 | default="30 3 * * * /usr/share/AdGuardHome/update_core.sh 2>&1"
550 | [ "$enabled" == "0" ] || [ "${crontab//autoupdate/}" == "$crontab" ] && cronenable=0 || cronenable=1
551 | crontab_editor
552 |
553 | config_get workdir $CONFIGURATION workdir "/etc/config/adGuardConfig/workspace"
554 | config_get lastworkdir $CONFIGURATION lastworkdir "/etc/config/adGuardConfig/workspace"
555 | findstr="/usr/share/AdGuardHome/tailto.sh [0-9]* \$(uci get AdGuardHome.AdGuardHome.workdir)/data/querylog.json"
556 | #[ -n "$lastworkdir" ] && findstr="/usr/share/AdGuardHome/tailto.sh [0-9]* $lastworkdir/data/querylog.json" && [ "$lastworkdir" != "$workdir" ] && replace="${lastworkdir//\//\\/}/${workdir//\//\\/}"
557 | default="0 * * * * /usr/share/AdGuardHome/tailto.sh 2000 \$(uci get AdGuardHome.AdGuardHome.workdir)/data/querylog.json"
558 | [ "$enabled" == "0" ] || [ "${crontab//cutquerylog/}" == "$crontab" ] && cronenable=0 || cronenable=1
559 | crontab_editor
560 | #[ "$lastworkdir" != "$workdir" ] && uci set AdGuardHome.AdGuardHome.lastworkdir="$workdir" && commit=1
561 |
562 | config_get logfile $CONFIGURATION logfile ""
563 | config_get lastlogfile $CONFIGURATION lastlogfile ""
564 | findstr="/usr/share/AdGuardHome/tailto.sh [0-9]* \$(uci get AdGuardHome.AdGuardHome.logfile)"
565 | default="30 3 * * * /usr/share/AdGuardHome/tailto.sh 2000 \$(uci get AdGuardHome.AdGuardHome.logfile)"
566 | #[ -n "$lastlogfile" ] && findstr="/usr/share/AdGuardHome/tailto.sh [0-9]* $lastlogfile" && [ -n "$logfile" ] && [ "$lastlogfile" != "$logfile" ] && replace="${lastlogfile//\//\\/}/${logfile//\//\\/}"
567 | [ "$logfile" == "syslog" ] || [ "$logfile" == "" ] || [ "$enabled" == "0" ] || [ "${crontab//cutruntimelog/}" == "$crontab" ] && cronenable=0 || cronenable=1
568 | crontab_editor
569 | #[ -n "$logfile" ] && [ "$lastlogfile" != "$logfile" ] && uci set AdGuardHome.AdGuardHome.lastlogfile="$logfile" && commit=1
570 |
571 | findstr="/usr/share/AdGuardHome/addhost.sh"
572 | default="0 * * * * /usr/share/AdGuardHome/addhost.sh"
573 | [ "$enabled" == "0" ] || [ "${crontab//autohost/}" == "$crontab" ] && cronenable=0 || cronenable=1
574 | crontab_editor
575 | [ "$cronenable" == "0" ] && /usr/share/AdGuardHome/addhost.sh "del" "noreload" || /usr/share/AdGuardHome/addhost.sh "" "noreload"
576 |
577 | findstr="/usr/share/AdGuardHome/gfw2adg.sh"
578 | default="30 3 * * * /usr/share/AdGuardHome/gfw2adg.sh"
579 | [ "$enabled" == "0" ] || [ "${crontab//autogfw/}" == "$crontab" ] && cronenable=0 || cronenable=1
580 | crontab_editor
581 | [ "$cronreload" -gt 0 ] && /etc/init.d/cron restart
582 | #[ "$commit" -gt 0 ] && uci commit AdGuardHome
583 | }
584 | crontab_editor(){
585 | #usage input:
586 | #findstr=
587 | #default=
588 | #cronenable=
589 | #replace="${last//\//\\/}/${now//\//\\/}"
590 | #output:cronreload:if >1 please /etc/init.d/cron restart manual
591 | local testline reload
592 | local line="$(grep "$findstr" $CRON_FILE)"
593 | [ -n "$replace" ] && [ -n "$line" ] && eval testline="\${line//$replace}" && [ "$testline" != "$line" ] && line="$testline" && reload="1" && replace=""
594 | if [ "${line:0:1}" != "#" ]; then
595 | if [ $cronenable -eq 1 ]; then
596 | [ -z "$line" ] && line="$default" && reload="1"
597 | if [ -n "$reload" ]; then
598 | sed -i "\,$findstr,d" $CRON_FILE
599 | echo "$line" >> $CRON_FILE
600 | cronreload=$((cronreload+1))
601 | fi
602 | elif [ -n "$line" ]; then
603 | sed -i "\,$findstr,d" $CRON_FILE
604 | echo "#$line" >> $CRON_FILE
605 | cronreload=$((cronreload+1))
606 | fi
607 | else
608 | if [ $cronenable -eq 1 ]; then
609 | sed -i "\,$findstr,d" $CRON_FILE
610 | echo "${line:1}" >> $CRON_FILE
611 | cronreload=$((cronreload+1))
612 | elif [ -z "$reload" ]; then
613 | sed -i "\,$findstr,d" $CRON_FILE
614 | echo "$line" >> $CRON_FILE
615 | fi
616 | fi
617 |
618 | }
619 |
--------------------------------------------------------------------------------
/luci-app-adguardhome/root/etc/uci-defaults/40_luci-AdGuardHome:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | uci -q batch <<-EOF >/dev/null 2>&1
4 | delete ucitrack.@AdGuardHome[-1]
5 | add ucitrack AdGuardHome
6 | set ucitrack.@AdGuardHome[-1].init=AdGuardHome
7 | commit ucitrack
8 | delete AdGuardHome.AdGuardHome.ucitracktest
9 | EOF
10 |
11 | rm -f /tmp/luci-indexcache
12 | exit 0
13 |
--------------------------------------------------------------------------------
/luci-app-adguardhome/root/usr/share/AdGuardHome/AdGuardHome_template.yaml:
--------------------------------------------------------------------------------
1 | #提交就可以直接用的配置模板文件
2 | #a template config can be use with a apply
3 | bind_host: 0.0.0.0
4 | bind_port: 3000
5 | users:
6 | - name: root
7 | password: $2y$10$FfeQavihMUiXCuJhHuQwy.6EOXDvkXb/S50qI5fXizqarNT/ShhQm
8 | language: ""
9 | rlimit_nofile: 0
10 | dns:
11 | bind_host: 0.0.0.0
12 | port: 5553
13 | statistics_interval: 1
14 | protection_enabled: true
15 | filtering_enabled: true
16 | filters_update_interval: 24
17 | blocking_mode: nxdomain
18 | blocked_response_ttl: 10
19 | querylog_enabled: false
20 | querylog_interval: 1
21 | ratelimit: 0
22 | ratelimit_whitelist: []
23 | refuse_any: false
24 | bootstrap_dns:
25 | #bootstrap_dns
26 | all_servers: false
27 | allowed_clients: []
28 | disallowed_clients: []
29 | blocked_hosts: []
30 | parental_block_host: ""
31 | safebrowsing_block_host: ""
32 | blocked_services: []
33 | cache_size: 4194304
34 | parental_sensitivity: 13
35 | parental_enabled: false
36 | safesearch_enabled: false
37 | safebrowsing_enabled: false
38 | safebrowsing_cache_size: 1048576
39 | safesearch_cache_size: 1048576
40 | parental_cache_size: 1048576
41 | cache_time: 30
42 | rewrites: []
43 | upstream_dns:
44 | #upstream_dns
45 | tls:
46 | enabled: false
47 | server_name: ""
48 | force_https: false
49 | port_https: 443
50 | port_dns_over_tls: 853
51 | certificate_chain: ""
52 | private_key: ""
53 | certificate_path: ""
54 | private_key_path: ""
55 | filters:
56 | - enabled: true
57 | url: https://adguardteam.github.io/AdGuardSDNSFilter/Filters/filter.txt
58 | name: AdGuard Simplified Domain Names filter
59 | id: 1
60 | - enabled: true
61 | url: https://adaway.org/hosts.txt
62 | name: AdAway
63 | id: 2
64 | - enabled: false
65 | url: https://hosts-file.net/ad_servers.txt
66 | name: hpHosts - Ad and Tracking servers only
67 | id: 3
68 | - enabled: true
69 | url: https://www.malwaredomainlist.com/hostslist/hosts.txt
70 | name: MalwareDomainList.com Hosts List
71 | id: 4
72 | - enabled: false
73 | url: https://raw.githubusercontent.com/vokins/yhosts/master/data/tvbox.txt
74 | name: tvbox
75 | id: 1575018007
76 | - enabled: true
77 | url: https://hosts.nfz.moe/full/hosts
78 | name: neoHosts full
79 | id: 1575618240
80 | - enabled: false
81 | url: https://hosts.nfz.moe/basic/hosts
82 | name: neoHosts basic
83 | id: 1575618241
84 | - enabled: false
85 | url: http://sbc.io/hosts/hosts
86 | name: StevenBlack host basic
87 | id: 1575618242
88 | - enabled: false
89 | url: http://sbc.io/hosts/alternates/fakenews-gambling-porn-social/hosts
90 | name: StevenBlack host+fakenews + gambling + porn + social
91 | id: 1575618243
92 | - enabled: false
93 | url: https://cdn.jsdelivr.net/gh/privacy-protection-tools/anti-AD/anti-ad-easylist.txt
94 | name: anti-AD(Adblock+neohosts+yhosts+cjxlist+adhlist)
95 | id: 1577113202
96 | user_rules: []
97 | dhcp:
98 | enabled: false
99 | interface_name: ""
100 | gateway_ip: ""
101 | subnet_mask: ""
102 | range_start: ""
103 | range_end: ""
104 | lease_duration: 86400
105 | icmp_timeout_msec: 1000
106 | clients: []
107 | log_file: ""
108 | verbose: false
109 | schema_version: 5
--------------------------------------------------------------------------------
/luci-app-adguardhome/root/usr/share/AdGuardHome/addhost.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | checkmd5(){
3 | local nowmd5=$(md5sum /etc/hosts)
4 | nowmd5=${nowmd5%% *}
5 | local lastmd5=$(uci get AdGuardHome.AdGuardHome.hostsmd5 2>/dev/null)
6 | if [ "$nowmd5" != "$lastmd5" ]; then
7 | uci set AdGuardHome.AdGuardHome.hostsmd5="$nowmd5"
8 | uci commit AdGuardHome
9 | [ "$1" == "noreload" ] || /etc/init.d/AdGuardHome reload
10 | fi
11 | }
12 | [ "$1" == "del" ] && sed -i '/programaddstart/,/programaddend/d' /etc/hosts && checkmd5 "$2" && exit 0
13 | /usr/bin/awk 'BEGIN{
14 | while ((getline < "/tmp/dhcp.leases") > 0)
15 | {
16 | a[$2]=$4;
17 | }
18 | while (("ip -6 neighbor show | grep -v fe80" | getline) > 0)
19 | {
20 | if (a[$5]) {print $1" "a[$5] >"/tmp/tmphost"; }
21 | }
22 | print "#programaddend" >"/tmp/tmphost";
23 | }'
24 | grep programaddstart /etc/hosts >/dev/null 2>&1
25 | if [ "$?" == "0" ]; then
26 | sed -i '/programaddstart/,/programaddend/c\#programaddstart' /etc/hosts
27 | sed -i '/programaddstart/'r/tmp/tmphost /etc/hosts
28 | else
29 | echo "#programaddstart" >>/etc/hosts
30 | cat /tmp/tmphost >> /etc/hosts
31 | fi
32 | rm /tmp/tmphost
33 | checkmd5 "$2"
--------------------------------------------------------------------------------
/luci-app-adguardhome/root/usr/share/AdGuardHome/firewall.start:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | AdGuardHome_enable=$(uci get AdGuardHome.AdGuardHome.enabled)
4 | redirect=$(uci get AdGuardHome.AdGuardHome.redirect)
5 |
6 | if [ $AdGuardHome_enable -eq 1 -a "$redirect" == "redirect" ]; then
7 | /etc/init.d/AdGuardHome do_redirect 1
8 | fi
9 |
--------------------------------------------------------------------------------
/luci-app-adguardhome/root/usr/share/AdGuardHome/getsyslog.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | PATH="/usr/sbin:/usr/bin:/sbin:/bin"
3 | logread -e AdGuardHome > /tmp/AdGuardHometmp.log
4 | logread -e AdGuardHome -f >> /tmp/AdGuardHometmp.log &
5 | pid=$!
6 | echo "1">/var/run/AdGuardHomesyslog
7 | while true
8 | do
9 | sleep 12
10 | watchdog=$(cat /var/run/AdGuardHomesyslog)
11 | if [ "$watchdog"x == "0"x ]; then
12 | kill $pid
13 | rm /tmp/AdGuardHometmp.log
14 | rm /var/run/AdGuardHomesyslog
15 | exit 0
16 | else
17 | echo "0">/var/run/AdGuardHomesyslog
18 | fi
19 | done
--------------------------------------------------------------------------------
/luci-app-adguardhome/root/usr/share/AdGuardHome/gfw2adg.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | PATH="/usr/sbin:/usr/bin:/sbin:/bin"
3 | checkmd5(){
4 | local nowmd5=$(md5sum /tmp/adguard.list 2>/dev/null)
5 | nowmd5=${nowmd5%% *}
6 | local lastmd5=$(uci get AdGuardHome.AdGuardHome.gfwlistmd5 2>/dev/null)
7 |
8 | if [ "$nowmd5" != "$lastmd5" ]; then
9 | uci set AdGuardHome.AdGuardHome.gfwlistmd5="$nowmd5"
10 | uci commit AdGuardHome
11 | [ "$1" == "noreload" ] || /etc/init.d/AdGuardHome reload
12 | fi
13 | }
14 |
15 | configpath=$(uci get AdGuardHome.AdGuardHome.configpath 2>/dev/null)
16 | [ "$1" == "del" ] && sed -i '/programaddstart/,/programaddend/d' $configpath && checkmd5 "$2" && exit 0
17 | gfwupstream=$(uci get AdGuardHome.AdGuardHome.gfwupstream 2>/dev/null)
18 |
19 | if [ -z $gfwupstream ]; then
20 | gfwupstream="tcp://208.67.220.220:5353"
21 | fi
22 |
23 | if [ ! -f "$configpath" ]; then
24 | echo "please make a config first"
25 | exit 1
26 | fi
27 |
28 | wget-ssl --no-check-certificate https://cdn.jsdelivr.net/gh/gfwlist/gfwlist/gfwlist.txt -O- | base64 -d > /tmp/gfwlist.txt
29 | cat /tmp/gfwlist.txt | awk -v upst="$gfwupstream" 'BEGIN{getline;}{
30 | s1=substr($0,1,1);
31 | if (s1=="!")
32 | {next;}
33 | if (s1=="@"){
34 | $0=substr($0,3);
35 | s1=substr($0,1,1);
36 | white=1;}
37 | else{
38 | white=0;
39 | }
40 |
41 | if (s1=="|")
42 | {s2=substr($0,2,1);
43 | if (s2=="|")
44 | {
45 | $0=substr($0,3);
46 | split($0,d,"/");
47 | $0=d[1];
48 | }else{
49 | split($0,d,"/");
50 | $0=d[3];
51 | }}
52 | else{
53 | split($0,d,"/");
54 | $0=d[1];
55 | }
56 | star=index($0,"*");
57 | if (star!=0)
58 | {
59 | $0=substr($0,star+1);
60 | dot=index($0,".");
61 | if (dot!=0)
62 | $0=substr($0,dot+1);
63 | else
64 | next;
65 | s1=substr($0,1,1);
66 | }
67 | if (s1==".")
68 | {fin=substr($0,2);}
69 | else{fin=$0;}
70 | if (index(fin,".")==0) next;
71 | if (index(fin,"%")!=0) next;
72 | if (index(fin,":")!=0) next;
73 | match(fin,"^[0-9\.]+")
74 | if (RSTART==1 && RLENGTH==length(fin)) {print "ipset add gfwlist "fin>"/tmp/doipset.sh";next;}
75 | if (fin=="" || finl==fin) next;
76 | finl=fin;
77 | if (white==0)
78 | {print(" - '\''[/"fin"/]"upst"'\''");}
79 | else{
80 | print(" - '\''[/"fin"/]#'\''");}
81 | }END{print(" - '\''[/programaddend/]#'\''")}' > /tmp/adguard.list
82 |
83 | grep programaddstart $configpath
84 |
85 | if [ "$?" == "0" ]; then
86 | sed -i '/programaddstart/,/programaddend/c\ - '\''\[\/programaddstart\/\]#'\''' $configpath
87 | sed -i '/programaddstart/'r/tmp/adguard.list $configpath
88 | else
89 | sed -i '1i\ - '\''[/programaddstart/]#'\''' /tmp/adguard.list
90 | sed -i '/upstream_dns:/'r/tmp/adguard.list $configpath
91 | fi
92 |
93 | checkmd5 "$2"
94 |
95 | rm -f /tmp/gfwlist.txt /tmp/adguard.list
--------------------------------------------------------------------------------
/luci-app-adguardhome/root/usr/share/AdGuardHome/links.txt:
--------------------------------------------------------------------------------
1 | https://github.com/AdguardTeam/AdGuardHome/releases/download/${latest_ver}/AdGuardHome_linux_${Arch}.tar.gz
2 | https://static.adguard.com/adguardhome/release/AdGuardHome_linux_${Arch}.tar.gz
3 | #https://static.adguard.com/adguardhome/beta/AdGuardHome_linux_${Arch}.tar.gz
--------------------------------------------------------------------------------
/luci-app-adguardhome/root/usr/share/AdGuardHome/tailto.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | tail -n $1 "$2" > /var/run/tailtmp
3 | cat /var/run/tailtmp > "$2"
4 | rm /var/run/tailtmp
--------------------------------------------------------------------------------
/luci-app-adguardhome/root/usr/share/AdGuardHome/update_core.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | PATH="/usr/sbin:/usr/bin:/sbin:/bin"
3 | binpath=$(uci get AdGuardHome.AdGuardHome.binpath)
4 |
5 | if [ -z "$binpath" ]; then
6 | uci set AdGuardHome.AdGuardHome.binpath="/tmp/AdGuardHome/AdGuardHome"
7 | binpath="/tmp/AdGuardHome/AdGuardHome"
8 | fi
9 |
10 | mkdir -p ${binpath%/*}
11 | upxflag=$(uci get AdGuardHome.AdGuardHome.upxflag 2>/dev/null)
12 |
13 | check_if_already_running(){
14 | running_tasks="$(ps |grep "AdGuardHome" |grep "update_core" |grep -v "grep" |awk '{print $1}' |wc -l)"
15 | [ "${running_tasks}" -gt "2" ] && echo -e "\nA task is already running." && EXIT 2
16 | }
17 |
18 | check_wgetcurl(){
19 | which curl && downloader="curl -L -k --retry 2 --connect-timeout 20 -o" && return
20 | which wget-ssl && downloader="wget-ssl --no-check-certificate -t 2 -T 20 -O" && return
21 | [ -z "$1" ] && opkg update || (echo error opkg && EXIT 1)
22 | [ -z "$1" ] && (opkg remove wget wget-nossl --force-depends ; opkg install wget ; check_wgetcurl 1 ;return)
23 | [ "$1" == "1" ] && (opkg install curl ; check_wgetcurl 2 ; return)
24 | echo error curl and wget && EXIT 1
25 | }
26 |
27 | check_latest_version(){
28 | check_wgetcurl
29 | latest_ver="$($downloader - https://api.github.com/repos/AdguardTeam/AdGuardHome/releases/latest 2>/dev/null|grep -E 'tag_name' |grep -E 'v[0-9.]+' -o 2>/dev/null)"
30 |
31 | if [ -z "${latest_ver}" ]; then
32 | echo -e "\nFailed to check latest version, please try again later." && EXIT 1
33 | fi
34 |
35 | now_ver="$($binpath -c /dev/null --check-config 2>&1| grep -m 1 -E 'v[0-9.]+' -o)"
36 |
37 | if [ "${latest_ver}"x != "${now_ver}"x ] || [ "$1" == "force" ]; then
38 | echo -e "Local version: ${now_ver}., cloud version: ${latest_ver}."
39 | doupdate_core
40 | else
41 | echo -e "\nLocal version: ${now_ver}, cloud version: ${latest_ver}."
42 | echo -e "You're already using the latest version."
43 | if [ ! -z "$upxflag" ]; then
44 | filesize=$(ls -l $binpath | awk '{ print $5 }')
45 | if [ $filesize -gt 8000000 ]; then
46 | echo -e "start upx may take a long time"
47 | doupx
48 | mkdir -p "/tmp/AdGuardHomeupdate/AdGuardHome" >/dev/null 2>&1
49 | rm -fr /tmp/AdGuardHomeupdate/AdGuardHome/${binpath##*/}
50 | /tmp/upx-${upx_latest_ver}-${Arch}_linux/upx $upxflag $binpath -o /tmp/AdGuardHomeupdate/AdGuardHome/${binpath##*/}
51 | rm -rf /tmp/upx-${upx_latest_ver}-${Arch}_linux
52 | /etc/init.d/AdGuardHome stop nobackup
53 | rm $binpath
54 | mv -f /tmp/AdGuardHomeupdate/AdGuardHome/${binpath##*/} $binpath
55 | /etc/init.d/AdGuardHome start
56 | echo -e "finished"
57 | fi
58 | fi
59 | EXIT 0
60 | fi
61 | }
62 |
63 | doupx(){
64 | Archt="$(opkg info kernel | grep Architecture | awk -F "[ _]" '{print($2)}')"
65 | case $Archt in
66 | "i386")
67 | Arch="i386"
68 | ;;
69 | "i686")
70 | Arch="i386"
71 | echo -e "i686 use $Arch may have bug"
72 | ;;
73 | "x86")
74 | Arch="amd64"
75 | ;;
76 | "mipsel")
77 | Arch="mipsel"
78 | ;;
79 | "mips64el")
80 | Arch="mips64el"
81 | Arch="mipsel"
82 | echo -e "mips64el use $Arch may have bug"
83 | ;;
84 | "mips")
85 | Arch="mips"
86 | ;;
87 | "mips64")
88 | Arch="mips64"
89 | Arch="mips"
90 | echo -e "mips64 use $Arch may have bug"
91 | ;;
92 | "arm")
93 | Arch="arm"
94 | ;;
95 | "armeb")
96 | Arch="armeb"
97 | ;;
98 | "aarch64")
99 | Arch="arm64"
100 | ;;
101 | "powerpc")
102 | Arch="powerpc"
103 | ;;
104 | "powerpc64")
105 | Arch="powerpc64"
106 | ;;
107 | *)
108 | echo -e "error not support $Archt if you can use offical release please issue a bug"
109 | EXIT 1
110 | ;;
111 | esac
112 | upx_latest_ver="$($downloader - https://api.github.com/repos/upx/upx/releases/latest 2>/dev/null|grep -E 'tag_name' |grep -E '[0-9.]+' -o 2>/dev/null)"
113 | $downloader /tmp/upx-${upx_latest_ver}-${Arch}_linux.tar.xz "https://github.com/upx/upx/releases/download/v${upx_latest_ver}/upx-${upx_latest_ver}-${Arch}_linux.tar.xz" 2>&1
114 | #tar xvJf
115 | which xz || (opkg list | grep ^xz || opkg update && opkg install xz) || (echo "xz download fail" && EXIT 1)
116 | mkdir -p /tmp/upx-${upx_latest_ver}-${Arch}_linux
117 | xz -d -c /tmp/upx-${upx_latest_ver}-${Arch}_linux.tar.xz| tar -x -C "/tmp" >/dev/null 2>&1
118 | if [ ! -e "/tmp/upx-${upx_latest_ver}-${Arch}_linux/upx" ]; then
119 | echo -e "Failed to download upx."
120 | EXIT 1
121 | fi
122 | rm /tmp/upx-${upx_latest_ver}-${Arch}_linux.tar.xz
123 | }
124 |
125 | doupdate_core(){
126 | echo -e "Updating core..."
127 | mkdir -p "/tmp/AdGuardHomeupdate"
128 | rm -rf /tmp/AdGuardHomeupdate/* >/dev/null 2>&1
129 | Archt="$(opkg info kernel | grep Architecture | awk -F "[ _]" '{print($2)}')"
130 | case $Archt in
131 | "i386")
132 | Arch="386"
133 | ;;
134 | "i686")
135 | Arch="386"
136 | ;;
137 | "x86")
138 | Arch="amd64"
139 | ;;
140 | "mipsel")
141 | Arch="mipsle"
142 | ;;
143 | "mips64el")
144 | Arch="mips64le"
145 | Arch="mipsle"
146 | echo -e "mips64el use $Arch may have bug"
147 | ;;
148 | "mips")
149 | Arch="mips"
150 | ;;
151 | "mips64")
152 | Arch="mips64"
153 | Arch="mips"
154 | echo -e "mips64 use $Arch may have bug"
155 | ;;
156 | "arm")
157 | Arch="arm"
158 | ;;
159 | "aarch64")
160 | Arch="arm64"
161 | ;;
162 | "powerpc")
163 | Arch="ppc"
164 | echo -e "error not support $Archt"
165 | EXIT 1
166 | ;;
167 | "powerpc64")
168 | Arch="ppc64"
169 | echo -e "error not support $Archt"
170 | EXIT 1
171 | ;;
172 | *)
173 | echo -e "error not support $Archt if you can use offical release please issue a bug"
174 | EXIT 1
175 | ;;
176 | esac
177 | echo -e "start download"
178 | grep -v "^#" /usr/share/AdGuardHome/links.txt >/tmp/run/AdHlinks.txt
179 | while read link
180 | do
181 | eval link="$link"
182 | $downloader /tmp/AdGuardHomeupdate/${link##*/} "$link" 2>&1
183 | if [ "$?" != "0" ]; then
184 | echo "download failed try another download"
185 | rm -f /tmp/AdGuardHomeupdate/${link##*/}
186 | else
187 | local success="1"
188 | break
189 | fi
190 | done < "/tmp/run/AdHlinks.txt"
191 | rm /tmp/run/AdHlinks.txt
192 | [ -z "$success" ] && echo "no download success" && EXIT 1
193 | if [ "${link##*.}" == "gz" ]; then
194 | tar -zxf "/tmp/AdGuardHomeupdate/${link##*/}" -C "/tmp/AdGuardHomeupdate/"
195 | if [ ! -e "/tmp/AdGuardHomeupdate/AdGuardHome" ]; then
196 | echo -e "Failed to download core."
197 | rm -rf "/tmp/AdGuardHomeupdate" >/dev/null 2>&1
198 | EXIT 1
199 | fi
200 | downloadbin="/tmp/AdGuardHomeupdate/AdGuardHome/AdGuardHome"
201 | else
202 | downloadbin="/tmp/AdGuardHomeupdate/${link##*/}"
203 | fi
204 | chmod 755 $downloadbin
205 | echo -e "download success start copy"
206 | if [ -n "$upxflag" ]; then
207 | echo -e "start upx may take a long time"
208 | doupx
209 | /tmp/upx-${upx_latest_ver}-${Arch}_linux/upx $upxflag $downloadbin
210 | rm -rf /tmp/upx-${upx_latest_ver}-${Arch}_linux
211 | fi
212 | echo -e "start copy"
213 | /etc/init.d/AdGuardHome stop nobackup
214 | rm "$binpath"
215 | mv -f "$downloadbin" "$binpath"
216 | if [ "$?" == "1" ]; then
217 | echo "mv failed maybe not enough space please use upx or change bin to /tmp/AdGuardHome"
218 | EXIT 1
219 | fi
220 | /etc/init.d/AdGuardHome start
221 | rm -rf "/tmp/AdGuardHomeupdate" >/dev/null 2>&1
222 | echo -e "Succeeded in updating core."
223 | echo -e "Local version: ${latest_ver}, cloud version: ${latest_ver}.\n"
224 | EXIT 0
225 | }
226 |
227 | EXIT(){
228 | rm /var/run/update_core 2>/dev/null
229 | [ "$1" != "0" ] && touch /var/run/update_core_error
230 | exit $1
231 | }
232 |
233 | main(){
234 | check_if_already_running
235 | check_latest_version $1
236 | }
237 | trap "EXIT 1" SIGTERM SIGINT
238 | touch /var/run/update_core
239 | rm /var/run/update_core_error 2>/dev/null
240 | main $1
241 |
--------------------------------------------------------------------------------
/luci-app-adguardhome/root/usr/share/AdGuardHome/waitnet.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | PATH="/usr/sbin:/usr/bin:/sbin:/bin"
3 | count=0
4 | while :
5 | do
6 | ping -c 1 -W 1 -q www.baidu.com 1>/dev/null 2>&1
7 | if [ "$?" == "0" ]; then
8 | /etc/init.d/AdGuardHome force_reload
9 | break
10 | fi
11 | ping -c 1 -W 1 -q 202.108.22.5 1>/dev/null 2>&1
12 | if [ "$?" == "0" ]; then
13 | /etc/init.d/AdGuardHome force_reload
14 | break
15 | fi
16 | sleep 5
17 | ping -c 1 -W 1 -q www.google.com 1>/dev/null 2>&1
18 | if [ "$?" == "0" ]; then
19 | /etc/init.d/AdGuardHome force_reload
20 | break
21 | fi
22 | ping -c 1 -W 1 -q 8.8.8.8 1>/dev/null 2>&1
23 | if [ "$?" == "0" ]; then
24 | /etc/init.d/AdGuardHome force_reload
25 | break
26 | fi
27 | sleep 5
28 | count=$((count+1))
29 | if [ $count -gt 18 ]; then
30 | /etc/init.d/AdGuardHome force_reload
31 | break
32 | fi
33 | done
34 | return 0
--------------------------------------------------------------------------------
/luci-app-adguardhome/root/usr/share/AdGuardHome/watchconfig.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | PATH="/usr/sbin:/usr/bin:/sbin:/bin"
3 | configpath=$(uci get AdGuardHome.AdGuardHome.configpath)
4 | while :
5 | do
6 | sleep 10
7 | if [ -f "$configpath" ]; then
8 | /etc/init.d/AdGuardHome do_redirect 1
9 | break
10 | fi
11 | done
12 | return 0
--------------------------------------------------------------------------------
/luci-app-adguardhome/root/www/luci-static/resources/codemirror/addon/fold/foldcode.js:
--------------------------------------------------------------------------------
1 | !function(n){"object"==typeof exports&&"object"==typeof module?n(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],n):n(CodeMirror)}(function(n){"use strict";function e(e,o,i,t){if(i&&i.call){var l=i;i=null}else l=r(e,i,"rangeFinder");"number"==typeof o&&(o=n.Pos(o,0));var f=r(e,i,"minFoldSize");function d(n){var r=l(e,o);if(!r||r.to.line-r.from.linee.firstLine();)o=n.Pos(o.line-1,0),u=d(!1);if(u&&!u.cleared&&"unfold"!==t){var a=function(n,e){var o=r(n,e,"widget");if("string"==typeof o){var i=document.createTextNode(o);(o=document.createElement("span")).appendChild(i),o.className="CodeMirror-foldmarker"}else o&&(o=o.cloneNode(!0));return o}(e,i);n.on(a,"mousedown",function(e){c.clear(),n.e_preventDefault(e)});var c=e.markText(u.from,u.to,{replacedWith:a,clearOnEnter:r(e,i,"clearOnEnter"),__isFold:!0});c.on("clear",function(o,r){n.signal(e,"unfold",e,o,r)}),n.signal(e,"fold",e,u.from,u.to)}}n.newFoldFunction=function(n,o){return function(r,i){e(r,i,{rangeFinder:n,widget:o})}},n.defineExtension("foldCode",function(n,o,r){e(this,n,o,r)}),n.defineExtension("isFolded",function(n){for(var e=this.findMarksAt(n),o=0;o=u){if(s&&f&&s.test(f.className))return;i=r(a.indicatorOpen)}}(i||f)&&t.setGutterMarker(n,a.gutter,i)})}function i(t){return new RegExp("(^|\\s)"+t+"(?:$|\\s)\\s*")}function f(t){var o=t.getViewport(),e=t.state.foldGutter;e&&(t.operation(function(){n(t,o.from,o.to)}),e.from=o.from,e.to=o.to)}function a(t,r,n){var i=t.state.foldGutter;if(i){var f=i.options;if(n==f.gutter){var a=e(t,r);a?a.clear():t.foldCode(o(r,0),f)}}}function d(t){var o=t.state.foldGutter;if(o){var e=o.options;o.from=o.to=0,clearTimeout(o.changeUpdate),o.changeUpdate=setTimeout(function(){f(t)},e.foldOnChangeTimeSpan||600)}}function u(t){var o=t.state.foldGutter;if(o){var e=o.options;clearTimeout(o.changeUpdate),o.changeUpdate=setTimeout(function(){var e=t.getViewport();o.from==o.to||e.from-o.to>20||o.from-e.to>20?f(t):t.operation(function(){e.fromo.to&&(n(t,o.to,e.to),o.to=e.to)})},e.updateViewportTimeSpan||400)}}function l(t,o){var e=t.state.foldGutter;if(e){var r=o.line;r>=e.from&&ro))break;r=l}}return r?{from:e.Pos(i.line,t.getLine(i.line).length),to:e.Pos(r,t.getLine(r).length)}:void 0}})});
--------------------------------------------------------------------------------
/luci-app-adguardhome/root/www/luci-static/resources/codemirror/lib/codemirror.css:
--------------------------------------------------------------------------------
1 | .CodeMirror{font-family:monospace;height:500px;color:black;direction:ltr}.CodeMirror-lines{padding:4px 0}.CodeMirror pre.CodeMirror-line,.CodeMirror pre.CodeMirror-line-like{padding:0 4px}.CodeMirror-scrollbar-filler,.CodeMirror-gutter-filler{background-color:white}.CodeMirror-gutters{border-right:1px solid #ddd;background-color:#f7f7f7;white-space:nowrap}.CodeMirror-linenumber{padding:0 3px 0 5px;min-width:20px;text-align:right;color:#999;white-space:nowrap}.CodeMirror-guttermarker{color:black}.CodeMirror-guttermarker-subtle{color:#999}.CodeMirror-cursor{border-left:1px solid black;border-right:0;width:0}.CodeMirror div.CodeMirror-secondarycursor{border-left:1px solid silver}.cm-fat-cursor .CodeMirror-cursor{width:auto;border:0 !important;background:#7e7}.cm-fat-cursor div.CodeMirror-cursors{z-index:1}.cm-fat-cursor-mark{background-color:rgba(20,255,20,0.5);-webkit-animation:blink 1.06s steps(1) infinite;-moz-animation:blink 1.06s steps(1) infinite;animation:blink 1.06s steps(1) infinite}.cm-animate-fat-cursor{width:auto;border:0;-webkit-animation:blink 1.06s steps(1) infinite;-moz-animation:blink 1.06s steps(1) infinite;animation:blink 1.06s steps(1) infinite;background-color:#7e7}@-moz-keyframes blink{50%{background-color:transparent}}@-webkit-keyframes blink{50%{background-color:transparent}}@keyframes blink{50%{background-color:transparent}}.cm-tab{display:inline-block;text-decoration:inherit}.CodeMirror-rulers{position:absolute;left:0;right:0;top:-50px;bottom:0;overflow:hidden}.CodeMirror-ruler{border-left:1px solid #ccc;top:0;bottom:0;position:absolute}.cm-s-default .cm-header{color:blue}.cm-s-default .cm-quote{color:#090}.cm-negative{color:#d44}.cm-positive{color:#292}.cm-header,.cm-strong{font-weight:bold}.cm-em{font-style:italic}.cm-link{text-decoration:underline}.cm-strikethrough{text-decoration:line-through}.cm-s-default .cm-keyword{color:#708}.cm-s-default .cm-atom{color:#219}.cm-s-default .cm-number{color:#164}.cm-s-default .cm-def{color:#00f}.cm-s-default .cm-variable-2{color:#05a}.cm-s-default .cm-variable-3,.cm-s-default .cm-type{color:#085}.cm-s-default .cm-comment{color:#a50}.cm-s-default .cm-string{color:#a11}.cm-s-default .cm-string-2{color:#f50}.cm-s-default .cm-meta{color:#555}.cm-s-default .cm-qualifier{color:#555}.cm-s-default .cm-builtin{color:#30a}.cm-s-default .cm-bracket{color:#997}.cm-s-default .cm-tag{color:#170}.cm-s-default .cm-attribute{color:#00c}.cm-s-default .cm-hr{color:#999}.cm-s-default .cm-link{color:#00c}.cm-s-default .cm-error{color:red}.cm-invalidchar{color:red}.CodeMirror-composing{border-bottom:2px solid}div.CodeMirror span.CodeMirror-matchingbracket{color:#0b0}div.CodeMirror span.CodeMirror-nonmatchingbracket{color:#a22}.CodeMirror-matchingtag{background:rgba(255,150,0,.3)}.CodeMirror-activeline-background{background:#e8f2ff}.CodeMirror{position:relative;overflow:hidden;background:white}.CodeMirror-scroll{overflow:scroll !important;margin-bottom:-30px;margin-right:-30px;padding-bottom:30px;height:100%;outline:0;position:relative}.CodeMirror-sizer{position:relative;border-right:30px solid transparent}.CodeMirror-vscrollbar,.CodeMirror-hscrollbar,.CodeMirror-scrollbar-filler,.CodeMirror-gutter-filler{position:absolute;z-index:6;display:none}.CodeMirror-vscrollbar{right:0;top:0;overflow-x:hidden;overflow-y:scroll}.CodeMirror-hscrollbar{bottom:0;left:0;overflow-y:hidden;overflow-x:scroll}.CodeMirror-scrollbar-filler{right:0;bottom:0}.CodeMirror-gutter-filler{left:0;bottom:0}.CodeMirror-gutters{position:absolute;left:0;top:0;min-height:100%;z-index:3}.CodeMirror-gutter{white-space:normal;height:100%;display:inline-block;vertical-align:top;margin-bottom:-30px}.CodeMirror-gutter-wrapper{position:absolute;z-index:4;background:none !important;border:none !important}.CodeMirror-gutter-background{position:absolute;top:0;bottom:0;z-index:4}.CodeMirror-gutter-elt{position:absolute;cursor:default;z-index:4}.CodeMirror-gutter-wrapper ::selection{background-color:transparent}.CodeMirror-gutter-wrapper ::-moz-selection{background-color:transparent}.CodeMirror-lines{cursor:text;min-height:1px}.CodeMirror pre.CodeMirror-line,.CodeMirror pre.CodeMirror-line-like{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0;border-width:0;background:transparent;font-family:inherit;font-size:inherit;margin:0;white-space:pre;word-wrap:normal;line-height:inherit;color:inherit;z-index:2;position:relative;overflow:visible;-webkit-tap-highlight-color:transparent;-webkit-font-variant-ligatures:contextual;font-variant-ligatures:contextual}.CodeMirror-wrap pre.CodeMirror-line,.CodeMirror-wrap pre.CodeMirror-line-like{word-wrap:break-word;white-space:pre-wrap;word-break:normal}.CodeMirror-linebackground{position:absolute;left:0;right:0;top:0;bottom:0;z-index:0}.CodeMirror-linewidget{position:relative;z-index:2;padding:.1px}.CodeMirror-rtl pre{direction:rtl}.CodeMirror-code{outline:0}.CodeMirror-scroll,.CodeMirror-sizer,.CodeMirror-gutter,.CodeMirror-gutters,.CodeMirror-linenumber{-moz-box-sizing:content-box;box-sizing:content-box}.CodeMirror-measure{position:absolute;width:100%;height:0;overflow:hidden;visibility:hidden}.CodeMirror-cursor{position:absolute;pointer-events:none}.CodeMirror-measure pre{position:static}div.CodeMirror-cursors{visibility:hidden;position:relative;z-index:3}div.CodeMirror-dragcursors{visibility:visible}.CodeMirror-focused div.CodeMirror-cursors{visibility:visible}.CodeMirror-selected{background:#d9d9d9}.CodeMirror-focused .CodeMirror-selected{background:#d7d4f0}.CodeMirror-crosshair{cursor:crosshair}.CodeMirror-line::selection,.CodeMirror-line>span::selection,.CodeMirror-line>span>span::selection{background:#d7d4f0}.CodeMirror-line::-moz-selection,.CodeMirror-line>span::-moz-selection,.CodeMirror-line>span>span::-moz-selection{background:#d7d4f0}.cm-searching{background-color:#ffa;background-color:rgba(255,255,0,.4)}.cm-force-border{padding-right:.1px}@media print{.CodeMirror div.CodeMirror-cursors{visibility:hidden}}.cm-tab-wrap-hack:after{content:''}span.CodeMirror-selectedtext{background:0}
2 |
--------------------------------------------------------------------------------
/luci-app-adguardhome/root/www/luci-static/resources/codemirror/mode/yaml/yaml.js:
--------------------------------------------------------------------------------
1 | !function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],e):e(CodeMirror)}(function(e){"use strict";e.defineMode("yaml",function(){var e=new RegExp("\\b(("+["true","false","on","off","yes","no"].join(")|(")+"))$","i");return{token:function(i,t){var r=i.peek(),n=t.escaped;if(t.escaped=!1,"#"==r&&(0==i.pos||/\s/.test(i.string.charAt(i.pos-1))))return i.skipToEnd(),"comment";if(i.match(/^('([^']|\\.)*'?|"([^"]|\\.)*"?)/))return"string";if(t.literal&&i.indentation()>t.keyCol)return i.skipToEnd(),"string";if(t.literal&&(t.literal=!1),i.sol()){if(t.keyCol=0,t.pair=!1,t.pairStart=!1,i.match(/---/))return"def";if(i.match(/\.\.\./))return"def";if(i.match(/\s*-\s+/))return"meta"}if(i.match(/^(\{|\}|\[|\])/))return"{"==r?t.inlinePairs++:"}"==r?t.inlinePairs--:"["==r?t.inlineList++:t.inlineList--,"meta";if(t.inlineList>0&&!n&&","==r)return i.next(),"meta";if(t.inlinePairs>0&&!n&&","==r)return t.keyCol=0,t.pair=!1,t.pairStart=!1,i.next(),"meta";if(t.pairStart){if(i.match(/^\s*(\||\>)\s*/))return t.literal=!0,"meta";if(i.match(/^\s*(\&|\*)[a-z0-9\._-]+\b/i))return"variable-2";if(0==t.inlinePairs&&i.match(/^\s*-?[0-9\.\,]+\s?$/))return"number";if(t.inlinePairs>0&&i.match(/^\s*-?[0-9\.\,]+\s?(?=(,|}))/))return"number";if(i.match(e))return"keyword"}return!t.pair&&i.match(/^\s*(?:[,\[\]{}&*!|>'"%@`][^\s'":]|[^,\[\]{}#&*!|>'"%@`])[^#]*?(?=\s*:($|\s))/)?(t.pair=!0,t.keyCol=i.indentation(),"atom"):t.pair&&i.match(/^:\s*/)?(t.pairStart=!0,"meta"):(t.pairStart=!1,t.escaped="\\"==r,i.next(),null)},startState:function(){return{pair:!1,pairStart:!1,keyCol:0,inlinePairs:0,inlineList:0,literal:!1,escaped:!1}},lineComment:"#",fold:"indent"}}),e.defineMIME("text/x-yaml","yaml"),e.defineMIME("text/yaml","yaml")});
--------------------------------------------------------------------------------
/luci-app-adguardhome/root/www/luci-static/resources/codemirror/theme/dracula.css:
--------------------------------------------------------------------------------
1 | .cm-s-dracula.CodeMirror,.cm-s-dracula .CodeMirror-gutters{background-color:#282a36 !important;color:#f8f8f2 !important;border:0}.cm-s-dracula .CodeMirror-gutters{color:#282a36}.cm-s-dracula .CodeMirror-cursor{border-left:solid thin #f8f8f0}.cm-s-dracula .CodeMirror-linenumber{color:#6d8a88}.cm-s-dracula .CodeMirror-selected{background:rgba(255,255,255,0.10)}.cm-s-dracula .CodeMirror-line::selection,.cm-s-dracula .CodeMirror-line>span::selection,.cm-s-dracula .CodeMirror-line>span>span::selection{background:rgba(255,255,255,0.10)}.cm-s-dracula .CodeMirror-line::-moz-selection,.cm-s-dracula .CodeMirror-line>span::-moz-selection,.cm-s-dracula .CodeMirror-line>span>span::-moz-selection{background:rgba(255,255,255,0.10)}.cm-s-dracula span.cm-comment{color:#6272a4}.cm-s-dracula span.cm-string,.cm-s-dracula span.cm-string-2{color:#f1fa8c}.cm-s-dracula span.cm-number{color:#bd93f9}.cm-s-dracula span.cm-variable{color:#50fa7b}.cm-s-dracula span.cm-variable-2{color:white}.cm-s-dracula span.cm-def{color:#50fa7b}.cm-s-dracula span.cm-operator{color:#ff79c6}.cm-s-dracula span.cm-keyword{color:#ff79c6}.cm-s-dracula span.cm-atom{color:#bd93f9}.cm-s-dracula span.cm-meta{color:#f8f8f2}.cm-s-dracula span.cm-tag{color:#ff79c6}.cm-s-dracula span.cm-attribute{color:#50fa7b}.cm-s-dracula span.cm-qualifier{color:#50fa7b}.cm-s-dracula span.cm-property{color:#66d9ef}.cm-s-dracula span.cm-builtin{color:#50fa7b}.cm-s-dracula span.cm-variable-3,.cm-s-dracula span.cm-type{color:#ffb86c}.cm-s-dracula .CodeMirror-activeline-background{background:rgba(255,255,255,0.1)}.cm-s-dracula .CodeMirror-matchingbracket{text-decoration:underline;color:white !important}
2 |
--------------------------------------------------------------------------------
/luci-app-adguardhome/root/www/luci-static/resources/twin-bcrypt.min.js:
--------------------------------------------------------------------------------
1 | /* @license
2 | * Twin-Bcrypt 2.2.0
3 | * https://github.com/fpirsch/twin-bcrypt
4 | * Licence: BSD-3-Clause
5 | */
6 | !function(r,n){"use strict";function e(r){return y[g]=t.apply(n,r),g++}function t(r){var e=[].slice.call(arguments,1);return function(){"function"==typeof r?r.apply(n,e):new Function(""+r)()}}function o(r){if(m)setTimeout(t(o,r),0);else{var n=y[r];if(n){m=!0;try{n()}finally{a(r),m=!1}}}}function a(r){delete y[r]}function i(){p=function(){var r=e(arguments);return process.nextTick(t(o,r)),r}}function u(){if(r.postMessage&&!r.importScripts){var n=!0,e=r.onmessage;return r.onmessage=function(){n=!1},r.postMessage("","*"),r.onmessage=e,n}}function f(){var n="setImmediate$"+Math.random()+"$",t=function(e){e.source===r&&"string"==typeof e.data&&0===e.data.indexOf(n)&&o(+e.data.slice(n.length))};r.addEventListener?r.addEventListener("message",t,!1):r.attachEvent("onmessage",t),p=function(){var t=e(arguments);return r.postMessage(n+t,"*"),t}}function c(){var r=new MessageChannel;r.port1.onmessage=function(r){var n=r.data;o(n)},p=function(){var n=e(arguments);return r.port2.postMessage(n),n}}function s(){var r=v.documentElement;p=function(){var n=e(arguments),t=v.createElement("script");return t.onreadystatechange=function(){o(n),t.onreadystatechange=null,r.removeChild(t),t=null},r.appendChild(t),n}}function l(){p=function(){var r=e(arguments);return setTimeout(t(o,r),0),r}}if(!r.setImmediate){var p,g=1,y={},m=!1,v=r.document,d=Object.getPrototypeOf&&Object.getPrototypeOf(r);d=d&&d.setTimeout?d:r,"[object process]"==={}.toString.call(r.process)?i():u()?f():r.MessageChannel?c():v&&"onreadystatechange"in v.createElement("script")?s():l(),d.setImmediate=p,d.clearImmediate=a}}(new Function("return this")()),function(r){"object"==typeof exports?r(exports,require("crypto")):r(self.TwinBcrypt={},self.crypto||self.msCrypto)}(function(r,n){"use strict";function e(r){for(var n=unescape(encodeURIComponent(r)),e=n.length,t=new Array(e),o=0;e>o;o++)t[o]=n.charCodeAt(o);return t}function t(r){for(var n=r.length,e=new Array(n),t=0;n>t;t++)e[t]=r.charCodeAt(t);return e}function o(r,n){for(var e,t,o=0,a="";n>o;){if(e=255&r[o++],a+=B[e>>2],e=(3&e)<<4,o>=n){a+=B[e];break}if(t=255&r[o++],e|=t>>4,a+=B[e],e=(15&t)<<2,o>=n){a+=B[e];break}t=255&r[o++],e|=t>>6,a+=B[e],a+=B[63&t]}return a}function a(r){for(var n,e,t=new Array(16),o=0,a=0;;){if(n=D[r.charCodeAt(o++)-46],e=D[r.charCodeAt(o++)-46],t[a++]=255&(n<<2|e>>4),22===o)break;n=e<<4,e=D[r.charCodeAt(o++)-46],t[a++]=255&(n|e>>2),n=e<<6,e=D[r.charCodeAt(o++)-46],t[a++]=255&(n|e)}return t}function i(r){for(var n=r.length,e=new Array(72),t=0,o=0;72>o;)e[o++]=r[t++],t===n&&(t=0);return e}function u(r,n,e){for(var t=0,o=e>>2;tt;)r[n++]=e[t++]<<24|e[t++]<<16|e[t++]<<8|e[t++]}function c(r){function n(n){for(var e=r,t=G>>2,o=t|O,f=n>>2,c=e[f]^e[t],s=e[1|f];o>t;)s^=(e[c>>>24]+e[a|c>>>16&255]^e[i|c>>>8&255])+e[u|255&c]^e[++t],c^=(e[s>>>24]+e[a|s>>>16&255]^e[i|s>>>8&255])+e[u|255&s]^e[++t];e[f]=s^e[S>>2],e[1|f]=c}function e(n){var e;for(r[L>>2]=0,r[L+4>>2]=0,e=0;M>e;e++)r[G>>2|e]^=r[(n>>2)+e];var t,o,f,c,s,l=r;for(e=0;M>e;e+=2){for(t=G>>2,o=t|O,f=L>>2,c=l[f]^l[t],s=l[1|f];o>t;)s^=(l[c>>>24]+l[a|c>>>16&255]^l[i|c>>>8&255])+l[u|255&c]^l[++t],c^=(l[s>>>24]+l[a|s>>>16&255]^l[i|s>>>8&255])+l[u|255&s]^l[++t];l[f]=s^l[S>>2],l[1|f]=c,r[G>>2|e]=l[f],r[G>>2|e+1]=c}for(e=0;T>e;e+=2){for(t=G>>2,o=t|O,f=L>>2,c=l[f]^l[t],s=l[1|f];o>t;)s^=(l[c>>>24]+l[a|c>>>16&255]^l[i|c>>>8&255])+l[u|255&c]^l[++t],c^=(l[s>>>24]+l[a|s>>>16&255]^l[i|s>>>8&255])+l[u|255&s]^l[++t];l[f]=s^l[S>>2],l[1|f]=c,r[e]=l[f],r[1|e]=c}}function t(r,n,t){for(var o=0;t>=o&&!(r>n);o++)e(R),e(j),r++;return r}var o=k>>2,a=o+256|0,i=a+256|0,u=i+256|0;return{encrypt:n,expandLoop:t}}function s(stdlib, foreign, heap) {"use asm";var HEAP32=new stdlib.Uint32Array(heap);var BLOWFISH_NUM_ROUNDS=16;var S_offset=0x0000;var S1_offset=0x0400;var S2_offset=0x0800;var S3_offset=0x0C00;var P_offset=0x1000;var P_last_offset=0x1044;var crypt_ciphertext_offset=0x1048;var LR_offset=0x01060;var password_offset=0x1068;var salt_offset=0x10b0;var P_LEN=18;var S_LEN=1024;function encrypt(offset) {offset=offset|0;var i=0;var n=0;var L=0;var R=0;var imax=0;imax=P_offset|BLOWFISH_NUM_ROUNDS<<2;L=HEAP32[offset>>2]|0;R=HEAP32[offset+4>>2]|0;L=L^HEAP32[P_offset>>2];for (i=P_offset; (i|0)<(imax|0);) {i=(i+4)>>>0;R=R^(((HEAP32[(L>>>22)>>2]>>>0) +(HEAP32[(S1_offset|(L>>>14&0x3ff))>>2]>>>0) ^(HEAP32[(S2_offset|(L>>>6&0x3ff))>>2])) +(HEAP32[(S3_offset|(L<<2&0x3ff))>>2]>>>0))^HEAP32[i>>2];i=(i+4)>>>0;L=L^(((HEAP32[(R>>>22)>>2]>>>0) +(HEAP32[(S1_offset|(R>>>14&0x3ff))>>2]>>>0) ^(HEAP32[(S2_offset|(R>>>6&0x3ff))>>2])) +(HEAP32[(S3_offset|(R<<2&0x3ff))>>2]>>>0))^HEAP32[i>>2];}HEAP32[offset>>2]=R^HEAP32[P_last_offset>>2];HEAP32[(offset+4)>>2]=L;}function expandKey(offset) {offset=offset|0;var i=0;var off=0;off=P_offset|0;for (i=0; (i|0)<(P_LEN|0); i=(i+1)|0) {HEAP32[off>>2]=HEAP32[off>>2]^HEAP32[offset>>2];offset=(offset+4)|0;off=(off+4)|0;}HEAP32[LR_offset>>2]=0;HEAP32[LR_offset+4>>2]=0;off=P_offset;for (i=0; (i|0)<(P_LEN|0); i=(i+2)|0) {encrypt(LR_offset);HEAP32[off>>2]=HEAP32[LR_offset>>2];HEAP32[off+4>>2]=HEAP32[LR_offset+4>>2];off=(off+8)|0;}off=S_offset;for (i=0; (i|0)<(S_LEN|0); i=(i+2)|0) {encrypt(LR_offset);HEAP32[off>>2]=HEAP32[LR_offset>>2];HEAP32[off+4>>2]=HEAP32[LR_offset+4>>2];off=(off+8)|0;}}function expandLoop(i, counterEnd, maxIterations) {i=i|0;counterEnd=counterEnd|0;maxIterations=maxIterations|0;var j=0;for (j=0; (j|0) <= (maxIterations|0); j=(j+1)|0) {if ((i>>>0)>(counterEnd>>>0)) break;expandKey(password_offset);expandKey(salt_offset);i=(i+1)>>>0;}return i|0;}return {encrypt: encrypt,expandLoop: expandLoop};}
7 | function l(r,n,e,t){var o,a,i,u=L>>2,f=u+1;for(t[u]=0,t[f]=0,a=0,o=0;M>o;o++)i=n[a++]<<24|n[a++]<<16|n[a++]<<8|n[a++],t[G>>2|o]^=i;for(a=0,o=0;M>o;o+=2)i=r[a++]<<24|r[a++]<<16|r[a++]<<8|r[a++],a&=65295,t[u]^=i,i=r[a++]<<24|r[a++]<<16|r[a++]<<8|r[a++],a&=65295,t[f]^=i,e.encrypt(L),t[G>>2|o]=t[u],t[G>>2|o+1]=t[f];var c=k>>2;for(o=0;T>o;o+=2)i=r[a++]<<24|r[a++]<<16|r[a++]<<8|r[a++],a&=65295,t[u]^=i,i=r[a++]<<24|r[a++]<<16|r[a++]<<8|r[a++],a&=65295,t[f]^=i,e.encrypt(L),t[c|o]=t[u],t[c|o+1]=t[f]}function p(r,n,e,t,o,a,i){for(var u=e;t>=u;){if(u=r.expandLoop(u,t,o),a){var f=a(u/(t+1));if(f===!1)return}if(u>t){if(i)return void setImmediate(g.bind(null,r,n,i));return}if(i)return void setImmediate(p.bind(null,r,n,u,t,o,a,i))}}function g(r,n,e){u(n,x,F);var t;for(t=0;64>t;t++)r.encrypt(F+0),r.encrypt(F+8),r.encrypt(F+16);var o,a=0,i=x.length,f=new Array(4*i);for(t=0;i>t;t++)o=n[(F>>2)+t],f[a++]=o>>24,f[a++]=o>>16&255,f[a++]=o>>8&255,f[a++]=255&o;return e&&e(f),f}function y(r,n){return r+o(n,23)}function m(n,o,m,v){var d,h=o.substr(0,29),w=+o.substr(4,2),A=o.substr(7,22);if("string"==typeof n)d=r.encodingMode===r.ENCODING_UTF8?e(n):t(n);else if(Array.isArray(n))d=n.map(function(r){return 255&r});else{if(!(n instanceof Uint8Array))throw new Error("Incorrect arguments");d=Array.prototype.slice.call(n)}d.push(0);var b,E,N=a(A,C),O=31>w?1<>2,N),f(b,R>>2,d),l(N,d,E,b),v?void p(E,b,0,M,T,m,function(r){v(y(h,r))}):(p(E,b,0,M,T,m),y(h,g(E,b)))}function v(r){if(!b)throw new Error("No cryptographically secure pseudorandom number generator available.");if(null==r&&(r=N),r=0|+r,isNaN(r)||4>r||r>31)throw new Error("Invalid cost parameter.");var n="$2y$";return 10>r&&(n+="0"),n+=r+"$",n+=o(b(C),C)}function d(r,n,e){if(n&&"number"!=typeof n){if("string"!=typeof n||!z.test(n))throw new Error("Invalid salt")}else n=v(n);return m(r,n,e)}function h(r,n,e,t){if(arguments.length<2)throw new Error("Incorrect arguments");if(2===arguments.length?(t=n,n=e=null):3===arguments.length&&(t=e,e=null,"function"==typeof n&&(e=n,n=null)),n&&"number"!=typeof n){if("string"!=typeof n||!z.test(n))throw new Error("Invalid salt")}else n=v(n);if(!t||"function"!=typeof t)throw new Error("No callback function was given.");m(r,n,e,t)}function w(r,n){if("string"!=typeof n||!Z.test(n))throw new Error("Incorrect arguments");var e=n.substr(0,n.length-31),t=d(r,e);return t===n}function A(r,n,e,t){if("string"!=typeof n||!Z.test(n))throw new Error("Incorrect arguments");if(t||(t=e,e=null),!t||"function"!=typeof t)throw new Error("No callback function was given.");var o=n.substr(0,n.length-31);h(r,o,e,function(r){t(r===n)})}var b,E="undefined"!=typeof InstallTrigger,I=E;n&&(b=n.randomBytes,n.getRandomValues&&(b=function(r){var e=new Uint8Array(r);return n.getRandomValues(e)}));var C=16,N=10,O=16,$=[608135816,2242054355,320440878,57701188,2752067618,698298832,137296536,3964562569,1160258022,953160567,3193202383,887688300,3232508343,3380367581,1065670069,3041331479,2450970073,2306472731],U=[3509652390,2564797868,805139163,3491422135,3101798381,1780907670,3128725573,4046225305,614570311,3012652279,134345442,2240740374,1667834072,1901547113,2757295779,4103290238,227898511,1921955416,1904987480,2182433518,2069144605,3260701109,2620446009,720527379,3318853667,677414384,3393288472,3101374703,2390351024,1614419982,1822297739,2954791486,3608508353,3174124327,2024746970,1432378464,3864339955,2857741204,1464375394,1676153920,1439316330,715854006,3033291828,289532110,2706671279,2087905683,3018724369,1668267050,732546397,1947742710,3462151702,2609353502,2950085171,1814351708,2050118529,680887927,999245976,1800124847,3300911131,1713906067,1641548236,4213287313,1216130144,1575780402,4018429277,3917837745,3693486850,3949271944,596196993,3549867205,258830323,2213823033,772490370,2760122372,1774776394,2652871518,566650946,4142492826,1728879713,2882767088,1783734482,3629395816,2517608232,2874225571,1861159788,326777828,3124490320,2130389656,2716951837,967770486,1724537150,2185432712,2364442137,1164943284,2105845187,998989502,3765401048,2244026483,1075463327,1455516326,1322494562,910128902,469688178,1117454909,936433444,3490320968,3675253459,1240580251,122909385,2157517691,634681816,4142456567,3825094682,3061402683,2540495037,79693498,3249098678,1084186820,1583128258,426386531,1761308591,1047286709,322548459,995290223,1845252383,2603652396,3431023940,2942221577,3202600964,3727903485,1712269319,422464435,3234572375,1170764815,3523960633,3117677531,1434042557,442511882,3600875718,1076654713,1738483198,4213154764,2393238008,3677496056,1014306527,4251020053,793779912,2902807211,842905082,4246964064,1395751752,1040244610,2656851899,3396308128,445077038,3742853595,3577915638,679411651,2892444358,2354009459,1767581616,3150600392,3791627101,3102740896,284835224,4246832056,1258075500,768725851,2589189241,3069724005,3532540348,1274779536,3789419226,2764799539,1660621633,3471099624,4011903706,913787905,3497959166,737222580,2514213453,2928710040,3937242737,1804850592,3499020752,2949064160,2386320175,2390070455,2415321851,4061277028,2290661394,2416832540,1336762016,1754252060,3520065937,3014181293,791618072,3188594551,3933548030,2332172193,3852520463,3043980520,413987798,3465142937,3030929376,4245938359,2093235073,3534596313,375366246,2157278981,2479649556,555357303,3870105701,2008414854,3344188149,4221384143,3956125452,2067696032,3594591187,2921233993,2428461,544322398,577241275,1471733935,610547355,4027169054,1432588573,1507829418,2025931657,3646575487,545086370,48609733,2200306550,1653985193,298326376,1316178497,3007786442,2064951626,458293330,2589141269,3591329599,3164325604,727753846,2179363840,146436021,1461446943,4069977195,705550613,3059967265,3887724982,4281599278,3313849956,1404054877,2845806497,146425753,1854211946,1266315497,3048417604,3681880366,3289982499,290971e4,1235738493,2632868024,2414719590,3970600049,1771706367,1449415276,3266420449,422970021,1963543593,2690192192,3826793022,1062508698,1531092325,1804592342,2583117782,2714934279,4024971509,1294809318,4028980673,1289560198,2221992742,1669523910,35572830,157838143,1052438473,1016535060,1802137761,1753167236,1386275462,3080475397,2857371447,1040679964,2145300060,2390574316,1461121720,2956646967,4031777805,4028374788,33600511,2920084762,1018524850,629373528,3691585981,3515945977,2091462646,2486323059,586499841,988145025,935516892,3367335476,2599673255,2839830854,265290510,3972581182,2759138881,3795373465,1005194799,847297441,406762289,1314163512,1332590856,1866599683,4127851711,750260880,613907577,1450815602,3165620655,3734664991,3650291728,3012275730,3704569646,1427272223,778793252,1343938022,2676280711,2052605720,1946737175,3164576444,3914038668,3967478842,3682934266,1661551462,3294938066,4011595847,840292616,3712170807,616741398,312560963,711312465,1351876610,322626781,1910503582,271666773,2175563734,1594956187,70604529,3617834859,1007753275,1495573769,4069517037,2549218298,2663038764,504708206,2263041392,3941167025,2249088522,1514023603,1998579484,1312622330,694541497,2582060303,2151582166,1382467621,776784248,2618340202,3323268794,2497899128,2784771155,503983604,4076293799,907881277,423175695,432175456,1378068232,4145222326,3954048622,3938656102,3820766613,2793130115,2977904593,26017576,3274890735,3194772133,1700274565,1756076034,4006520079,3677328699,720338349,1533947780,354530856,688349552,3973924725,1637815568,332179504,3949051286,53804574,2852348879,3044236432,1282449977,3583942155,3416972820,4006381244,1617046695,2628476075,3002303598,1686838959,431878346,2686675385,1700445008,1080580658,1009431731,832498133,3223435511,2605976345,2271191193,2516031870,1648197032,4164389018,2548247927,300782431,375919233,238389289,3353747414,2531188641,2019080857,1475708069,455242339,2609103871,448939670,3451063019,1395535956,2413381860,1841049896,1491858159,885456874,4264095073,4001119347,1565136089,3898914787,1108368660,540939232,1173283510,2745871338,3681308437,4207628240,3343053890,4016749493,1699691293,1103962373,3625875870,2256883143,3830138730,1031889488,3479347698,1535977030,4236805024,3251091107,2132092099,1774941330,1199868427,1452454533,157007616,2904115357,342012276,595725824,1480756522,206960106,497939518,591360097,863170706,2375253569,3596610801,1814182875,2094937945,3421402208,1082520231,3463918190,2785509508,435703966,3908032597,1641649973,2842273706,3305899714,1510255612,2148256476,2655287854,3276092548,4258621189,236887753,3681803219,274041037,1734335097,3815195456,3317970021,1899903192,1026095262,4050517792,356393447,2410691914,3873677099,3682840055,3913112168,2491498743,4132185628,2489919796,1091903735,1979897079,3170134830,3567386728,3557303409,857797738,1136121015,1342202287,507115054,2535736646,337727348,3213592640,1301675037,2528481711,1895095763,1721773893,3216771564,62756741,2142006736,835421444,2531993523,1442658625,3659876326,2882144922,676362277,1392781812,170690266,3921047035,1759253602,3611846912,1745797284,664899054,1329594018,3901205900,3045908486,2062866102,2865634940,3543621612,3464012697,1080764994,553557557,3656615353,3996768171,991055499,499776247,1265440854,648242737,3940784050,980351604,3713745714,1749149687,3396870395,4211799374,3640570775,1161844396,3125318951,1431517754,545492359,4268468663,3499529547,1437099964,2702547544,3433638243,2581715763,2787789398,1060185593,1593081372,2418618748,4260947970,69676912,2159744348,86519011,2512459080,3838209314,1220612927,3339683548,133810670,1090789135,1078426020,1569222167,845107691,3583754449,4072456591,1091646820,628848692,1613405280,3757631651,526609435,236106946,48312990,2942717905,3402727701,1797494240,859738849,992217954,4005476642,2243076622,3870952857,3732016268,765654824,3490871365,2511836413,1685915746,3888969200,1414112111,2273134842,3281911079,4080962846,172450625,2569994100,980381355,4109958455,2819808352,2716589560,2568741196,3681446669,3329971472,1835478071,660984891,3704678404,4045999559,3422617507,3040415634,1762651403,1719377915,3470491036,2693910283,3642056355,3138596744,1364962596,2073328063,1983633131,926494387,3423689081,2150032023,4096667949,1749200295,3328846651,309677260,2016342300,1779581495,3079819751,111262694,1274766160,443224088,298511866,1025883608,3806446537,1145181785,168956806,3641502830,3584813610,1689216846,3666258015,3200248200,1692713982,2646376535,4042768518,1618508792,1610833997,3523052358,4130873264,2001055236,3610705100,2202168115,4028541809,2961195399,1006657119,2006996926,3186142756,1430667929,3210227297,1314452623,4074634658,4101304120,2273951170,1399257539,3367210612,3027628629,1190975929,2062231137,2333990788,2221543033,2438960610,1181637006,548689776,2362791313,3372408396,3104550113,3145860560,296247880,1970579870,3078560182,3769228297,1714227617,3291629107,3898220290,166772364,1251581989,493813264,448347421,195405023,2709975567,677966185,3703036547,1463355134,2715995803,1338867538,1343315457,2802222074,2684532164,233230375,2599980071,2000651841,3277868038,1638401717,4028070440,3237316320,6314154,819756386,300326615,590932579,1405279636,3267499572,3150704214,2428286686,3959192993,3461946742,1862657033,1266418056,963775037,2089974820,2263052895,1917689273,448879540,3550394620,3981727096,150775221,3627908307,1303187396,508620638,2975983352,2726630617,1817252668,1876281319,1457606340,908771278,3720792119,3617206836,2455994898,1729034894,1080033504,976866871,3556439503,2881648439,1522871579,1555064734,1336096578,3548522304,2579274686,3574697629,3205460757,3593280638,3338716283,3079412587,564236357,2993598910,1781952180,1464380207,3163844217,3332601554,1699332808,1393555694,1183702653,3581086237,1288719814,691649499,2847557200,2895455976,3193889540,2717570544,1781354906,1676643554,2592534050,3230253752,1126444790,2770207658,2633158820,2210423226,2615765581,2414155088,3127139286,673620729,2805611233,1269405062,4015350505,3341807571,4149409754,1057255273,2012875353,2162469141,2276492801,2601117357,993977747,3918593370,2654263191,753973209,36408145,2530585658,25011837,3520020182,2088578344,530523599,2918365339,1524020338,1518925132,3760827505,3759777254,1202760957,3985898139,3906192525,674977740,4174734889,2031300136,2019492241,3983892565,4153806404,3822280332,352677332,2297720250,60907813,90501309,3286998549,1016092578,2535922412,2839152426,457141659,509813237,4120667899,652014361,1966332200,2975202805,55981186,2327461051,676427537,3255491064,2882294119,3433927263,1307055953,942726286,933058658,2468411793,3933900994,4215176142,1361170020,2001714738,2830558078,3274259782,1222529897,1679025792,2729314320,3714953764,1770335741,151462246,3013232138,1682292957,1483529935,471910574,1539241949,458788160,3436315007,1807016891,3718408830,978976581,1043663428,3165965781,1927990952,4200891579,2372276910,3208408903,3533431907,1412390302,2931980059,4132332400,1947078029,3881505623,4168226417,2941484381,1077988104,1320477388,886195818,18198404,3786409e3,2509781533,112762804,3463356488,1866414978,891333506,18488651,661792760,1628790961,3885187036,3141171499,876946877,2693282273,1372485963,791857591,2686433993,3759982718,3167212022,3472953795,2716379847,445679433,3561995674,3504004811,3574258232,54117162,3331405415,2381918588,3769707343,4154350007,1140177722,4074052095,668550556,3214352940,367459370,261225585,2610173221,4209349473,3468074219,3265815641,314222801,3066103646,3808782860,282218597,3406013506,3773591054,379116347,1285071038,846784868,2669647154,3771962079,3550491691,2305946142,453669953,1268987020,3317592352,3279303384,3744833421,2610507566,3859509063,266596637,3847019092,517658769,3462560207,3443424879,370717030,4247526661,2224018117,4143653529,4112773975,2788324899,2477274417,1456262402,2901442914,1517677493,1846949527,2295493580,3734397586,2176403920,1280348187,1908823572,3871786941,846861322,1172426758,3287448474,3383383037,1655181056,3139813346,901632758,1897031941,2986607138,3066810236,3447102507,1393639104,373351379,950779232,625454576,3124240540,4148612726,2007998917,544563296,2244738638,2330496472,2058025392,1291430526,424198748,50039436,29584100,3605783033,2429876329,2791104160,1057563949,3255363231,3075367218,3463963227,1469046755,985887462],M=$.length,T=U.length,x=[1332899944,1700884034,1701343084,1684370003,1668446532,1869963892],k=0,G=4096,S=4164,F=4168,L=4192,R=4200,j=4272,B="./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",D=[0,1,54,55,56,57,58,59,60,61,62,63,-1,-1,-1,-1,-1,-1,-1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,-1,-1,-1,-1,-1,-1,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,-1,-1,-1,-1,-1],z=/^\$2[ay]\$(0[4-9]|[12][0-9]|3[01])\$[.\/A-Za-z0-9]{21}[.Oeu]/,Z=/^\$2[ay]\$(0[4-9]|[12][0-9]|3[01])\$[.\/A-Za-z0-9]{21}[.Oeu][.\/A-Za-z0-9]{30}[.CGKOSWaeimquy26]$/;r.genSalt=v,r.hashSync=d,r.hash=h,r.compareSync=w,r.compare=A,r.ENCODING_UTF8=0,r.ENCODING_RAW=1,r.encodingMode=r.ENCODING_UTF8,r.cryptoRNG=!!b,r.randomBytes=b,r.defaultCost=N,r.version="2.2.0"});
--------------------------------------------------------------------------------