diff options
Diffstat (limited to '_www/public/build/bundle.css.map')
| -rw-r--r-- | _www/public/build/bundle.css.map | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/_www/public/build/bundle.css.map b/_www/public/build/bundle.css.map index dd549ed..796023e 100644 --- a/_www/public/build/bundle.css.map +++ b/_www/public/build/bundle.css.map @@ -21,7 +21,7 @@ "<script context=\"module\">\n\timport { messages } from \"./Notif.store.js\"\n\timport NotifItem from \"./NotifItem.svelte\"\n\n\texport const WuiPushNotif = {\n\t\tInfo: function(text) {\n\t\t\tconst msg = {\n\t\t\t\ttext: text,\n\t\t\t}\n\t\t\tmessages.update(msgs => msgs = [...msgs, msg])\n\t\t},\n\t\tError: function(text) {\n\t\t\tconst msg = {\n\t\t\t\ttext: text,\n\t\t\t\tkind: \"error\",\n\t\t\t}\n\t\t\tmessages.update(msgs => msgs = [...msgs, msg])\n\t\t}\n\t}\n</script>\n<script>\n\texport let timeout = 5000;\n</script>\n\n<style>\n\t.wui-notif {\n\t\tposition: fixed;\n\t\ttop: 5px;\n\t\tleft: calc((100% - 400px)/2);\n\t\twidth: 400px;\n\t}\n\t@media (max-width: 500px) {\n\t\t.wui-notif {\n\t\t\tleft: 1em;\n\t\t\twidth: calc(100% - 2em);\n\t\t}\n\t}\n</style>\n\n<div class=\"wui-notif\">\n\t{#each $messages as msg (msg)}\n\t<NotifItem text={msg.text} kind=\"{msg.kind}\" {timeout}/>\n\t{/each}\n</div>\n", "<script>\n\timport { onMount } from 'svelte'\n\timport { fade } from 'svelte/transition'\n\timport { messages } from \"./Notif.store.js\"\n\n\texport let text = \"\"\n\texport let kind = \"\"\n\texport let timeout = 5000\n\n\tonMount(() => {\n\t\tlet timerID = setTimeout(()=> {\n\t\t\tmessages.update(msgs => {\n\t\t\t\tmsgs.splice(0, 1);\n\t\t\t\tmsgs = msgs\n\t\t\t\treturn msgs\n\t\t\t})\n\t\t}, timeout)\n\t})\n</script>\n\n<style>\n\t.wui-notif-item {\n\t\tbackground-color: white;\n\t\tborder: 1px solid black;\n\t\tbox-shadow: 3px 3px;\n\t\tpadding: 1em;\n\t\tmargin-bottom: 1em;\n\t\tz-index: 1000;\n\t}\n\t.wui-notif-item.error {\n\t\tborder: 1px solid red;\n\t\tbox-shadow: 3px 3px red;\n\t}\n</style>\n\n<div transition:fade class=\"wui-notif-item {kind}\">\n\t{text}\n</div>\n", "<script>\n\timport { onMount } from 'svelte';\n\timport { WuiNotif, WuiPushNotif } from 'wui.svelte';\n\n\timport { apiEnvironment, environment, nanoSeconds, setEnvironment } from './environment.js';\n\timport Dashboard from './Dashboard.svelte';\n\timport Environment from './Environment.svelte';\n\timport HostsBlock from './HostsBlock.svelte';\n\timport HostsDir from './HostsDir.svelte';\n\timport MasterDir from './MasterDir.svelte';\n\n\tconst stateEnvironment = \"environment\";\n\tconst stateHostsBlock = \"hosts_block\";\n\tconst stateHostsDir = \"hosts_d\";\n\tconst stateMasterDir = \"master_d\";\n\n\tlet state;\n\tlet env = {\n\t\tNameServers: [],\n\t\tHostsBlocks: [],\n\t\tHostsFiles: {},\n\t};\n\n\tonMount(async () => {\n\t\tconst res = await fetch(apiEnvironment);\n\t\tif (res.status >= 400) {\n\t\t\tWuiPushNotif.Error(\"ERROR: {apiEnvironment}: \",\n\t\t\t\tres.status, res.statusText);\n\t\t\treturn;\n\t\t}\n\n\t\tsetEnvironment(await res.json());\n \t\tstate = window.location.hash.slice(1);\n\t});\n</script>\n\n<style>\n\tdiv.main {\n\t\tmargin: 0 auto;\n\t\twidth: 800px;\n\t\tpadding: 0px 1em;\n\t}\n\tnav.menu {\n\t\tcolor: #ff3e00;\n\t\ttext-transform: uppercase;\n\t\tfont-weight: 100;\n\t\tmargin-bottom: 2em;\n\t}\n\t.active {\n\t\tpadding-bottom: 4px;\n\t\tborder-bottom: 4px solid #ff3e00;\n\t}\n\t@media (max-width: 900px) {\n\t\tdiv.main {\n\t\t\twidth: calc(100% - 2em);\n\t\t}\n\t}\n</style>\n\n<WuiNotif timeout=3000 />\n\n<div class=\"main\">\n\t<nav class=\"menu\">\n\t\t<a\n\t\t\thref=\"#home\"\n\t\t\ton:click={()=>state=\"\"}\n\t\t\tclass:active=\"{state===''||state==='home'}\"\n\t\t>\n\t\t\trescached\n\t\t</a>\n\t\t/\n\t\t<a\n\t\t\thref=\"#environment\"\n\t\t\ton:click={()=>state=stateEnvironment}\n\t\t\tclass:active=\"{state===stateEnvironment}\"\n\t\t>\n\t\t\tEnvironment\n\t\t</a>\n\t\t/\n\t\t<a\n\t\t\thref=\"#{stateHostsBlock}\"\n\t\t\ton:click={()=>state=stateHostsBlock}\n\t\t\tclass:active=\"{state===stateHostsBlock}\"\n\t\t>\n\t\t\tHosts blocks\n\t\t</a>\n\t\t/\n\t\t<a\n\t\t\thref=\"#{stateHostsDir}\"\n\t\t\ton:click={()=>state=stateHostsDir}\n\t\t\tclass:active=\"{state === stateHostsDir}\"\n\t\t>\n\t\t\thosts.d\n\t\t</a>\n\t\t/\n\t\t<a\n\t\t\thref=\"#{stateMasterDir}\"\n\t\t\ton:click={()=>state=stateMasterDir}\n\t\t\tclass:active=\"{state === stateMasterDir}\"\n\t\t>\n\t\t\tmaster.d\n\t\t</a>\n\t</nav>\n\n\t{#if state === stateEnvironment}\n\t\t<Environment/>\n\t{:else if state === stateHostsBlock}\n\t\t<HostsBlock/>\n\t{:else if state === stateHostsDir}\n\t\t<HostsDir/>\n\t{:else if state === stateMasterDir}\n\t\t<MasterDir/>\n\t{:else}\n\t\t<Dashboard/>\n\t{/if}\n</div>\n", - "<script>\n\timport {WuiPushNotif} from 'wui.svelte';\n\timport {getRRTypeName} from './common.js';\n\n\tconst apiCaches = \"/api/caches\";\n\n\tlet query = \"\";\n\tlet listMsg = [];\n\n\tasync function handleSearch() {\n\t\tconst res = await fetch(apiCaches+\"?query=\"+ query)\n\n\t\tif (res.status >= 400) {\n\t\t\tconst resbody = await res.json()\n\t\t\tWuiPushNotif.Error(\"ERROR: \", resbody.message)\n\t\t\treturn;\n\t\t}\n\n\t\tlistMsg = await res.json()\n\t}\n\n\tasync function handleRemoveFromCaches(name) {\n\t\tconst res = await fetch(apiCaches+\"?name=\"+ name, {\n\t\t\tmethod: \"DELETE\",\n\t\t})\n\n\t\tif (res.status >= 400) {\n\t\t\tconst resbody = await res.json()\n\t\t\tWuiPushNotif.Error(\"ERROR: \", resbody.message)\n\t\t\treturn;\n\t\t}\n\n\t\tfor (let x = 0; x < listMsg.length; x++) {\n\t\t\tif (listMsg[x].Question.Name === name) {\n\t\t\t\tlistMsg.splice(x, 1)\n\t\t\t\tlistMsg = listMsg\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tconst msg = await res.json()\n\n\t\tWuiPushNotif.Info(msg.message)\n\t}\n</script>\n\n<style>\n\t.message {\n\t\tpadding: 1em 0px;\n\t\tborder-bottom: 1px solid silver;\n\t}\n\t.rr {\n\t\tmargin-left: 1em;\n\t\twidth: 100%;\n\t}\n\t.rr.header {\n\t\tfont-weight: bold;\n\t}\n\t.rr span {\n\t\tdisplay: inline-block;\n\t}\n\t.kind {\n\t\twidth: 9em;\n\t}\n\t.type {\n\t\twidth: 5em;\n\t}\n\t.ttl {\n\t\twidth: 6em;\n\t}\n</style>\n\n<div class=\"dashboard\">\n\t<div class=\"search\">\n\t\tCaches:\n\t\t<input bind:value={query}>\n\t\t<button on:click={handleSearch}>\n\t\t\tSearch\n\t\t</button>\n\t</div>\n\t{#each listMsg as msg (msg)}\n\t\t<div class=\"message\">\n\t\t\t<div class=\"qname\">\n\t\t\t\t{msg.Question.Name}\n\n\t\t\t\t<button\n\t\t\t\t\tclass=\"b-remove\"\n\t\t\t\t\ton:click={handleRemoveFromCaches(msg.Question.Name)}\n\t\t\t\t>\n\t\t\t\t\tRemove from caches\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t\t<div class=\"rr header\">\n\t\t\t\t<span class=\"kind\"> </span>\n\t\t\t\t<span class=\"type\"> Type </span>\n\t\t\t\t<span class=\"ttl\"> TTL </span>\n\t\t\t\t<span class=\"value\"> Value </span>\n\t\t\t</div>\n\t\t\t{#each msg.Answer as rr}\n\t\t\t\t<div class=\"rr\">\n\t\t\t\t\t<span class=\"kind\"> Answer </span>\n\t\t\t\t\t<span class=\"type\"> {getRRTypeName(rr.Type)} </span>\n\t\t\t\t\t<span class=\"ttl\"> {rr.TTL} </span>\n\t\t\t\t\t<span class=\"value\"> {rr.Value} </span>\n\t\t\t\t</div>\n\t\t\t{/each}\n\t\t\t{#if msg.Authority !== null && msg.Authority.length > 0}\n\t\t\t\t{#each msg.Authority as rr}\n\t\t\t\t\t<div class=\"rr\">\n\t\t\t\t\t\t<span class=\"kind\"> Authority </span>\n\t\t\t\t\t\t<span class=\"type\"> {getRRTypeName(rr.Type)} </span>\n\t\t\t\t\t\t<span class=\"ttl\"> {rr.TTL} </span>\n\t\t\t\t\t\t<span class=\"value\"> {rr.Value} </span>\n\t\t\t\t\t</div>\n\t\t\t\t{/each}\n\t\t\t{/if}\n\t\t\t{#if msg.Additional !== null && msg.Additional.length > 0}\n\t\t\t\t{#each msg.Additional as rr}\n\t\t\t\t\t<div class=\"rr\">\n\t\t\t\t\t\t<span class=\"kind\"> Additional </span>\n\t\t\t\t\t\t<span class=\"type\"> {getRRTypeName(rr.Type)} </span>\n\t\t\t\t\t\t<span class=\"ttl\"> {rr.TTL} </span>\n\t\t\t\t\t\t<span class=\"value\"> {rr.Value} </span>\n\t\t\t\t\t</div>\n\t\t\t\t{/each}\n\t\t\t{/if}\n\t\t</div>\n\t{/each}\n</div>\n", + "<script>\n\timport {WuiPushNotif} from 'wui.svelte';\n\timport {getRRTypeName} from './common.js';\n\n\tconst apiCaches = \"/api/caches\";\n\n\tlet query = \"\";\n\tlet listMsg = [];\n\n\tasync function handleSearch() {\n\t\tconst res = await fetch(apiCaches+\"?query=\"+ query)\n\n\t\tif (res.status >= 400) {\n\t\t\tconst resbody = await res.json()\n\t\t\tWuiPushNotif.Error(\"ERROR: \"+ resbody.message)\n\t\t\treturn;\n\t\t}\n\n\t\tlistMsg = await res.json()\n\t}\n\n\tasync function handleRemoveFromCaches(name) {\n\t\tconst res = await fetch(apiCaches+\"?name=\"+ name, {\n\t\t\tmethod: \"DELETE\",\n\t\t})\n\n\t\tif (res.status >= 400) {\n\t\t\tconst resbody = await res.json()\n\t\t\tWuiPushNotif.Error(\"ERROR: \"+ resbody.message)\n\t\t\treturn;\n\t\t}\n\n\t\tfor (let x = 0; x < listMsg.length; x++) {\n\t\t\tif (listMsg[x].Question.Name === name) {\n\t\t\t\tlistMsg.splice(x, 1)\n\t\t\t\tlistMsg = listMsg\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tconst msg = await res.json()\n\n\t\tWuiPushNotif.Info(msg.message)\n\t}\n</script>\n\n<style>\n\t.message {\n\t\tpadding: 1em 0px;\n\t\tborder-bottom: 1px solid silver;\n\t}\n\t.rr {\n\t\tmargin-left: 1em;\n\t\twidth: 100%;\n\t}\n\t.rr.header {\n\t\tfont-weight: bold;\n\t}\n\t.rr span {\n\t\tdisplay: inline-block;\n\t}\n\t.kind {\n\t\twidth: 9em;\n\t}\n\t.type {\n\t\twidth: 5em;\n\t}\n\t.ttl {\n\t\twidth: 6em;\n\t}\n</style>\n\n<div class=\"dashboard\">\n\t<div class=\"search\">\n\t\tCaches:\n\t\t<input bind:value={query}>\n\t\t<button on:click={handleSearch}>\n\t\t\tSearch\n\t\t</button>\n\t</div>\n\t{#each listMsg as msg (msg)}\n\t\t<div class=\"message\">\n\t\t\t<div class=\"qname\">\n\t\t\t\t{msg.Question.Name}\n\n\t\t\t\t<button\n\t\t\t\t\tclass=\"b-remove\"\n\t\t\t\t\ton:click={handleRemoveFromCaches(msg.Question.Name)}\n\t\t\t\t>\n\t\t\t\t\tRemove from caches\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t\t<div class=\"rr header\">\n\t\t\t\t<span class=\"kind\"> </span>\n\t\t\t\t<span class=\"type\"> Type </span>\n\t\t\t\t<span class=\"ttl\"> TTL </span>\n\t\t\t\t<span class=\"value\"> Value </span>\n\t\t\t</div>\n\n\t\t\t{#if msg.Answer !== null && msg.Answer.length > 0}\n\t\t\t\t{#each msg.Answer as rr}\n\t\t\t\t\t<div class=\"rr\">\n\t\t\t\t\t\t<span class=\"kind\"> Answer </span>\n\t\t\t\t\t\t<span class=\"type\"> {getRRTypeName(rr.Type)} </span>\n\t\t\t\t\t\t<span class=\"ttl\"> {rr.TTL} </span>\n\t\t\t\t\t\t<span class=\"value\"> {rr.Value} </span>\n\t\t\t\t\t</div>\n\t\t\t\t{/each}\n\t\t\t{/if}\n\t\t\t{#if msg.Authority !== null && msg.Authority.length > 0}\n\t\t\t\t{#each msg.Authority as rr}\n\t\t\t\t\t<div class=\"rr\">\n\t\t\t\t\t\t<span class=\"kind\"> Authority </span>\n\t\t\t\t\t\t<span class=\"type\"> {getRRTypeName(rr.Type)} </span>\n\t\t\t\t\t\t<span class=\"ttl\"> {rr.TTL} </span>\n\t\t\t\t\t\t<span class=\"value\"> {rr.Value} </span>\n\t\t\t\t\t</div>\n\t\t\t\t{/each}\n\t\t\t{/if}\n\t\t\t{#if msg.Additional !== null && msg.Additional.length > 0}\n\t\t\t\t{#each msg.Additional as rr}\n\t\t\t\t\t<div class=\"rr\">\n\t\t\t\t\t\t<span class=\"kind\"> Additional </span>\n\t\t\t\t\t\t<span class=\"type\"> {getRRTypeName(rr.Type)} </span>\n\t\t\t\t\t\t<span class=\"ttl\"> {rr.TTL} </span>\n\t\t\t\t\t\t<span class=\"value\"> {rr.Value} </span>\n\t\t\t\t\t</div>\n\t\t\t\t{/each}\n\t\t\t{/if}\n\t\t</div>\n\t{/each}\n</div>\n", "<script>\n\timport { onDestroy } from 'svelte';\n\n\timport { apiEnvironment, environment, nanoSeconds } from './environment.js';\n\timport { WuiPushNotif } from \"wui.svelte\";\n\timport { WuiLabelHint, WuiInputNumber, WuiInputIPPort } from \"wui.svelte\";\n\n\tlet env = {\n\t\tNameServers: [],\n\t\tHostsBlocks: [],\n\t\tHostsFiles: {},\n\t};\n\n\tconst envUnsubscribe = environment.subscribe(value => {\n\t\tenv = value;\n\t});\n\n\tonDestroy(envUnsubscribe);\n\n\tconst defTitleWidth = \"300px\";\n\n\tfunction addNameServer() {\n\t\tenv.NameServers = [...env.NameServers, '']\n\t}\n\n\tfunction deleteNameServer(ns) {\n\t\tfor (let x = 0; x < env.NameServers.length; x++) {\n\t\t\tif (env.NameServers[x] === ns) {\n\t\t\t\tenv.NameServers.splice(x, 1);\n\t\t\t\tenv.NameServers = env.NameServers;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tasync function updateEnvironment() {\n\t\tlet got = {};\n\n\t\tObject.assign(got, env)\n\t\tenvironment.set(env)\n\n\t\tgot.PruneDelay = got.PruneDelay * nanoSeconds;\n\t\tgot.PruneThreshold = got.PruneThreshold * nanoSeconds;\n\n\t\tconst res = await fetch(apiEnvironment, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t},\n\t\t\tbody: JSON.stringify(got),\n\t\t});\n\n\t\tif (res.status >= 400) {\n\t\t\tconst resbody = await res.json()\n\t\t\tWuiPushNotif.Error(\"ERROR: \", resbody.message)\n\t\t\treturn;\n\t\t}\n\n\t\tWuiPushNotif.Info(\"The environment succesfully updated ...\")\n\t}\n</script>\n\n<style>\n\tinput {\n\t\twidth: 100%;\n\t}\n\t.input-deletable {\n\t\twidth: 100%;\n\t}\n\t.input-deletable > input {\n\t\tmax-width: calc(100% - 100px);\n\t}\n\t.input-deletable > button {\n\t\twidth: 80px;\n\t}\n\t.input-checkbox {\n\t\twidth: 100%;\n\t}\n\t.input-checkbox input[type=\"checkbox\"] {\n\t\twidth: auto;\n\t}\n\t.section-bottom {\n\t\tmargin: 2em 0px 0px 0px;\n\t\tpadding: 1em;\n\t\tborder-top: 1px solid black;\n\t}\n</style>\n\n<div class=\"environment\">\n<p>\nThis page allow you to change the rescached environment.\nUpon save, the rescached service will be restarted.\n</p>\n\n<h3>rescached</h3>\n<div>\n\t<WuiLabelHint\n\t\ttitle=\"System resolv.conf\"\n\t\ttitle_width=\"{defTitleWidth}\"\n\t\tinfo=\"A path to dynamically generated resolv.conf(5) by\nresolvconf(8). If set, the nameserver values in referenced file will\nreplace 'parent' value and 'parent' will become a fallback in\ncase the referenced file being deleted or can not be parsed.\"\n\t>\n\t\t<input\n\t\t\tbind:value={env.FileResolvConf}\n\t\t/>\n\t</WuiLabelHint>\n\n\t<WuiLabelHint\n\t\ttitle=\"Debug level\"\n\t\ttitle_width=\"{defTitleWidth}\"\n\t\tinfo=\"This option only used for debugging program or if user\nwant to monitor what kind of traffic goes in and out of rescached.\"\n\t>\n\t\t<WuiInputNumber\n\t\t\tmin=0\n\t\t\tmax=3\n\t\t\tbind:value={env.Debug}\n\t\t\tunit=\"\"\n\t\t/>\n\t</WuiLabelHint>\n</div>\n\n<h3>DNS server</h3>\n<div>\n\t<WuiLabelHint\n\t\ttitle=\"Parent name servers\"\n\t\ttitle_width=\"{defTitleWidth}\"\n\t\tinfo=\"List of parent DNS servers.\"\n\t>\n\t</WuiLabelHint>\n\n\t{#each env.NameServers as ns}\n\t<div class=\"input-deletable\">\n\t\t<input bind:value={ns}>\n\t\t<button on:click={deleteNameServer(ns)}>\n\t\t\tDelete\n\t\t</button>\n\t</div>\n\t{/each}\n\n\t<button\n\t\ton:click={addNameServer}\n\t>\n\t\tAdd\n\t</button>\n\n\t<WuiLabelHint\n\t\ttitle=\"Listen address\"\n\t\ttitle_width=\"{defTitleWidth}\"\n\t\tinfo=\"Address in local network where rescached will\nlistening for query from client through UDP and TCP.\n<br/>\nIf you want rescached to serve a query from another host in your local\nnetwork, change this value to <tt>0.0.0.0:53</tt>.\"\n\t>\n\t\t<WuiInputIPPort\n\t\t\tbind:value={env.ListenAddress}\n\t\t/>\n\t</WuiLabelHint>\n\n\t<WuiLabelHint\n\t\ttitle=\"HTTP listen port\"\n\t\ttitle_width=\"{defTitleWidth}\"\n\t\tinfo=\"Port to serve DNS over HTTP\"\n\t>\n\t\t<WuiInputNumber\n\t\t\tmin=0\n\t\t\tmax=65535\n\t\t\tbind:value={env.HTTPPort}\n\t\t\tunit=\"\"\n\t\t/>\n\t</WuiLabelHint>\n\n\t<WuiLabelHint\n\t\ttitle=\"TLS listen port\"\n\t\ttitle_width=\"{defTitleWidth}\"\n\t\tinfo=\"Port to listen for DNS over TLS\"\n\t>\n\t\t<WuiInputNumber\n\t\t\tmin=0\n\t\t\tmax=65535\n\t\t\tbind:value={env.TLSPort}\n\t\t\tunit=\"\"\n\t\t/>\n\t</WuiLabelHint>\n\n\t<WuiLabelHint\n\t\ttitle=\"TLS certificate\"\n\t\ttitle_width=\"{defTitleWidth}\"\n\t\tinfo=\"Path to certificate file to serve DNS over TLS and\nHTTPS\">\n\t\t<input\n\t\t\tplaceholder=\"/path/to/certificate\"\n\t\t\tbind:value={env.TLSCertFile}\n\t\t/>\n\t</WuiLabelHint>\n\n\t<WuiLabelHint\n\t\ttitle=\"TLS private key\"\n\t\ttitle_width=\"{defTitleWidth}\"\n\t\tinfo=\"Path to certificate private key file to serve DNS over TLS and\nHTTPS.\"\n\t>\n\t\t<input\n\t\t\tplaceholder=\"/path/to/certificate/private.key\"\n\t\t\tbind:value={env.TLSPrivateKey}\n\t\t/>\n\t</WuiLabelHint>\n\n\t<WuiLabelHint\n\t\ttitle=\"TLS allow insecure\"\n\t\ttitle_width=\"{defTitleWidth}\"\n\t\tinfo=\"If its true, allow serving DoH and DoT with self signed\ncertificate.\"\n\t>\n\t\t<div class=\"input-checkbox\">\n\t\t\t<input\n\t\t\t\ttype=checkbox\n\t\t\t\tbind:checked={env.TLSAllowInsecure}\n\t\t\t>\n\t\t\t<span class=\"suffix\">\n\t\t\t\tYes\n\t\t\t</span>\n\t\t</div>\n\t</WuiLabelHint>\n\n\t<WuiLabelHint\n\t\ttitle=\"DoH behind proxy\"\n\t\ttitle_width=\"{defTitleWidth}\"\n\t\tinfo=\"If its true, serve DNS over HTTP only, even if\ncertificate files is defined.\nThis allow serving DNS request forwarded by another proxy server.\"\n\t>\n\t\t<div class=\"input-checkbox\">\n\t\t\t<input\n\t\t\t\ttype=checkbox\n\t\t\t\tbind:checked={env.DoHBehindProxy}\n\t\t\t>\n\t\t\t<span class=\"suffix\">\n\t\t\t\tYes\n\t\t\t</span>\n\t\t</div>\n\t</WuiLabelHint>\n\n\t<WuiLabelHint\n\t\ttitle=\"Prune delay\"\n\t\ttitle_width=\"{defTitleWidth}\"\n\t\tinfo=\"Delay for pruning caches.\nEvery N seconds, rescached will traverse all caches and remove response that\nhas not been accessed less than cache.prune_threshold.\nIts value must be equal or greater than 1 hour (3600 seconds).\n\"\n\t>\n\t\t<WuiInputNumber\n\t\t\tmin=3600\n\t\t\tmax=36000\n\t\t\tbind:value={env.PruneDelay}\n\t\t\tunit=\"seconds\"\n\t\t/>\n\t</WuiLabelHint>\n\n\t<WuiLabelHint\n\t\ttitle=\"Prune threshold\"\n\t\ttitle_width=\"{defTitleWidth}\"\n\t\tinfo=\"The duration when the cache will be considered expired.\nIts value must be negative and greater or equal than -1 hour (-3600 seconds).\"\n\t>\n\t\t<WuiInputNumber\n\t\t\tmin=-36000\n\t\t\tmax=-3600\n\t\t\tbind:value={env.PruneThreshold}\n\t\t\tunit=\"seconds\"\n\t\t/>\n\t</WuiLabelHint>\n</div>\n\n\t<div class=\"section-bottom\">\n\t\t<div>\n\t\t\t<button on:click={updateEnvironment}>\n\t\t\t\tSave\n\t\t\t</button>\n\t\t</div>\n\t</div>\n</div>\n", "<script>\n\timport { onDestroy } from 'svelte';\n\timport { WuiPushNotif } from 'wui.svelte';\n\timport { environment, nanoSeconds, setEnvironment } from './environment.js';\n\n\tconst apiHostsBlock = \"/api/hosts_block\"\n\tlet env = {\n\t\tNameServers: [],\n\t\tHostsBlocks: [],\n\t\tHostsFiles: {},\n\t};\n\n\tconst envUnsubscribe = environment.subscribe(value => {\n\t\tenv = value;\n\t});\n\tonDestroy(envUnsubscribe);\n\n\tasync function updateHostsBlocks() {\n\t\tconst res = await fetch(apiHostsBlock, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t},\n\t\t\tbody: JSON.stringify(env.HostsBlocks),\n\t\t});\n\n\t\tif (res.status >= 400) {\n\t\t\tWuiPushNotif.Error(\"ERROR: \", res.status, res.statusText)\n\t\t\treturn;\n\t\t}\n\n\t\tsetEnvironment(await res.json());\n\t}\n</script>\n\n<style>\n\t.block_source {\n\t\twidth: calc(100% - 2em);\n\t\toverflow: auto;\n\t\tfont-size: 12px;\n\t}\n\t.block_source input:disabled {\n\t\tcolor: black;\n\t}\n\t.item span {\n\t\tdisplay: inline-block;\n\t\tmargin-right: 1em;\n\t}\n\t.item.header {\n\t\tfont-weight: bold;\n\t\tmargin-bottom: 1em;\n\t\tborder-bottom: 1px solid silver;\n\t}\n\t.item > span:nth-child(1) {\n\t\twidth: 4em;\n\t}\n\t.item > span:nth-child(2) {\n\t\twidth: 15em;\n\t}\n\t.item > span:nth-child(3) {\n\t\twidth: 23em;\n\t}\n\t.item > span:nth-child(3) input {\n\t\twidth: 100%;\n\t}\n\t.item > span:nth-child(4) {\n\t\twidth: 16em;\n\t}\n</style>\n\n<div class=\"hosts-block\">\n\t<p>\n\tConfigure the source of blocked hosts file.\n\t</p>\n\n\t<div class=\"block_source\">\n\t\t<div class=\"item header\">\n\t\t\t<span> Enabled </span>\n\t\t\t<span> Name </span>\n\t\t\t<span> URL </span>\n\t\t\t<span> Last updated </span>\n\t\t</div>\n\t\t{#each env.HostsBlocks as hostsBlock}\n\t\t<div class=\"item\">\n\t\t\t<span>\n\t\t\t\t<input\n\t\t\t\t\ttype=checkbox\n\t\t\t\t\tbind:checked={hostsBlock.IsEnabled}\n\t\t\t\t>\n\t\t\t</span>\n\t\t\t<span>\n\t\t\t\t{hostsBlock.Name}\n\t\t\t</span>\n\t\t\t<span>\n\t\t\t\t<input\n\t\t\t\t\tbind:value={hostsBlock.URL}\n\t\t\t\t\tdisabled\n\t\t\t\t>\n\t\t\t</span>\n\t\t\t<span>\n\t\t\t\t{hostsBlock.LastUpdated}\n\t\t\t</span>\n\t\t</div>\n\t\t{/each}\n\t</div>\n\n\t<div>\n\t\t<button on:click={updateHostsBlocks}>\n\t\t\tSave\n\t\t</button>\n\t</div>\n</div>\n", "<script> import { onDestroy } from 'svelte';\n\timport { WuiPushNotif } from 'wui.svelte';\n\timport { apiEnvironment, environment, nanoSeconds } from './environment.js';\n\n\tconst apiHostsDir = \"/api/hosts.d\"\n\n\tlet env = {\n\t\tHostsFiles: {},\n\t};\n\tlet hostsFile = {\n\t\tName: \"\",\n\t\tRecords: [],\n\t};\n\tlet newRecord = null;\n\tlet newHostsFile = \"\";\n\n\tconst envUnsubscribe = environment.subscribe(value => {\n\t\tenv = value;\n\t});\n\tonDestroy(envUnsubscribe);\n\n\tasync function getHostsFile(hf) {\n\t\tif (hf.Records === null) {\n\t\t\thf.Records = []\n\t\t}\n\t\tif (hf.Records.length > 0) {\n\t\t\thostsFile = hf;\n\t\t\treturn;\n\t\t}\n\t\tconst res = await fetch(apiHostsDir +\"/\"+ hf.Name);\n\t\thf.Records = await res.json();\n\t\thostsFile = hf;\n\t}\n\n\tasync function createHostsFile() {\n\t\tif (newHostsFile === \"\") {\n\t\t\treturn;\n\t\t}\n\n\t\tconst res = await fetch(apiHostsDir+ \"/\"+ newHostsFile, {\n\t\t\tmethod: \"PUT\",\n\t\t})\n\n\t\tif (res.status >= 400) {\n\t\t\tconst resError = await res.json()\n\t\t\tWuiPushNotif.Error(\"ERROR: createHostsFile: \", resError.message)\n\t\t\treturn;\n\t\t}\n\n\t\tconst hf = {\n\t\t\tName: newHostsFile,\n\t\t\tRecords: [],\n\t\t}\n\t\tenv.HostsFiles[newHostsFile] = hf\n\t\tenv = env\n\n\t\tWuiPushNotif.Info(\"The new host file '\"+ newHostsFile +\"' has been created\")\n\t}\n\n\tasync function updateHostsFile() {\n\t\tconst res = await fetch(apiHostsDir+\"/\"+ hostsFile.Name, {\n\t\t\tmethod: \"POST\",\n\t\t\tbody: JSON.stringify(hostsFile.Records),\n\t\t})\n\n\t\tif (res.status >= 400) {\n\t\t\tconst resError = await res.json()\n\t\t\tWuiPushNotif.Error(\"ERROR: updateHostsFile: \", resError.message)\n\t\t\treturn;\n\t\t}\n\n\t\thostsFile.Records = await res.json()\n\n\t\tWuiPushNotif.Info(\"The host file '\"+ hostsFile.Name +\"' has been updated\")\n\t}\n\n\tfunction addRecord() {\n\t\tif (newRecord !== null) {\n\t\t\treturn\n\t\t}\n\t\tnewRecord = {\n\t\t\tName: \"\",\n\t\t\tValue: \"\",\n\t\t}\n\t}\n\n\tasync function handleHostsRecordCreate() {\n\t\tconst api = apiHostsDir +\"/\"+ hostsFile.Name +\"/rr\"\n\t\t\t+\"?domain=\"+ newRecord.Name\n\t\t\t+\"&value=\"+ newRecord.Value\n\n\t\tconst res = await fetch(api, {\n\t\t\tmethod: \"POST\"\n\t\t})\n\t\tif (res.status >= 400) {\n\t\t\tconst resError = await res.json()\n\t\t\tWuiPushNotif.Error(\"ERROR: \"+ resError.message)\n\t\t\treturn;\n\t\t}\n\t\tconst rr = await res.json()\n\t\thostsFile.Records.push(rr)\n\t\thostsFile.Records = hostsFile.Records\n\t\tnewRecord = null\n\t\tWuiPushNotif.Info(\"Record '\"+ rr.Name +\"' has been created\")\n\t}\n\n\tasync function handleHostsRecordDelete(rr, idx) {\n\t\tconst api = apiHostsDir +\"/\"+ hostsFile.Name +\"/rr\"+\n\t\t\t\"?domain=\"+rr.Name\n\n\t\tconst res = await fetch(api, {\n\t\t\tmethod: \"DELETE\"\n\t\t})\n\t\tif (res.status >= 400) {\n\t\t\tconst resError = await res.json()\n\t\t\tWuiPushNotif.Error(\"ERROR: \"+ resError.message)\n\t\t\treturn;\n\t\t}\n\t\thostsFile.Records.splice(idx, 1);\n\t\thostsFile.Records = hostsFile.Records;\n\t\tWuiPushNotif.Info(\"Record '\"+ rr.Name +\"' has been deleted\")\n\t}\n\n\tasync function deleteHostsFile(hfile) {\n\t\tconst res = await fetch(apiHostsDir+\"/\"+hfile.Name, {\n\t\t\tmethod: \"DELETE\",\n\t\t});\n\t\tif (res.status >= 400) {\n\t\t\tconst resError = await res.json()\n\t\t\tWuiPushNotif.Error(\"ERROR: deleteHostsFile: \", resError.message)\n\t\t\treturn;\n\t\t}\n\t\tdelete env.HostsFiles[hfile.Name]\n\t\tenv = env;\n\t\thostsFile = {\n\t\t\tName: \"\",\n\t\t\tRecords: [],\n\t\t}\n\t\tWuiPushNotif.Info(\"The host file '\"+ hfile.Name +\"' has been deleted\")\n\t}\n</script>\n\n<style>\n\t.nav-left {\n\t\tpadding: 0px;\n\t\twidth: 280px;\n\t\tfloat: left;\n\t}\n\t.nav-left .item {\n\t\tmargin: 4px 0px;\n\t}\n\t.content {\n\t\tfloat: left;\n\t\twidth: calc(100% - 300px);\n\t}\n\t.host {\n\t\tfont-family: monospace;\n\t\twidth: 100%;\n\t}\n\t.host.header {\n\t\tmargin: 1em 0px;\n\t\tfont-weight: bold;\n\t\tborder-bottom: 1px solid silver;\n\t}\n\t.host_name {\n\t\tdisplay: inline-block;\n\t\twidth: 240px;\n\t\tword-wrap: break-word;\n\t}\n\t.host_value {\n\t\tdisplay: inline-block;\n\t\twidth: 140px;\n\t}\n</style>\n\n<div class=\"hosts_d\">\n\t<div class=\"nav-left\">\n\t\t{#each Object.entries(env.HostsFiles) as [name,hf], name }\n\t\t<div class=\"item\">\n\t\t\t<a href=\"#\" on:click={getHostsFile(hf)}>\n\t\t\t\t{hf.Name}\n\t\t\t</a>\n\t\t</div>\n\t\t{/each}\n\n\t\t<br/>\n\n\t\t<label>\n\t\t\t<span>New hosts file:</span>\n\t\t\t<br/>\n\t\t\t<input bind:value={newHostsFile}>\n\t\t</label>\n\t\t<button on:click={createHostsFile}>\n\t\t\tCreate\n\t\t</button>\n\t</div>\n\n\t<div class=\"content\">\n\t\t{#if hostsFile.Name === \"\"}\n\t\t\t<div>\n\t\t\t\tSelect one of the hosts file to manage.\n\t\t\t</div>\n\t\t{:else}\n\t\t\t<p>\n\t\t\t\t{hostsFile.Name} ({hostsFile.Records.length} records)\n\t\t\t\t<button on:click={deleteHostsFile(hostsFile)}>\n\t\t\t\t\tDelete\n\t\t\t\t</button>\n\t\t\t</p>\n\t\t\t<div>\n\t\t\t\t<button on:click={addRecord}>\n\t\t\t\t\tAdd\n\t\t\t\t</button>\n\t\t\t</div>\n\n\t\t\t{#if newRecord !== null}\n\t\t\t\t<div class=\"host\">\n\t\t\t\t\t<input\n\t\t\t\t\t\tclass=\"host_name\"\n\t\t\t\t\t\tplaceholder=\"Domain name\"\n\t\t\t\t\t\tbind:value={newRecord.Name}\n\t\t\t\t\t>\n\t\t\t\t\t<input\n\t\t\t\t\t\tclass=\"host_value\"\n\t\t\t\t\t\tplaceholder=\"IP address\"\n\t\t\t\t\t\tbind:value={newRecord.Value}\n\t\t\t\t\t>\n\t\t\t\t\t<button on:click={handleHostsRecordCreate}>\n\t\t\t\t\t\tCreate\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t{/if}\n\n\t\t\t<div class=\"host header\">\n\t\t\t\t<span class=\"host_name\"> Domain name </span>\n\t\t\t\t<span class=\"host_value\"> IP address </span>\n\t\t\t</div>\n\n\t\t\t{#each hostsFile.Records as rr, idx (idx)}\n\t\t\t\t<div class=\"host\">\n\t\t\t\t\t<span class=\"host_name\"> {rr.Name} </span>\n\t\t\t\t\t<span class=\"host_value\"> {rr.Value} </span>\n\t\t\t\t\t<button on:click={handleHostsRecordDelete(rr, idx)}>\n\t\t\t\t\t\tX\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t{/each}\n\t\t{/if}\n\t</div>\n</div>\n", |
