init commit

This commit is contained in:
Luka Dekanozishvili 2026-01-18 14:55:11 +01:00
parent dfe324cf8f
commit 7e37f1bbe0
31 changed files with 2103 additions and 718 deletions

389
deno.lock generated
View file

@ -1,161 +1,161 @@
{ {
"version": "5", "version": "5",
"specifiers": { "specifiers": {
"npm:@eslint/compat@^1.4.0": "1.4.1_eslint@9.39.1", "npm:@eslint/compat@^1.4.1": "1.4.1_eslint@9.39.2",
"npm:@eslint/js@^9.39.1": "9.39.1", "npm:@eslint/js@^9.39.2": "9.39.2",
"npm:@sveltejs/adapter-node@^5.4.0": "5.4.0_@sveltejs+kit@2.49.0__@sveltejs+vite-plugin-svelte@6.2.1___svelte@5.44.1____acorn@8.15.0___vite@7.2.4____@types+node@22.19.1____picomatch@4.0.3___@types+node@22.19.1__svelte@5.44.1___acorn@8.15.0__vite@7.2.4___@types+node@22.19.1___picomatch@4.0.3__acorn@8.15.0__@types+node@22.19.1_rollup@4.53.3_@sveltejs+vite-plugin-svelte@6.2.1__svelte@5.44.1___acorn@8.15.0__vite@7.2.4___@types+node@22.19.1___picomatch@4.0.3__@types+node@22.19.1_svelte@5.44.1__acorn@8.15.0_vite@7.2.4__@types+node@22.19.1__picomatch@4.0.3_@types+node@22.19.1", "npm:@sveltejs/adapter-node@^5.4.0": "5.4.0_@sveltejs+kit@2.49.3__@sveltejs+vite-plugin-svelte@6.2.2___svelte@5.46.1____acorn@8.15.0___vite@7.3.0____@types+node@22.19.3____picomatch@4.0.3___@types+node@22.19.3__svelte@5.46.1___acorn@8.15.0__typescript@5.9.3__vite@7.3.0___@types+node@22.19.3___picomatch@4.0.3__acorn@8.15.0__@types+node@22.19.3_rollup@4.53.3_@sveltejs+vite-plugin-svelte@6.2.2__svelte@5.46.1___acorn@8.15.0__vite@7.3.0___@types+node@22.19.3___picomatch@4.0.3__@types+node@22.19.3_svelte@5.46.1__acorn@8.15.0_typescript@5.9.3_vite@7.3.0__@types+node@22.19.3__picomatch@4.0.3_@types+node@22.19.3",
"npm:@sveltejs/kit@^2.48.5": "2.49.0_@sveltejs+vite-plugin-svelte@6.2.1__svelte@5.44.1___acorn@8.15.0__vite@7.2.4___@types+node@22.19.1___picomatch@4.0.3__@types+node@22.19.1_svelte@5.44.1__acorn@8.15.0_vite@7.2.4__@types+node@22.19.1__picomatch@4.0.3_acorn@8.15.0_@types+node@22.19.1", "npm:@sveltejs/kit@^2.49.3": "2.49.3_@sveltejs+vite-plugin-svelte@6.2.2__svelte@5.46.1___acorn@8.15.0__vite@7.3.0___@types+node@22.19.3___picomatch@4.0.3__@types+node@22.19.3_svelte@5.46.1__acorn@8.15.0_typescript@5.9.3_vite@7.3.0__@types+node@22.19.3__picomatch@4.0.3_acorn@8.15.0_@types+node@22.19.3",
"npm:@sveltejs/vite-plugin-svelte@^6.2.1": "6.2.1_svelte@5.44.1__acorn@8.15.0_vite@7.2.4__@types+node@22.19.1__picomatch@4.0.3_@types+node@22.19.1", "npm:@sveltejs/vite-plugin-svelte@^6.2.2": "6.2.2_svelte@5.46.1__acorn@8.15.0_vite@7.3.0__@types+node@22.19.3__picomatch@4.0.3_@types+node@22.19.3",
"npm:@tailwindcss/forms@~0.5.10": "0.5.10_tailwindcss@4.1.17", "npm:@tailwindcss/forms@~0.5.11": "0.5.11_tailwindcss@4.1.18",
"npm:@tailwindcss/typography@~0.5.19": "0.5.19_tailwindcss@4.1.17", "npm:@tailwindcss/typography@~0.5.19": "0.5.19_tailwindcss@4.1.18",
"npm:@tailwindcss/vite@^4.1.17": "4.1.17_vite@7.2.4__@types+node@22.19.1__picomatch@4.0.3_@types+node@22.19.1", "npm:@tailwindcss/vite@^4.1.18": "4.1.18_vite@7.3.0__@types+node@22.19.3__picomatch@4.0.3_@types+node@22.19.3",
"npm:@types/node@22": "22.19.1", "npm:@types/node@^22.19.3": "22.19.3",
"npm:daisyui@^5.5.5": "5.5.5", "npm:daisyui@^5.5.14": "5.5.14",
"npm:eslint-plugin-svelte@^3.13.0": "3.13.0_eslint@9.39.1_svelte@5.44.1__acorn@8.15.0_postcss@8.5.6", "npm:eslint-plugin-svelte@^3.13.1": "3.13.1_eslint@9.39.2_svelte@5.46.1__acorn@8.15.0_postcss@8.5.6",
"npm:eslint@^9.39.1": "9.39.1", "npm:eslint@^9.39.2": "9.39.2",
"npm:globals@^16.5.0": "16.5.0", "npm:globals@^16.5.0": "16.5.0",
"npm:prettier-plugin-svelte@^3.4.0": "3.4.0_prettier@3.7.4_svelte@5.44.1__acorn@8.15.0", "npm:prettier-plugin-svelte@^3.4.1": "3.4.1_prettier@3.7.4_svelte@5.46.1__acorn@8.15.0",
"npm:prettier@^3.7.4": "3.7.4", "npm:prettier@^3.7.4": "3.7.4",
"npm:svelte-check@^4.3.4": "4.3.4_svelte@5.44.1__acorn@8.15.0_typescript@5.9.3", "npm:svelte-check@^4.3.5": "4.3.5_svelte@5.46.1__acorn@8.15.0_typescript@5.9.3",
"npm:svelte@^5.43.8": "5.44.1_acorn@8.15.0", "npm:svelte@^5.46.1": "5.46.1_acorn@8.15.0",
"npm:tailwindcss@^4.1.17": "4.1.17", "npm:tailwindcss@^4.1.18": "4.1.18",
"npm:typescript-eslint@^8.47.0": "8.48.0_eslint@9.39.1_typescript@5.9.3_@typescript-eslint+parser@8.48.0__eslint@9.39.1__typescript@5.9.3", "npm:typescript-eslint@^8.52.0": "8.52.0_eslint@9.39.2_typescript@5.9.3_@typescript-eslint+parser@8.52.0__eslint@9.39.2__typescript@5.9.3",
"npm:typescript@^5.9.3": "5.9.3", "npm:typescript@^5.9.3": "5.9.3",
"npm:vite@^7.2.2": "7.2.4_@types+node@22.19.1_picomatch@4.0.3" "npm:vite@^7.3.0": "7.3.0_@types+node@22.19.3_picomatch@4.0.3"
}, },
"npm": { "npm": {
"@esbuild/aix-ppc64@0.25.12": { "@esbuild/aix-ppc64@0.27.2": {
"integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", "integrity": "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==",
"os": ["aix"], "os": ["aix"],
"cpu": ["ppc64"] "cpu": ["ppc64"]
}, },
"@esbuild/android-arm64@0.25.12": { "@esbuild/android-arm64@0.27.2": {
"integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", "integrity": "sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==",
"os": ["android"], "os": ["android"],
"cpu": ["arm64"] "cpu": ["arm64"]
}, },
"@esbuild/android-arm@0.25.12": { "@esbuild/android-arm@0.27.2": {
"integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", "integrity": "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==",
"os": ["android"], "os": ["android"],
"cpu": ["arm"] "cpu": ["arm"]
}, },
"@esbuild/android-x64@0.25.12": { "@esbuild/android-x64@0.27.2": {
"integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", "integrity": "sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==",
"os": ["android"], "os": ["android"],
"cpu": ["x64"] "cpu": ["x64"]
}, },
"@esbuild/darwin-arm64@0.25.12": { "@esbuild/darwin-arm64@0.27.2": {
"integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", "integrity": "sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==",
"os": ["darwin"], "os": ["darwin"],
"cpu": ["arm64"] "cpu": ["arm64"]
}, },
"@esbuild/darwin-x64@0.25.12": { "@esbuild/darwin-x64@0.27.2": {
"integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", "integrity": "sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==",
"os": ["darwin"], "os": ["darwin"],
"cpu": ["x64"] "cpu": ["x64"]
}, },
"@esbuild/freebsd-arm64@0.25.12": { "@esbuild/freebsd-arm64@0.27.2": {
"integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", "integrity": "sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==",
"os": ["freebsd"], "os": ["freebsd"],
"cpu": ["arm64"] "cpu": ["arm64"]
}, },
"@esbuild/freebsd-x64@0.25.12": { "@esbuild/freebsd-x64@0.27.2": {
"integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", "integrity": "sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==",
"os": ["freebsd"], "os": ["freebsd"],
"cpu": ["x64"] "cpu": ["x64"]
}, },
"@esbuild/linux-arm64@0.25.12": { "@esbuild/linux-arm64@0.27.2": {
"integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", "integrity": "sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==",
"os": ["linux"], "os": ["linux"],
"cpu": ["arm64"] "cpu": ["arm64"]
}, },
"@esbuild/linux-arm@0.25.12": { "@esbuild/linux-arm@0.27.2": {
"integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", "integrity": "sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==",
"os": ["linux"], "os": ["linux"],
"cpu": ["arm"] "cpu": ["arm"]
}, },
"@esbuild/linux-ia32@0.25.12": { "@esbuild/linux-ia32@0.27.2": {
"integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", "integrity": "sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==",
"os": ["linux"], "os": ["linux"],
"cpu": ["ia32"] "cpu": ["ia32"]
}, },
"@esbuild/linux-loong64@0.25.12": { "@esbuild/linux-loong64@0.27.2": {
"integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", "integrity": "sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==",
"os": ["linux"], "os": ["linux"],
"cpu": ["loong64"] "cpu": ["loong64"]
}, },
"@esbuild/linux-mips64el@0.25.12": { "@esbuild/linux-mips64el@0.27.2": {
"integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", "integrity": "sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==",
"os": ["linux"], "os": ["linux"],
"cpu": ["mips64el"] "cpu": ["mips64el"]
}, },
"@esbuild/linux-ppc64@0.25.12": { "@esbuild/linux-ppc64@0.27.2": {
"integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", "integrity": "sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==",
"os": ["linux"], "os": ["linux"],
"cpu": ["ppc64"] "cpu": ["ppc64"]
}, },
"@esbuild/linux-riscv64@0.25.12": { "@esbuild/linux-riscv64@0.27.2": {
"integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", "integrity": "sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==",
"os": ["linux"], "os": ["linux"],
"cpu": ["riscv64"] "cpu": ["riscv64"]
}, },
"@esbuild/linux-s390x@0.25.12": { "@esbuild/linux-s390x@0.27.2": {
"integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", "integrity": "sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==",
"os": ["linux"], "os": ["linux"],
"cpu": ["s390x"] "cpu": ["s390x"]
}, },
"@esbuild/linux-x64@0.25.12": { "@esbuild/linux-x64@0.27.2": {
"integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", "integrity": "sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==",
"os": ["linux"], "os": ["linux"],
"cpu": ["x64"] "cpu": ["x64"]
}, },
"@esbuild/netbsd-arm64@0.25.12": { "@esbuild/netbsd-arm64@0.27.2": {
"integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", "integrity": "sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==",
"os": ["netbsd"], "os": ["netbsd"],
"cpu": ["arm64"] "cpu": ["arm64"]
}, },
"@esbuild/netbsd-x64@0.25.12": { "@esbuild/netbsd-x64@0.27.2": {
"integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", "integrity": "sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==",
"os": ["netbsd"], "os": ["netbsd"],
"cpu": ["x64"] "cpu": ["x64"]
}, },
"@esbuild/openbsd-arm64@0.25.12": { "@esbuild/openbsd-arm64@0.27.2": {
"integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", "integrity": "sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==",
"os": ["openbsd"], "os": ["openbsd"],
"cpu": ["arm64"] "cpu": ["arm64"]
}, },
"@esbuild/openbsd-x64@0.25.12": { "@esbuild/openbsd-x64@0.27.2": {
"integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", "integrity": "sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==",
"os": ["openbsd"], "os": ["openbsd"],
"cpu": ["x64"] "cpu": ["x64"]
}, },
"@esbuild/openharmony-arm64@0.25.12": { "@esbuild/openharmony-arm64@0.27.2": {
"integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", "integrity": "sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==",
"os": ["openharmony"], "os": ["openharmony"],
"cpu": ["arm64"] "cpu": ["arm64"]
}, },
"@esbuild/sunos-x64@0.25.12": { "@esbuild/sunos-x64@0.27.2": {
"integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", "integrity": "sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==",
"os": ["sunos"], "os": ["sunos"],
"cpu": ["x64"] "cpu": ["x64"]
}, },
"@esbuild/win32-arm64@0.25.12": { "@esbuild/win32-arm64@0.27.2": {
"integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", "integrity": "sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==",
"os": ["win32"], "os": ["win32"],
"cpu": ["arm64"] "cpu": ["arm64"]
}, },
"@esbuild/win32-ia32@0.25.12": { "@esbuild/win32-ia32@0.27.2": {
"integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", "integrity": "sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==",
"os": ["win32"], "os": ["win32"],
"cpu": ["ia32"] "cpu": ["ia32"]
}, },
"@esbuild/win32-x64@0.25.12": { "@esbuild/win32-x64@0.27.2": {
"integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", "integrity": "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==",
"os": ["win32"], "os": ["win32"],
"cpu": ["x64"] "cpu": ["x64"]
}, },
"@eslint-community/eslint-utils@4.9.0_eslint@9.39.1": { "@eslint-community/eslint-utils@4.9.1_eslint@9.39.2": {
"integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==",
"dependencies": [ "dependencies": [
"eslint", "eslint",
"eslint-visitor-keys@3.4.3" "eslint-visitor-keys@3.4.3"
@ -164,7 +164,7 @@
"@eslint-community/regexpp@4.12.2": { "@eslint-community/regexpp@4.12.2": {
"integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==" "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew=="
}, },
"@eslint/compat@1.4.1_eslint@9.39.1": { "@eslint/compat@1.4.1_eslint@9.39.2": {
"integrity": "sha512-cfO82V9zxxGBxcQDr1lfaYB7wykTa0b00mGa36FrJl7iTFd0Z2cHfEYuxcBRP/iNijCsWsEkA+jzT8hGYmv33w==", "integrity": "sha512-cfO82V9zxxGBxcQDr1lfaYB7wykTa0b00mGa36FrJl7iTFd0Z2cHfEYuxcBRP/iNijCsWsEkA+jzT8hGYmv33w==",
"dependencies": [ "dependencies": [
"@eslint/core", "@eslint/core",
@ -194,8 +194,8 @@
"@types/json-schema" "@types/json-schema"
] ]
}, },
"@eslint/eslintrc@3.3.1": { "@eslint/eslintrc@3.3.3": {
"integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", "integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==",
"dependencies": [ "dependencies": [
"ajv", "ajv",
"debug", "debug",
@ -208,8 +208,8 @@
"strip-json-comments" "strip-json-comments"
] ]
}, },
"@eslint/js@9.39.1": { "@eslint/js@9.39.2": {
"integrity": "sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw==" "integrity": "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA=="
}, },
"@eslint/object-schema@2.1.7": { "@eslint/object-schema@2.1.7": {
"integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==" "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA=="
@ -438,7 +438,7 @@
"acorn" "acorn"
] ]
}, },
"@sveltejs/adapter-node@5.4.0_@sveltejs+kit@2.49.0__@sveltejs+vite-plugin-svelte@6.2.1___svelte@5.44.1____acorn@8.15.0___vite@7.2.4____@types+node@22.19.1____picomatch@4.0.3___@types+node@22.19.1__svelte@5.44.1___acorn@8.15.0__vite@7.2.4___@types+node@22.19.1___picomatch@4.0.3__acorn@8.15.0__@types+node@22.19.1_rollup@4.53.3_@sveltejs+vite-plugin-svelte@6.2.1__svelte@5.44.1___acorn@8.15.0__vite@7.2.4___@types+node@22.19.1___picomatch@4.0.3__@types+node@22.19.1_svelte@5.44.1__acorn@8.15.0_vite@7.2.4__@types+node@22.19.1__picomatch@4.0.3_@types+node@22.19.1": { "@sveltejs/adapter-node@5.4.0_@sveltejs+kit@2.49.3__@sveltejs+vite-plugin-svelte@6.2.2___svelte@5.46.1____acorn@8.15.0___vite@7.3.0____@types+node@22.19.3____picomatch@4.0.3___@types+node@22.19.3__svelte@5.46.1___acorn@8.15.0__typescript@5.9.3__vite@7.3.0___@types+node@22.19.3___picomatch@4.0.3__acorn@8.15.0__@types+node@22.19.3_rollup@4.53.3_@sveltejs+vite-plugin-svelte@6.2.2__svelte@5.46.1___acorn@8.15.0__vite@7.3.0___@types+node@22.19.3___picomatch@4.0.3__@types+node@22.19.3_svelte@5.46.1__acorn@8.15.0_typescript@5.9.3_vite@7.3.0__@types+node@22.19.3__picomatch@4.0.3_@types+node@22.19.3": {
"integrity": "sha512-NMsrwGVPEn+J73zH83Uhss/hYYZN6zT3u31R3IHAn3MiKC3h8fjmIAhLfTSOeNHr5wPYfjjMg8E+1gyFgyrEcQ==", "integrity": "sha512-NMsrwGVPEn+J73zH83Uhss/hYYZN6zT3u31R3IHAn3MiKC3h8fjmIAhLfTSOeNHr5wPYfjjMg8E+1gyFgyrEcQ==",
"dependencies": [ "dependencies": [
"@rollup/plugin-commonjs", "@rollup/plugin-commonjs",
@ -448,8 +448,8 @@
"rollup" "rollup"
] ]
}, },
"@sveltejs/kit@2.49.0_@sveltejs+vite-plugin-svelte@6.2.1__svelte@5.44.1___acorn@8.15.0__vite@7.2.4___@types+node@22.19.1___picomatch@4.0.3__@types+node@22.19.1_svelte@5.44.1__acorn@8.15.0_vite@7.2.4__@types+node@22.19.1__picomatch@4.0.3_acorn@8.15.0_@types+node@22.19.1": { "@sveltejs/kit@2.49.3_@sveltejs+vite-plugin-svelte@6.2.2__svelte@5.46.1___acorn@8.15.0__vite@7.3.0___@types+node@22.19.3___picomatch@4.0.3__@types+node@22.19.3_svelte@5.46.1__acorn@8.15.0_typescript@5.9.3_vite@7.3.0__@types+node@22.19.3__picomatch@4.0.3_acorn@8.15.0_@types+node@22.19.3": {
"integrity": "sha512-oH8tXw7EZnie8FdOWYrF7Yn4IKrqTFHhXvl8YxXxbKwTMcD/5NNCryUSEXRk2ZR4ojnub0P8rNrsVGHXWqIDtA==", "integrity": "sha512-luTmE2Isk9GRJnitqanLoByKBiyLdfLpV2qV9a25JMxjbQt919TVqG8pibJDkxTvX9+w2k/9IL7o+/RtG++3QA==",
"dependencies": [ "dependencies": [
"@standard-schema/spec", "@standard-schema/spec",
"@sveltejs/acorn-typescript", "@sveltejs/acorn-typescript",
@ -466,11 +466,15 @@
"set-cookie-parser", "set-cookie-parser",
"sirv", "sirv",
"svelte", "svelte",
"typescript",
"vite" "vite"
], ],
"optionalPeers": [
"typescript"
],
"bin": true "bin": true
}, },
"@sveltejs/vite-plugin-svelte-inspector@5.0.1_@sveltejs+vite-plugin-svelte@6.2.1__svelte@5.44.1___acorn@8.15.0__vite@7.2.4___@types+node@22.19.1___picomatch@4.0.3__@types+node@22.19.1_svelte@5.44.1__acorn@8.15.0_vite@7.2.4__@types+node@22.19.1__picomatch@4.0.3_@types+node@22.19.1": { "@sveltejs/vite-plugin-svelte-inspector@5.0.1_@sveltejs+vite-plugin-svelte@6.2.2__svelte@5.46.1___acorn@8.15.0__vite@7.3.0___@types+node@22.19.3___picomatch@4.0.3__@types+node@22.19.3_svelte@5.46.1__acorn@8.15.0_vite@7.3.0__@types+node@22.19.3__picomatch@4.0.3_@types+node@22.19.3": {
"integrity": "sha512-ubWshlMk4bc8mkwWbg6vNvCeT7lGQojE3ijDh3QTR6Zr/R+GXxsGbyH4PExEPpiFmqPhYiVSVmHBjUcVc1JIrA==", "integrity": "sha512-ubWshlMk4bc8mkwWbg6vNvCeT7lGQojE3ijDh3QTR6Zr/R+GXxsGbyH4PExEPpiFmqPhYiVSVmHBjUcVc1JIrA==",
"dependencies": [ "dependencies": [
"@sveltejs/vite-plugin-svelte", "@sveltejs/vite-plugin-svelte",
@ -479,27 +483,27 @@
"vite" "vite"
] ]
}, },
"@sveltejs/vite-plugin-svelte@6.2.1_svelte@5.44.1__acorn@8.15.0_vite@7.2.4__@types+node@22.19.1__picomatch@4.0.3_@types+node@22.19.1": { "@sveltejs/vite-plugin-svelte@6.2.2_svelte@5.46.1__acorn@8.15.0_vite@7.3.0__@types+node@22.19.3__picomatch@4.0.3_@types+node@22.19.3": {
"integrity": "sha512-YZs/OSKOQAQCnJvM/P+F1URotNnYNeU3P2s4oIpzm1uFaqUEqRxUB0g5ejMjEb5Gjb9/PiBI5Ktrq4rUUF8UVQ==", "integrity": "sha512-9P/0sA/+lWxvRmJFGmVVoVQFeCIktv9bNju1Gc8h1Ptf/UeWCfVgpSy0CDdozVpQWfTvBZblttjrvo6ICxujdg==",
"dependencies": [ "dependencies": [
"@sveltejs/vite-plugin-svelte-inspector", "@sveltejs/vite-plugin-svelte-inspector",
"debug",
"deepmerge", "deepmerge",
"magic-string", "magic-string",
"obug",
"svelte", "svelte",
"vite", "vite",
"vitefu" "vitefu"
] ]
}, },
"@tailwindcss/forms@0.5.10_tailwindcss@4.1.17": { "@tailwindcss/forms@0.5.11_tailwindcss@4.1.18": {
"integrity": "sha512-utI1ONF6uf/pPNO68kmN1b8rEwNXv3czukalo8VtJH8ksIkZXr3Q3VYudZLkCsDd4Wku120uF02hYK25XGPorw==", "integrity": "sha512-h9wegbZDPurxG22xZSoWtdzc41/OlNEUQERNqI/0fOwa2aVlWGu7C35E/x6LDyD3lgtztFSSjKZyuVM0hxhbgA==",
"dependencies": [ "dependencies": [
"mini-svg-data-uri", "mini-svg-data-uri",
"tailwindcss" "tailwindcss"
] ]
}, },
"@tailwindcss/node@4.1.17": { "@tailwindcss/node@4.1.18": {
"integrity": "sha512-csIkHIgLb3JisEFQ0vxr2Y57GUNYh447C8xzwj89U/8fdW8LhProdxvnVH6U8M2Y73QKiTIH+LWbK3V2BBZsAg==", "integrity": "sha512-DoR7U1P7iYhw16qJ49fgXUlry1t4CpXeErJHnQ44JgTSKMaZUdf17cfn5mHchfJ4KRBZRFA/Coo+MUF5+gOaCQ==",
"dependencies": [ "dependencies": [
"@jridgewell/remapping", "@jridgewell/remapping",
"enhanced-resolve", "enhanced-resolve",
@ -510,67 +514,67 @@
"tailwindcss" "tailwindcss"
] ]
}, },
"@tailwindcss/oxide-android-arm64@4.1.17": { "@tailwindcss/oxide-android-arm64@4.1.18": {
"integrity": "sha512-BMqpkJHgOZ5z78qqiGE6ZIRExyaHyuxjgrJ6eBO5+hfrfGkuya0lYfw8fRHG77gdTjWkNWEEm+qeG2cDMxArLQ==", "integrity": "sha512-dJHz7+Ugr9U/diKJA0W6N/6/cjI+ZTAoxPf9Iz9BFRF2GzEX8IvXxFIi/dZBloVJX/MZGvRuFA9rqwdiIEZQ0Q==",
"os": ["android"], "os": ["android"],
"cpu": ["arm64"] "cpu": ["arm64"]
}, },
"@tailwindcss/oxide-darwin-arm64@4.1.17": { "@tailwindcss/oxide-darwin-arm64@4.1.18": {
"integrity": "sha512-EquyumkQweUBNk1zGEU/wfZo2qkp/nQKRZM8bUYO0J+Lums5+wl2CcG1f9BgAjn/u9pJzdYddHWBiFXJTcxmOg==", "integrity": "sha512-Gc2q4Qhs660bhjyBSKgq6BYvwDz4G+BuyJ5H1xfhmDR3D8HnHCmT/BSkvSL0vQLy/nkMLY20PQ2OoYMO15Jd0A==",
"os": ["darwin"], "os": ["darwin"],
"cpu": ["arm64"] "cpu": ["arm64"]
}, },
"@tailwindcss/oxide-darwin-x64@4.1.17": { "@tailwindcss/oxide-darwin-x64@4.1.18": {
"integrity": "sha512-gdhEPLzke2Pog8s12oADwYu0IAw04Y2tlmgVzIN0+046ytcgx8uZmCzEg4VcQh+AHKiS7xaL8kGo/QTiNEGRog==", "integrity": "sha512-FL5oxr2xQsFrc3X9o1fjHKBYBMD1QZNyc1Xzw/h5Qu4XnEBi3dZn96HcHm41c/euGV+GRiXFfh2hUCyKi/e+yw==",
"os": ["darwin"], "os": ["darwin"],
"cpu": ["x64"] "cpu": ["x64"]
}, },
"@tailwindcss/oxide-freebsd-x64@4.1.17": { "@tailwindcss/oxide-freebsd-x64@4.1.18": {
"integrity": "sha512-hxGS81KskMxML9DXsaXT1H0DyA+ZBIbyG/sSAjWNe2EDl7TkPOBI42GBV3u38itzGUOmFfCzk1iAjDXds8Oh0g==", "integrity": "sha512-Fj+RHgu5bDodmV1dM9yAxlfJwkkWvLiRjbhuO2LEtwtlYlBgiAT4x/j5wQr1tC3SANAgD+0YcmWVrj8R9trVMA==",
"os": ["freebsd"], "os": ["freebsd"],
"cpu": ["x64"] "cpu": ["x64"]
}, },
"@tailwindcss/oxide-linux-arm-gnueabihf@4.1.17": { "@tailwindcss/oxide-linux-arm-gnueabihf@4.1.18": {
"integrity": "sha512-k7jWk5E3ldAdw0cNglhjSgv501u7yrMf8oeZ0cElhxU6Y2o7f8yqelOp3fhf7evjIS6ujTI3U8pKUXV2I4iXHQ==", "integrity": "sha512-Fp+Wzk/Ws4dZn+LV2Nqx3IilnhH51YZoRaYHQsVq3RQvEl+71VGKFpkfHrLM/Li+kt5c0DJe/bHXK1eHgDmdiA==",
"os": ["linux"], "os": ["linux"],
"cpu": ["arm"] "cpu": ["arm"]
}, },
"@tailwindcss/oxide-linux-arm64-gnu@4.1.17": { "@tailwindcss/oxide-linux-arm64-gnu@4.1.18": {
"integrity": "sha512-HVDOm/mxK6+TbARwdW17WrgDYEGzmoYayrCgmLEw7FxTPLcp/glBisuyWkFz/jb7ZfiAXAXUACfyItn+nTgsdQ==", "integrity": "sha512-S0n3jboLysNbh55Vrt7pk9wgpyTTPD0fdQeh7wQfMqLPM/Hrxi+dVsLsPrycQjGKEQk85Kgbx+6+QnYNiHalnw==",
"os": ["linux"], "os": ["linux"],
"cpu": ["arm64"] "cpu": ["arm64"]
}, },
"@tailwindcss/oxide-linux-arm64-musl@4.1.17": { "@tailwindcss/oxide-linux-arm64-musl@4.1.18": {
"integrity": "sha512-HvZLfGr42i5anKtIeQzxdkw/wPqIbpeZqe7vd3V9vI3RQxe3xU1fLjss0TjyhxWcBaipk7NYwSrwTwK1hJARMg==", "integrity": "sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg==",
"os": ["linux"], "os": ["linux"],
"cpu": ["arm64"] "cpu": ["arm64"]
}, },
"@tailwindcss/oxide-linux-x64-gnu@4.1.17": { "@tailwindcss/oxide-linux-x64-gnu@4.1.18": {
"integrity": "sha512-M3XZuORCGB7VPOEDH+nzpJ21XPvK5PyjlkSFkFziNHGLc5d6g3di2McAAblmaSUNl8IOmzYwLx9NsE7bplNkwQ==", "integrity": "sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g==",
"os": ["linux"], "os": ["linux"],
"cpu": ["x64"] "cpu": ["x64"]
}, },
"@tailwindcss/oxide-linux-x64-musl@4.1.17": { "@tailwindcss/oxide-linux-x64-musl@4.1.18": {
"integrity": "sha512-k7f+pf9eXLEey4pBlw+8dgfJHY4PZ5qOUFDyNf7SI6lHjQ9Zt7+NcscjpwdCEbYi6FI5c2KDTDWyf2iHcCSyyQ==", "integrity": "sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ==",
"os": ["linux"], "os": ["linux"],
"cpu": ["x64"] "cpu": ["x64"]
}, },
"@tailwindcss/oxide-wasm32-wasi@4.1.17": { "@tailwindcss/oxide-wasm32-wasi@4.1.18": {
"integrity": "sha512-cEytGqSSoy7zK4JRWiTCx43FsKP/zGr0CsuMawhH67ONlH+T79VteQeJQRO/X7L0juEUA8ZyuYikcRBf0vsxhg==", "integrity": "sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA==",
"cpu": ["wasm32"] "cpu": ["wasm32"]
}, },
"@tailwindcss/oxide-win32-arm64-msvc@4.1.17": { "@tailwindcss/oxide-win32-arm64-msvc@4.1.18": {
"integrity": "sha512-JU5AHr7gKbZlOGvMdb4722/0aYbU+tN6lv1kONx0JK2cGsh7g148zVWLM0IKR3NeKLv+L90chBVYcJ8uJWbC9A==", "integrity": "sha512-HjSA7mr9HmC8fu6bdsZvZ+dhjyGCLdotjVOgLA2vEqxEBZaQo9YTX4kwgEvPCpRh8o4uWc4J/wEoFzhEmjvPbA==",
"os": ["win32"], "os": ["win32"],
"cpu": ["arm64"] "cpu": ["arm64"]
}, },
"@tailwindcss/oxide-win32-x64-msvc@4.1.17": { "@tailwindcss/oxide-win32-x64-msvc@4.1.18": {
"integrity": "sha512-SKWM4waLuqx0IH+FMDUw6R66Hu4OuTALFgnleKbqhgGU30DY20NORZMZUKgLRjQXNN2TLzKvh48QXTig4h4bGw==", "integrity": "sha512-bJWbyYpUlqamC8dpR7pfjA0I7vdF6t5VpUGMWRkXVE3AXgIZjYUYAK7II1GNaxR8J1SSrSrppRar8G++JekE3Q==",
"os": ["win32"], "os": ["win32"],
"cpu": ["x64"] "cpu": ["x64"]
}, },
"@tailwindcss/oxide@4.1.17": { "@tailwindcss/oxide@4.1.18": {
"integrity": "sha512-F0F7d01fmkQhsTjXezGBLdrl1KresJTcI3DB8EkScCldyKp3Msz4hub4uyYaVnk88BAS1g5DQjjF6F5qczheLA==", "integrity": "sha512-EgCR5tTS5bUSKQgzeMClT6iCY3ToqE1y+ZB0AKldj809QXk1Y+3jB0upOYZrn9aGIzPtUsP7sX4QQ4XtjBB95A==",
"optionalDependencies": [ "optionalDependencies": [
"@tailwindcss/oxide-android-arm64", "@tailwindcss/oxide-android-arm64",
"@tailwindcss/oxide-darwin-arm64", "@tailwindcss/oxide-darwin-arm64",
@ -586,15 +590,15 @@
"@tailwindcss/oxide-win32-x64-msvc" "@tailwindcss/oxide-win32-x64-msvc"
] ]
}, },
"@tailwindcss/typography@0.5.19_tailwindcss@4.1.17": { "@tailwindcss/typography@0.5.19_tailwindcss@4.1.18": {
"integrity": "sha512-w31dd8HOx3k9vPtcQh5QHP9GwKcgbMp87j58qi6xgiBnFFtKEAgCWnDw4qUT8aHwkCp8bKvb/KGKWWHedP0AAg==", "integrity": "sha512-w31dd8HOx3k9vPtcQh5QHP9GwKcgbMp87j58qi6xgiBnFFtKEAgCWnDw4qUT8aHwkCp8bKvb/KGKWWHedP0AAg==",
"dependencies": [ "dependencies": [
"postcss-selector-parser@6.0.10", "postcss-selector-parser@6.0.10",
"tailwindcss" "tailwindcss"
] ]
}, },
"@tailwindcss/vite@4.1.17_vite@7.2.4__@types+node@22.19.1__picomatch@4.0.3_@types+node@22.19.1": { "@tailwindcss/vite@4.1.18_vite@7.3.0__@types+node@22.19.3__picomatch@4.0.3_@types+node@22.19.3": {
"integrity": "sha512-4+9w8ZHOiGnpcGI6z1TVVfWaX/koK7fKeSYF3qlYg2xpBtbteP2ddBxiarL+HVgfSJGeK5RIxRQmKm4rTJJAwA==", "integrity": "sha512-jVA+/UpKL1vRLg6Hkao5jldawNmRo7mQYrZtNHMIVpLfLhDml5nMRUo/8MwoX2vNXvnaXNNMedrMfMugAVX1nA==",
"dependencies": [ "dependencies": [
"@tailwindcss/node", "@tailwindcss/node",
"@tailwindcss/oxide", "@tailwindcss/oxide",
@ -611,8 +615,8 @@
"@types/json-schema@7.0.15": { "@types/json-schema@7.0.15": {
"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="
}, },
"@types/node@22.19.1": { "@types/node@22.19.3": {
"integrity": "sha512-LCCV0HdSZZZb34qifBsyWlUmok6W7ouER+oQIGBScS8EsZsQbrtFTUrDX4hOl+CS6p7cnNC4td+qrSVGSCTUfQ==", "integrity": "sha512-1N9SBnWYOJTrNZCdh/yJE+t910Y128BoyY+zBLWhL3r0TYzlTmFdXrPwHL9DyFZmlEXNQQolTZh3KHV31QDhyA==",
"dependencies": [ "dependencies": [
"undici-types" "undici-types"
] ]
@ -620,8 +624,8 @@
"@types/resolve@1.20.2": { "@types/resolve@1.20.2": {
"integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==" "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q=="
}, },
"@typescript-eslint/eslint-plugin@8.48.0_@typescript-eslint+parser@8.48.0__eslint@9.39.1__typescript@5.9.3_eslint@9.39.1_typescript@5.9.3": { "@typescript-eslint/eslint-plugin@8.52.0_@typescript-eslint+parser@8.52.0__eslint@9.39.2__typescript@5.9.3_eslint@9.39.2_typescript@5.9.3": {
"integrity": "sha512-XxXP5tL1txl13YFtrECECQYeZjBZad4fyd3cFV4a19LkAY/bIp9fev3US4S5fDVV2JaYFiKAZ/GRTOLer+mbyQ==", "integrity": "sha512-okqtOgqu2qmZJ5iN4TWlgfF171dZmx2FzdOv2K/ixL2LZWDStL8+JgQerI2sa8eAEfoydG9+0V96m7V+P8yE1Q==",
"dependencies": [ "dependencies": [
"@eslint-community/regexpp", "@eslint-community/regexpp",
"@typescript-eslint/parser", "@typescript-eslint/parser",
@ -630,15 +634,14 @@
"@typescript-eslint/utils", "@typescript-eslint/utils",
"@typescript-eslint/visitor-keys", "@typescript-eslint/visitor-keys",
"eslint", "eslint",
"graphemer",
"ignore@7.0.5", "ignore@7.0.5",
"natural-compare", "natural-compare",
"ts-api-utils", "ts-api-utils",
"typescript" "typescript"
] ]
}, },
"@typescript-eslint/parser@8.48.0_eslint@9.39.1_typescript@5.9.3": { "@typescript-eslint/parser@8.52.0_eslint@9.39.2_typescript@5.9.3": {
"integrity": "sha512-jCzKdm/QK0Kg4V4IK/oMlRZlY+QOcdjv89U2NgKHZk1CYTj82/RVSx1mV/0gqCVMJ/DA+Zf/S4NBWNF8GQ+eqQ==", "integrity": "sha512-iIACsx8pxRnguSYhHiMn2PvhvfpopO9FXHyn1mG5txZIsAaB6F0KwbFnUQN3KCiG3Jcuad/Cao2FAs1Wp7vAyg==",
"dependencies": [ "dependencies": [
"@typescript-eslint/scope-manager", "@typescript-eslint/scope-manager",
"@typescript-eslint/types", "@typescript-eslint/types",
@ -649,8 +652,8 @@
"typescript" "typescript"
] ]
}, },
"@typescript-eslint/project-service@8.48.0_typescript@5.9.3": { "@typescript-eslint/project-service@8.52.0_typescript@5.9.3": {
"integrity": "sha512-Ne4CTZyRh1BecBf84siv42wv5vQvVmgtk8AuiEffKTUo3DrBaGYZueJSxxBZ8fjk/N3DrgChH4TOdIOwOwiqqw==", "integrity": "sha512-xD0MfdSdEmeFa3OmVqonHi+Cciab96ls1UhIF/qX/O/gPu5KXD0bY9lu33jj04fjzrXHcuvjBcBC+D3SNSadaw==",
"dependencies": [ "dependencies": [
"@typescript-eslint/tsconfig-utils", "@typescript-eslint/tsconfig-utils",
"@typescript-eslint/types", "@typescript-eslint/types",
@ -658,21 +661,21 @@
"typescript" "typescript"
] ]
}, },
"@typescript-eslint/scope-manager@8.48.0": { "@typescript-eslint/scope-manager@8.52.0": {
"integrity": "sha512-uGSSsbrtJrLduti0Q1Q9+BF1/iFKaxGoQwjWOIVNJv0o6omrdyR8ct37m4xIl5Zzpkp69Kkmvom7QFTtue89YQ==", "integrity": "sha512-ixxqmmCcc1Nf8S0mS0TkJ/3LKcC8mruYJPOU6Ia2F/zUUR4pApW7LzrpU3JmtePbRUTes9bEqRc1Gg4iyRnDzA==",
"dependencies": [ "dependencies": [
"@typescript-eslint/types", "@typescript-eslint/types",
"@typescript-eslint/visitor-keys" "@typescript-eslint/visitor-keys"
] ]
}, },
"@typescript-eslint/tsconfig-utils@8.48.0_typescript@5.9.3": { "@typescript-eslint/tsconfig-utils@8.52.0_typescript@5.9.3": {
"integrity": "sha512-WNebjBdFdyu10sR1M4OXTt2OkMd5KWIL+LLfeH9KhgP+jzfDV/LI3eXzwJ1s9+Yc0Kzo2fQCdY/OpdusCMmh6w==", "integrity": "sha512-jl+8fzr/SdzdxWJznq5nvoI7qn2tNYV/ZBAEcaFMVXf+K6jmXvAFrgo/+5rxgnL152f//pDEAYAhhBAZGrVfwg==",
"dependencies": [ "dependencies": [
"typescript" "typescript"
] ]
}, },
"@typescript-eslint/type-utils@8.48.0_eslint@9.39.1_typescript@5.9.3": { "@typescript-eslint/type-utils@8.52.0_eslint@9.39.2_typescript@5.9.3": {
"integrity": "sha512-zbeVaVqeXhhab6QNEKfK96Xyc7UQuoFWERhEnj3mLVnUWrQnv15cJNseUni7f3g557gm0e46LZ6IJ4NJVOgOpw==", "integrity": "sha512-JD3wKBRWglYRQkAtsyGz1AewDu3mTc7NtRjR/ceTyGoPqmdS5oCdx/oZMWD5Zuqmo6/MpsYs0wp6axNt88/2EQ==",
"dependencies": [ "dependencies": [
"@typescript-eslint/types", "@typescript-eslint/types",
"@typescript-eslint/typescript-estree", "@typescript-eslint/typescript-estree",
@ -683,11 +686,11 @@
"typescript" "typescript"
] ]
}, },
"@typescript-eslint/types@8.48.0": { "@typescript-eslint/types@8.52.0": {
"integrity": "sha512-cQMcGQQH7kwKoVswD1xdOytxQR60MWKM1di26xSUtxehaDs/32Zpqsu5WJlXTtTTqyAVK8R7hvsUnIXRS+bjvA==" "integrity": "sha512-LWQV1V4q9V4cT4H5JCIx3481iIFxH1UkVk+ZkGGAV1ZGcjGI9IoFOfg3O6ywz8QqCDEp7Inlg6kovMofsNRaGg=="
}, },
"@typescript-eslint/typescript-estree@8.48.0_typescript@5.9.3": { "@typescript-eslint/typescript-estree@8.52.0_typescript@5.9.3": {
"integrity": "sha512-ljHab1CSO4rGrQIAyizUS6UGHHCiAYhbfcIZ1zVJr5nMryxlXMVWS3duFPSKvSUbFPwkXMFk1k0EMIjub4sRRQ==", "integrity": "sha512-XP3LClsCc0FsTK5/frGjolyADTh3QmsLp6nKd476xNI9CsSsLnmn4f0jrzNoAulmxlmNIpeXuHYeEQv61Q6qeQ==",
"dependencies": [ "dependencies": [
"@typescript-eslint/project-service", "@typescript-eslint/project-service",
"@typescript-eslint/tsconfig-utils", "@typescript-eslint/tsconfig-utils",
@ -701,8 +704,8 @@
"typescript" "typescript"
] ]
}, },
"@typescript-eslint/utils@8.48.0_eslint@9.39.1_typescript@5.9.3": { "@typescript-eslint/utils@8.52.0_eslint@9.39.2_typescript@5.9.3": {
"integrity": "sha512-yTJO1XuGxCsSfIVt1+1UrLHtue8xz16V8apzPYI06W0HbEbEWHxHXgZaAgavIkoh+GeV6hKKd5jm0sS6OYxWXQ==", "integrity": "sha512-wYndVMWkweqHpEpwPhwqE2lnD2DxC6WVLupU/DOt/0/v+/+iQbbzO3jOHjmBMnhu0DgLULvOaU4h4pwHYi2oRQ==",
"dependencies": [ "dependencies": [
"@eslint-community/eslint-utils", "@eslint-community/eslint-utils",
"@typescript-eslint/scope-manager", "@typescript-eslint/scope-manager",
@ -712,8 +715,8 @@
"typescript" "typescript"
] ]
}, },
"@typescript-eslint/visitor-keys@8.48.0": { "@typescript-eslint/visitor-keys@8.52.0": {
"integrity": "sha512-T0XJMaRPOH3+LBbAfzR2jalckP1MSG/L9eUtY0DEzUyVaXJ/t6zN0nR7co5kz0Jko/nkSYCBRkz1djvjajVTTg==", "integrity": "sha512-ink3/Zofus34nmBsPjow63FP5M7IGff0RKAgqR6+CFpdk22M7aLwC9gOcLGYqr7MczLPzZVERW9hRog3O4n1sQ==",
"dependencies": [ "dependencies": [
"@typescript-eslint/types", "@typescript-eslint/types",
"eslint-visitor-keys@4.2.1" "eslint-visitor-keys@4.2.1"
@ -818,8 +821,8 @@
"integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
"bin": true "bin": true
}, },
"daisyui@5.5.5": { "daisyui@5.5.14": {
"integrity": "sha512-ekvI93ZkWIJoCOtDl0D2QMxnWvTejk9V5nWBqRv+7t0xjiBXqAK5U6o6JE2RPvlIC3EqwNyUoIZSdHX9MZK3nw==" "integrity": "sha512-L47rvw7I7hK68TA97VB8Ee0woHew+/ohR6Lx6Ah/krfISOqcG4My7poNpX5Mo5/ytMxiR40fEaz6njzDi7cuSg=="
}, },
"debug@4.4.3": { "debug@4.4.3": {
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
@ -839,15 +842,15 @@
"devalue@5.5.0": { "devalue@5.5.0": {
"integrity": "sha512-69sM5yrHfFLJt0AZ9QqZXGCPfJ7fQjvpln3Rq5+PS03LD32Ost1Q9N+eEnaQwGRIriKkMImXD56ocjQmfjbV3w==" "integrity": "sha512-69sM5yrHfFLJt0AZ9QqZXGCPfJ7fQjvpln3Rq5+PS03LD32Ost1Q9N+eEnaQwGRIriKkMImXD56ocjQmfjbV3w=="
}, },
"enhanced-resolve@5.18.3": { "enhanced-resolve@5.18.4": {
"integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==", "integrity": "sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==",
"dependencies": [ "dependencies": [
"graceful-fs", "graceful-fs",
"tapable" "tapable"
] ]
}, },
"esbuild@0.25.12": { "esbuild@0.27.2": {
"integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", "integrity": "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==",
"optionalDependencies": [ "optionalDependencies": [
"@esbuild/aix-ppc64", "@esbuild/aix-ppc64",
"@esbuild/android-arm", "@esbuild/android-arm",
@ -882,8 +885,8 @@
"escape-string-regexp@4.0.0": { "escape-string-regexp@4.0.0": {
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="
}, },
"eslint-plugin-svelte@3.13.0_eslint@9.39.1_svelte@5.44.1__acorn@8.15.0_postcss@8.5.6": { "eslint-plugin-svelte@3.13.1_eslint@9.39.2_svelte@5.46.1__acorn@8.15.0_postcss@8.5.6": {
"integrity": "sha512-2ohCCQJJTNbIpQCSDSTWj+FN0OVfPmSO03lmSNT7ytqMaWF6kpT86LdzDqtm4sh7TVPl/OEWJ/d7R87bXP2Vjg==", "integrity": "sha512-Ng+kV/qGS8P/isbNYVE3sJORtubB+yLEcYICMkUWNaDTb0SwZni/JhAYXh/Dz/q2eThUwWY0VMPZ//KYD1n3eQ==",
"dependencies": [ "dependencies": [
"@eslint-community/eslint-utils", "@eslint-community/eslint-utils",
"@jridgewell/sourcemap-codec", "@jridgewell/sourcemap-codec",
@ -915,8 +918,8 @@
"eslint-visitor-keys@4.2.1": { "eslint-visitor-keys@4.2.1": {
"integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==" "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ=="
}, },
"eslint@9.39.1": { "eslint@9.39.2": {
"integrity": "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==", "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==",
"dependencies": [ "dependencies": [
"@eslint-community/eslint-utils", "@eslint-community/eslint-utils",
"@eslint-community/regexpp", "@eslint-community/regexpp",
@ -966,14 +969,14 @@
"eslint-visitor-keys@4.2.1" "eslint-visitor-keys@4.2.1"
] ]
}, },
"esquery@1.6.0": { "esquery@1.7.0": {
"integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==",
"dependencies": [ "dependencies": [
"estraverse" "estraverse"
] ]
}, },
"esrap@2.2.0": { "esrap@2.2.1": {
"integrity": "sha512-WBmtxe7R9C5mvL4n2le8nMUe4mD5V9oiK2vJpQ9I3y20ENPUomPcphBXE8D1x/Bm84oN1V+lOfgXxtqmxTp3Xg==", "integrity": "sha512-GiYWG34AN/4CUyaWAgunGt0Rxvr1PTMlGC0vvEov/uOQYWne2bpN03Um+k8jT+q3op33mKouP2zeJ6OlM+qeUg==",
"dependencies": [ "dependencies": [
"@jridgewell/sourcemap-codec" "@jridgewell/sourcemap-codec"
] ]
@ -1057,9 +1060,6 @@
"graceful-fs@4.2.11": { "graceful-fs@4.2.11": {
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="
}, },
"graphemer@1.4.0": {
"integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag=="
},
"has-flag@4.0.0": { "has-flag@4.0.0": {
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
}, },
@ -1284,6 +1284,9 @@
"natural-compare@1.4.0": { "natural-compare@1.4.0": {
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="
}, },
"obug@2.1.1": {
"integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ=="
},
"optionator@0.9.4": { "optionator@0.9.4": {
"integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
"dependencies": [ "dependencies": [
@ -1358,8 +1361,8 @@
"util-deprecate" "util-deprecate"
] ]
}, },
"postcss-selector-parser@7.1.0": { "postcss-selector-parser@7.1.1": {
"integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==",
"dependencies": [ "dependencies": [
"cssesc", "cssesc",
"util-deprecate" "util-deprecate"
@ -1376,8 +1379,8 @@
"prelude-ls@1.2.1": { "prelude-ls@1.2.1": {
"integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="
}, },
"prettier-plugin-svelte@3.4.0_prettier@3.7.4_svelte@5.44.1__acorn@8.15.0": { "prettier-plugin-svelte@3.4.1_prettier@3.7.4_svelte@5.46.1__acorn@8.15.0": {
"integrity": "sha512-pn1ra/0mPObzqoIQn/vUTR3ZZI6UuZ0sHqMK5x2jMLGrs53h0sXhkVuDcrlssHwIMk7FYrMjHBPoUSyyEEDlBQ==", "integrity": "sha512-xL49LCloMoZRvSwa6IEdN2GV6cq2IqpYGstYtMT+5wmml1/dClEoI0MZR78MiVPpu6BdQFfN0/y73yO6+br5Pg==",
"dependencies": [ "dependencies": [
"prettier", "prettier",
"svelte" "svelte"
@ -1482,8 +1485,8 @@
"supports-preserve-symlinks-flag@1.0.0": { "supports-preserve-symlinks-flag@1.0.0": {
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="
}, },
"svelte-check@4.3.4_svelte@5.44.1__acorn@8.15.0_typescript@5.9.3": { "svelte-check@4.3.5_svelte@5.46.1__acorn@8.15.0_typescript@5.9.3": {
"integrity": "sha512-DVWvxhBrDsd+0hHWKfjP99lsSXASeOhHJYyuKOFYJcP7ThfSCKgjVarE8XfuMWpS5JV3AlDf+iK1YGGo2TACdw==", "integrity": "sha512-e4VWZETyXaKGhpkxOXP+B/d0Fp/zKViZoJmneZWe/05Y2aqSKj3YN2nLfYPJBQ87WEiY4BQCQ9hWGu9mPT1a1Q==",
"dependencies": [ "dependencies": [
"@jridgewell/trace-mapping", "@jridgewell/trace-mapping",
"chokidar", "chokidar",
@ -1495,23 +1498,23 @@
], ],
"bin": true "bin": true
}, },
"svelte-eslint-parser@1.4.0_svelte@5.44.1__acorn@8.15.0_postcss@8.5.6": { "svelte-eslint-parser@1.4.1_svelte@5.46.1__acorn@8.15.0_postcss@8.5.6": {
"integrity": "sha512-fjPzOfipR5S7gQ/JvI9r2H8y9gMGXO3JtmrylHLLyahEMquXI0lrebcjT+9/hNgDej0H7abTyox5HpHmW1PSWA==", "integrity": "sha512-1eqkfQ93goAhjAXxZiu1SaKI9+0/sxp4JIWQwUpsz7ybehRE5L8dNuz7Iry7K22R47p5/+s9EM+38nHV2OlgXA==",
"dependencies": [ "dependencies": [
"eslint-scope", "eslint-scope",
"eslint-visitor-keys@4.2.1", "eslint-visitor-keys@4.2.1",
"espree", "espree",
"postcss", "postcss",
"postcss-scss", "postcss-scss",
"postcss-selector-parser@7.1.0", "postcss-selector-parser@7.1.1",
"svelte" "svelte"
], ],
"optionalPeers": [ "optionalPeers": [
"svelte" "svelte"
] ]
}, },
"svelte@5.44.1_acorn@8.15.0": { "svelte@5.46.1_acorn@8.15.0": {
"integrity": "sha512-8VnkRXpa6tJ9IqiwKvzZBNnBy9tZg0N63duDz0EJqiozsmBEAZfHiZzWWWAneIN+cAWkK1JkafW1xIbC4YrdBA==", "integrity": "sha512-ynjfCHD3nP2el70kN5Pmg37sSi0EjOm9FgHYQdC4giWG/hzO3AatzXXJJgP305uIhGQxSufJLuYWtkY8uK/8RA==",
"dependencies": [ "dependencies": [
"@jridgewell/remapping", "@jridgewell/remapping",
"@jridgewell/sourcemap-codec", "@jridgewell/sourcemap-codec",
@ -1530,8 +1533,8 @@
"zimmerframe" "zimmerframe"
] ]
}, },
"tailwindcss@4.1.17": { "tailwindcss@4.1.18": {
"integrity": "sha512-j9Ee2YjuQqYT9bbRTfTZht9W/ytp5H+jJpZKiYdP/bpnXARAuELt9ofP0lPnmHjbga7SNQIxdTAXCmtKVYjN+Q==" "integrity": "sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw=="
}, },
"tapable@2.3.0": { "tapable@2.3.0": {
"integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==" "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg=="
@ -1546,8 +1549,8 @@
"totalist@3.0.1": { "totalist@3.0.1": {
"integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==" "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ=="
}, },
"ts-api-utils@2.1.0_typescript@5.9.3": { "ts-api-utils@2.4.0_typescript@5.9.3": {
"integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", "integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==",
"dependencies": [ "dependencies": [
"typescript" "typescript"
] ]
@ -1558,8 +1561,8 @@
"prelude-ls" "prelude-ls"
] ]
}, },
"typescript-eslint@8.48.0_eslint@9.39.1_typescript@5.9.3_@typescript-eslint+parser@8.48.0__eslint@9.39.1__typescript@5.9.3": { "typescript-eslint@8.52.0_eslint@9.39.2_typescript@5.9.3_@typescript-eslint+parser@8.52.0__eslint@9.39.2__typescript@5.9.3": {
"integrity": "sha512-fcKOvQD9GUn3Xw63EgiDqhvWJ5jsyZUaekl3KVpGsDJnN46WJTe3jWxtQP9lMZm1LJNkFLlTaWAxK2vUQR+cqw==", "integrity": "sha512-atlQQJ2YkO4pfTVQmQ+wvYQwexPDOIgo+RaVcD7gHgzy/IQA+XTyuxNM9M9TVXvttkF7koBHmcwisKdOAf2EcA==",
"dependencies": [ "dependencies": [
"@typescript-eslint/eslint-plugin", "@typescript-eslint/eslint-plugin",
"@typescript-eslint/parser", "@typescript-eslint/parser",
@ -1585,8 +1588,8 @@
"util-deprecate@1.0.2": { "util-deprecate@1.0.2": {
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
}, },
"vite@7.2.4_@types+node@22.19.1_picomatch@4.0.3": { "vite@7.3.0_@types+node@22.19.3_picomatch@4.0.3": {
"integrity": "sha512-NL8jTlbo0Tn4dUEXEsUg8KeyG/Lkmc4Fnzb8JXN/Ykm9G4HNImjtABMJgkQoVjOBN/j2WAwDTRytdqJbZsah7w==", "integrity": "sha512-dZwN5L1VlUBewiP6H9s2+B3e3Jg96D0vzN+Ry73sOefebhYr9f94wwkMNN/9ouoU8pV1BqA1d1zGk8928cx0rg==",
"dependencies": [ "dependencies": [
"@types/node", "@types/node",
"esbuild", "esbuild",
@ -1604,7 +1607,7 @@
], ],
"bin": true "bin": true
}, },
"vitefu@1.1.1_vite@7.2.4__@types+node@22.19.1__picomatch@4.0.3_@types+node@22.19.1": { "vitefu@1.1.1_vite@7.3.0__@types+node@22.19.3__picomatch@4.0.3_@types+node@22.19.3": {
"integrity": "sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==", "integrity": "sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==",
"dependencies": [ "dependencies": [
"vite" "vite"
@ -1636,27 +1639,27 @@
"workspace": { "workspace": {
"packageJson": { "packageJson": {
"dependencies": [ "dependencies": [
"npm:@eslint/compat@^1.4.0", "npm:@eslint/compat@^1.4.1",
"npm:@eslint/js@^9.39.1", "npm:@eslint/js@^9.39.2",
"npm:@sveltejs/adapter-node@^5.4.0", "npm:@sveltejs/adapter-node@^5.4.0",
"npm:@sveltejs/kit@^2.48.5", "npm:@sveltejs/kit@^2.49.3",
"npm:@sveltejs/vite-plugin-svelte@^6.2.1", "npm:@sveltejs/vite-plugin-svelte@^6.2.2",
"npm:@tailwindcss/forms@~0.5.10", "npm:@tailwindcss/forms@~0.5.11",
"npm:@tailwindcss/typography@~0.5.19", "npm:@tailwindcss/typography@~0.5.19",
"npm:@tailwindcss/vite@^4.1.17", "npm:@tailwindcss/vite@^4.1.18",
"npm:@types/node@22", "npm:@types/node@^22.19.3",
"npm:daisyui@^5.5.5", "npm:daisyui@^5.5.14",
"npm:eslint-plugin-svelte@^3.13.0", "npm:eslint-plugin-svelte@^3.13.1",
"npm:eslint@^9.39.1", "npm:eslint@^9.39.2",
"npm:globals@^16.5.0", "npm:globals@^16.5.0",
"npm:prettier-plugin-svelte@^3.4.0", "npm:prettier-plugin-svelte@^3.4.1",
"npm:prettier@^3.7.4", "npm:prettier@^3.7.4",
"npm:svelte-check@^4.3.4", "npm:svelte-check@^4.3.5",
"npm:svelte@^5.43.8", "npm:svelte@^5.46.1",
"npm:tailwindcss@^4.1.17", "npm:tailwindcss@^4.1.18",
"npm:typescript-eslint@^8.47.0", "npm:typescript-eslint@^8.52.0",
"npm:typescript@^5.9.3", "npm:typescript@^5.9.3",
"npm:vite@^7.2.2" "npm:vite@^7.3.0"
] ]
} }
} }

View file

@ -13,28 +13,28 @@
"lint": "eslint ." "lint": "eslint ."
}, },
"dependencies": { "dependencies": {
"daisyui": "^5.5.5" "daisyui": "^5.5.14"
}, },
"devDependencies": { "devDependencies": {
"@eslint/compat": "^1.4.0", "@eslint/compat": "^1.4.1",
"@eslint/js": "^9.39.1", "@eslint/js": "^9.39.2",
"@sveltejs/adapter-node": "^5.4.0", "@sveltejs/adapter-node": "^5.4.0",
"@sveltejs/kit": "^2.48.5", "@sveltejs/kit": "^2.49.3",
"@sveltejs/vite-plugin-svelte": "^6.2.1", "@sveltejs/vite-plugin-svelte": "^6.2.2",
"@tailwindcss/forms": "^0.5.10", "@tailwindcss/forms": "^0.5.11",
"@tailwindcss/typography": "^0.5.19", "@tailwindcss/typography": "^0.5.19",
"@tailwindcss/vite": "^4.1.17", "@tailwindcss/vite": "^4.1.18",
"@types/node": "^22", "@types/node": "^22.19.3",
"eslint": "^9.39.1", "eslint": "^9.39.2",
"eslint-plugin-svelte": "^3.13.0", "eslint-plugin-svelte": "^3.13.1",
"globals": "^16.5.0", "globals": "^16.5.0",
"prettier": "^3.7.4", "prettier": "^3.7.4",
"prettier-plugin-svelte": "^3.4.0", "prettier-plugin-svelte": "^3.4.1",
"svelte": "^5.43.8", "svelte": "^5.46.1",
"svelte-check": "^4.3.4", "svelte-check": "^4.3.5",
"tailwindcss": "^4.1.17", "tailwindcss": "^4.1.18",
"typescript": "^5.9.3", "typescript": "^5.9.3",
"typescript-eslint": "^8.47.0", "typescript-eslint": "^8.52.0",
"vite": "^7.2.2" "vite": "^7.3.0"
} }
} }

View file

@ -1,11 +1,28 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta property="og:locale" content="en_US">
<meta property="og:type" content="website">
<meta property="og:site_name" content="Hexname">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="copyright" content="HexName">
<meta name="base" content="https://hexname.com">
<link rel="canonical" href="https://hexname.com/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="HandheldFriendly" content="True">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="default">
<meta name="referrer" content="no-referrer-when-downgrade">
<meta name="twitter:card" content="summary_large_image">
%sveltekit.head% %sveltekit.head%
</head> </head>
<body data-sveltekit-preload-data="hover"> <body class="bg-base-200 h-screen" data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div> <div style="display: contents">
%sveltekit.body%
</div>
</body> </body>
</html> </html>

View file

@ -1,7 +1,7 @@
<script lang="ts"> <script lang="ts">
import { fade, fly } from "svelte/transition"; import { fade, fly } from "svelte/transition";
let { errorMessage = null as string | null, duration = 5000 } = $props(); let { errorMessage = $bindable(), duration = 5000 } = $props();
$effect(() => { $effect(() => {
if (!errorMessage) { if (!errorMessage) {
@ -15,6 +15,7 @@
timeoutId = setTimeout(() => { timeoutId = setTimeout(() => {
visible = false; visible = false;
timeoutId = null; timeoutId = null;
errorMessage = "";
}, duration); }, duration);
}); });
@ -27,7 +28,7 @@
in:fly={{ y: -70, duration: 500 }} in:fly={{ y: -70, duration: 500 }}
out:fade={{ duration: 300 }} out:fade={{ duration: 300 }}
> >
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 shrink-0 stroke-current" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" /></svg> <svg class="h-6 w-6 shrink-0 stroke-current" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" /></svg>
<span>{errorMessage}</span> <span>{errorMessage}</span>
</div> </div>
{/if} {/if}

55
src/lib/Footer.svelte Normal file
View file

@ -0,0 +1,55 @@
<script>
import { auth } from "./auth.svelte";
const year = new Date().getFullYear();
</script>
<footer class="flex items-center justify-center bg-base-200 text-base-content p-10 mt-15 z-9">
<div class="footer footer-horizontal max-w-800">
<div class="hidden sm:block"></div>
<div class="hidden sm:block"></div>
<aside>
<svg
width="50"
height="50"
viewBox="0 0 24 24"
fill-rule="evenodd"
clip-rule="evenodd"
class="fill-current">
<path
d="M22.672 15.226l-2.432.811.841 2.515c.33 1.019-.209 2.127-1.23 2.456-1.15.325-2.148-.321-2.463-1.226l-.84-2.518-5.013 1.677.84 2.517c.391 1.203-.434 2.542-1.831 2.542-.88 0-1.601-.564-1.86-1.314l-.842-2.516-2.431.809c-1.135.328-2.145-.317-2.463-1.229-.329-1.018.211-2.127 1.231-2.456l2.432-.809-1.621-4.823-2.432.808c-1.355.384-2.558-.59-2.558-1.839 0-.817.509-1.582 1.327-1.846l2.433-.809-.842-2.515c-.33-1.02.211-2.129 1.232-2.458 1.02-.329 2.13.209 2.461 1.229l.842 2.515 5.011-1.677-.839-2.517c-.403-1.238.484-2.553 1.843-2.553.819 0 1.585.509 1.85 1.326l.841 2.517 2.431-.81c1.02-.33 2.131.211 2.461 1.229.332 1.018-.21 2.126-1.23 2.456l-2.433.809 1.622 4.823 2.433-.809c1.242-.401 2.557.484 2.557 1.838 0 .819-.51 1.583-1.328 1.847m-8.992-6.428l-5.01 1.675 1.619 4.828 5.011-1.674-1.62-4.829z"></path>
</svg>
<p>
© 2025-{year} HexName
<br/>
Focus on what truly matters.
</p>
</aside>
<nav>
<p class="footer-title">Services</p>
<div>
<a class="link link-hover" href="/register">Register</a> /
<a class="link link-hover" href="/login">Log in</a>
</div>
{#if auth.isAuthenticated}
<a class="link link-hover" href="/dashboard/register-domain">Register a domain</a>
{:else}
<a class="link link-hover" href="/#search-for-your-domain">Search for a domain</a>
{/if}
<a class="link link-hover" href="/#contact-us">Contact us!</a>
</nav>
<nav>
<p class="footer-title">Pages</p>
<a class="link link-hover" href="/">Home</a>
<a class="link link-hover" href="/about">About</a>
<a class="link link-hover" href="/faq">Frequently asked questions</a>
</nav>
<nav>
<p class="footer-title">Legal</p>
<a class="link link-hover" href="/terms-of-service">Terms of service</a>
<a class="link link-hover" href="/privacy-policy">Privacy policy</a>
<a class="link link-hover" href="cookie-policy">Cookie policy</a>
</nav>
<div class="hidden sm:block"></div>
<div class="hidden sm:block"></div>
</div>
</footer>

View file

@ -26,26 +26,25 @@
auth.isMfaEnabled = !auth.isMfaEnabled; auth.isMfaEnabled = !auth.isMfaEnabled;
} }
} }
let { sideMenuOpen = $bindable(), isMobile } = $props()
</script> </script>
<div class="navbar bg-base-100 shadow-sm top-0 z-10 py-0"> <div class="backdrop-blur bg-white/6 fixed navbar shadow-sm top-0 z-40 py-0" id="main-navbar">
<div class="navbar-start"> <div class="navbar-start">
<div class="dropdown"> {#if auth.isAuthenticated || isMobile}
<div tabindex="0" role="button" class="btn btn-ghost lg:hidden"> <button aria-label="toggle side menu" onclick={() => {sideMenuOpen = !sideMenuOpen}}>
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h8m-8 6h16" /> </svg> <ul class="menu p-0"><li>
<div class="p-2.5">
<svg class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h8m-8 6h16"/></svg>
</div> </div>
<ul </li></ul>
tabindex="-1" </button>
class="menu menu-sm dropdown-content bg-base-100 rounded-box z-1 mt-3 w-52 p-2 shadow"> {/if}
<li><a href="/">Home</a></li> <ul class="menu pl-0"><li><a href="/" class="text-xl font-semibold">HexName</a></li></ul>
<li><a href="/about">About us</a></li>
<li><a href="/faq">FAQ</a></li>
</ul>
</div> </div>
<a class="btn btn-ghost text-xl" href="/">HexName</a> <div class="navbar m-0 w-100">
</div> <ul class="menu menu-horizontal not-md:hidden m-auto justify-center items-center">
<div class="navbar-center hidden lg:flex">
<ul class="menu menu-horizontal px-1">
<li><a href="/">Home</a></li> <li><a href="/">Home</a></li>
<li><a href="/about">About us</a></li> <li><a href="/about">About us</a></li>
<li><a href="/faq">FAQ</a></li> <li><a href="/faq">FAQ</a></li>
@ -53,35 +52,39 @@
</div> </div>
<div class="navbar-end"> <div class="navbar-end">
{#if auth.isAuthenticated} {#if auth.isAuthenticated}
<div class="dropdown dropdown-end"> <div class="dropdown dropdown-end z-40">
<div tabindex="0" role="button" class="btn btn-ghost btn-circle avatar"> <div tabindex="0" role="button" class="btn btn-ghost btn-circle avatar" aria-label="profile icon">
<svg class="size-9" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="#dfe5ed"><path stroke-linecap="round" stroke-linejoin="round" d="M17.982 18.725A7.488 7.488 0 0 0 12 15.75a7.488 7.488 0 0 0-5.982 2.975m11.963 0a9 9 0 1 0-11.963 0m11.963 0A8.966 8.966 0 0 1 12 21a8.966 8.966 0 0 1-5.982-2.275M15 9.75a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" /></svg> <svg class="size-9" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="#dfe5ed"><path stroke-linecap="round" stroke-linejoin="round" d="M17.982 18.725A7.488 7.488 0 0 0 12 15.75a7.488 7.488 0 0 0-5.982 2.975m11.963 0a9 9 0 1 0-11.963 0m11.963 0A8.966 8.966 0 0 1 12 21a8.966 8.966 0 0 1-5.982-2.275M15 9.75a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" /></svg>
</div> </div>
<ul <ul
tabindex="-1" tabindex="-1"
class="menu menu-sm dropdown-content bg-base-200 rounded-box z-10 mt-3 w-52 p-2 shadow"> class="menu menu-sm dropdown-content bg-base-200 rounded-box z-40 mt-3 w-52 p-2 shadow">
<li><text class="font-bold">{auth.userEmail}</text></li> <li><text class="font-bold">{auth.userEmail}</text></li>
<li> <!-- <li><input type="checkbox" value="light" class="toggle theme-controller"/></li> -->
<!-- <li>
<div class="justify-between"> <div class="justify-between">
2-factor via email 2-factor via email
<label class="toggle text-base-content outline-transparent"> <label class="toggle text-base-content outline-transparent">
<input <input
type="checkbox" type="checkbox"
bind:checked={auth.isMfaEnabled} bind:checked={auth.isMfaEnabled}
on:change={toggleMfa} onchange={toggleMfa}
/> />
<svg class="outline-transparent" aria-label="disabled" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 6 18" /><path d="m6 6 12 12"/></svg> <svg class="outline-transparent" aria-label="disabled" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 6 18" /><path d="m6 6 12 12"/></svg>
<svg class="outline-transparent" aria-label="enabled" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><g stroke-linejoin="round" stroke-linecap="round" stroke-width="4" fill="none" stroke="currentColor"><path d="M20 6 9 17l-5-5"></path></g></svg> <svg class="outline-transparent" aria-label="enabled" viewBox="0 0 24 24"><g stroke-linejoin="round" stroke-linecap="round" stroke-width="4" fill="none" stroke="currentColor"><path d="M20 6 9 17l-5-5"></path></g></svg>
</label> </label>
</div> </div>
</li> </li> -->
<li><a href="/delete-account">Delete account</a></li> <li><a href="/delete-account">Delete account</a></li>
<li><a href="/logout">Log out</a></li> <li><a href="/logout">Log out</a></li>
</ul> </ul>
</div> </div>
{:else} {:else}
<a href="/register"><button class="btn btn-sm btn-primary rounded-lg mr-2">Create an account</button></a> <div class="gap-4 flex">
<a href="/login"><button class="btn btn-sm btn-secondary rounded-lg mr-2">Log in</button></a> <a href="/register"><button style="box-shadow: 0 0 10px rgba(0,0,0,0.6)" class="btn btn-primary break-keep whitespace-nowrap rounded-lg">Create an account</button></a>
<a href="/login"><button style="box-shadow: 0 0 10px rgba(0,0,0,0.6)" class="btn btn-outline btn-secondary whitespace-nowrap border-2 rounded-lg">Log in</button></a>
</div>
{/if} {/if}
</div> </div>
</div> </div>
<div class="divider bg-primary-content/20 fixed mt-[63px] z-41 h-0.25 w-screen"></div>

112
src/lib/Phone.svelte Normal file
View file

@ -0,0 +1,112 @@
<script>
let { isRotated } = $props();
</script>
<div class={isRotated ? "rotate-x-40 rotate-z-35" : ""}>
<div class=".max-w-90 .min-w-90">
<div class="flex flex-col items-center">
<div class="mockup-phone border-primary">
<div class="mockup-phone-camera"></div>
<div class="mockup-phone-display text-white .grid .place-content-center bg-base-200">
<div class="flex flex-col h-full w-full">
<div class="p-4 text-xs my-8">
<pre>$ dig example.hexname.com -t TXT +short</pre>
<pre class="text-success">"v=spf1 mx ra=spf-reports -all"</pre>
<pre>$</pre>
<pre>$</pre>
<pre>$ dig example.hexname.com +short</pre>
<pre class="text-success">198.51.100.98</pre>
<pre>$ curl icanhazip.com</pre>
<pre class="text-success">198.51.100.135</pre>
<pre>$ ./update-ddns.sh</pre>
<pre>$ dig example.hexname.com +short</pre>
<pre class="text-success">198.51.100.135</pre>
<pre>$ <text class="animate-terminal-blink"></text></pre>
</div>
<div class="mt-auto bg-base-300 w-full p-1 text-xs">
<div class="my-1 grid grid-cols-7 w-full justify-items-center items-center gap-1">
<kbd>ESC</kbd>
<kbd>/</kbd>
<kbd>-</kbd>
<kbd>HOME</kbd>
<kbd class="scale-130"></kbd>
<kbd>END</kbd>
<kbd>PGUP</kbd>
<kbd>
<svg class="size-3.5" fill="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M22 4.25a.75.75 0 00-1.5 0v15a.75.75 0 001.5 0v-15zm-9.72 14.28a.75.75 0 11-1.06-1.06l4.97-4.97H1.75a.75.75 0 010-1.5h14.44l-4.97-4.97a.75.75 0 011.06-1.06l6.25 6.25a.75.75 0 010 1.06l-6.25 6.25z"/></svg>
</kbd>
<kbd>CTRL</kbd>
<kbd>ALT</kbd>
<kbd class="scale-130"></kbd>
<kbd class="scale-130"></kbd>
<kbd class="scale-130"></kbd>
<kbd>PGDN</kbd>
</div>
</div>
<div class="bg-base-100 mb-5 py-2 w-full">
<div class="flex w-full justify-center gap-1">
<kbd class="kbd h-7 cursor-pointer hover:-translate-y-[2px] hover:bg-white/10 hover:tooltip hover:tooltip-primary" data-tip="q">q</kbd>
<kbd class="kbd h-7 cursor-pointer hover:-translate-y-[2px] hover:bg-white/10 hover:tooltip hover:tooltip-primary" data-tip="w">w</kbd>
<kbd class="kbd h-7 cursor-pointer hover:-translate-y-[2px] hover:bg-white/10 hover:tooltip hover:tooltip-primary" data-tip="e">e</kbd>
<kbd class="kbd h-7 cursor-pointer hover:-translate-y-[2px] hover:bg-white/10 hover:tooltip hover:tooltip-primary" data-tip="r">r</kbd>
<kbd class="kbd h-7 cursor-pointer hover:-translate-y-[2px] hover:bg-white/10 hover:tooltip hover:tooltip-primary" data-tip="t">t</kbd>
<kbd class="kbd h-7 cursor-pointer hover:-translate-y-[2px] hover:bg-white/10 hover:tooltip hover:tooltip-primary" data-tip="y">y</kbd>
<kbd class="kbd h-7 cursor-pointer hover:-translate-y-[2px] hover:bg-white/10 hover:tooltip hover:tooltip-primary" data-tip="u">u</kbd>
<kbd class="kbd h-7 cursor-pointer hover:-translate-y-[2px] hover:bg-white/10 hover:tooltip hover:tooltip-primary" data-tip="i">i</kbd>
<kbd class="kbd h-7 cursor-pointer hover:-translate-y-[2px] hover:bg-white/10 hover:tooltip hover:tooltip-primary" data-tip="o">o</kbd>
<kbd class="kbd h-7 cursor-pointer hover:-translate-y-[2px] hover:bg-white/10 hover:tooltip hover:tooltip-primary" data-tip="p">p</kbd>
</div>
<div class="my-1 flex w-full justify-center gap-1">
<kbd class="kbd h-7 cursor-pointer hover:-translate-y-[2px] hover:bg-white/10 hover:tooltip hover:tooltip-primary" data-tip="a">a</kbd>
<kbd class="kbd h-7 cursor-pointer hover:-translate-y-[2px] hover:bg-white/10 hover:tooltip hover:tooltip-primary" data-tip="s">s</kbd>
<kbd class="kbd h-7 cursor-pointer hover:-translate-y-[2px] hover:bg-white/10 hover:tooltip hover:tooltip-primary" data-tip="d">d</kbd>
<kbd class="kbd h-7 cursor-pointer hover:-translate-y-[2px] hover:bg-white/10 hover:tooltip hover:tooltip-primary" data-tip="f">f</kbd>
<kbd class="kbd h-7 cursor-pointer hover:-translate-y-[2px] hover:bg-white/10 hover:tooltip hover:tooltip-primary" data-tip="g">g</kbd>
<kbd class="kbd h-7 cursor-pointer hover:-translate-y-[2px] hover:bg-white/10 hover:tooltip hover:tooltip-primary" data-tip="h">h</kbd>
<kbd class="kbd h-7 cursor-pointer hover:-translate-y-[2px] hover:bg-white/10 hover:tooltip hover:tooltip-primary" data-tip="j">j</kbd>
<kbd class="kbd h-7 cursor-pointer hover:-translate-y-[2px] hover:bg-white/10 hover:tooltip hover:tooltip-primary" data-tip="k">k</kbd>
<kbd class="kbd h-7 cursor-pointer hover:-translate-y-[2px] hover:bg-white/10 hover:tooltip hover:tooltip-primary" data-tip="l">l</kbd>
</div>
<div class="my-1 flex w-full justify-center gap-1">
<kbd class="kbd h-7 cursor-pointer hover:-translate-y-[2px] hover:bg-white/10">
<svg class="w-4 h-4" viewBox="0 0 24 24" fill="none"><path d="M8 17V12H5.6302C4.71068 12 4.27858 10.8635 4.96584 10.2526L10.6713 5.18109C11.429 4.50752 12.571 4.50752 13.3287 5.18109L19.0342 10.2526C19.7214 10.8635 19.2893 12 18.3698 12H16V17C16 18.1046 15.1046 19 14 19H10C8.89543 19 8 18.1046 8 17Z" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
</kbd>
<kbd class="kbd h-7 cursor-pointer hover:-translate-y-[2px] hover:bg-white/10 hover:tooltip hover:tooltip-primary" data-tip="z">z</kbd>
<kbd class="kbd h-7 cursor-pointer hover:-translate-y-[2px] hover:bg-white/10 hover:tooltip hover:tooltip-primary" data-tip="x">x</kbd>
<kbd class="kbd h-7 cursor-pointer hover:-translate-y-[2px] hover:bg-white/10 hover:tooltip hover:tooltip-primary" data-tip="c">c</kbd>
<kbd class="kbd h-7 cursor-pointer hover:-translate-y-[2px] hover:bg-white/10 hover:tooltip hover:tooltip-primary" data-tip="v">v</kbd>
<kbd class="kbd h-7 cursor-pointer hover:-translate-y-[2px] hover:bg-white/10 hover:tooltip hover:tooltip-primary" data-tip="b">b</kbd>
<kbd class="kbd h-7 cursor-pointer hover:-translate-y-[2px] hover:bg-white/10 hover:tooltip hover:tooltip-primary" data-tip="n">n</kbd>
<kbd class="kbd h-7 cursor-pointer hover:-translate-y-[2px] hover:bg-white/10 hover:tooltip hover:tooltip-primary" data-tip="m">m</kbd>
<kbd class="kbd h-7 cursor-pointer hover:-translate-y-[2px] hover:bg-white/10 hover:tooltip hover:tooltip-primary" data-tip="/">/</kbd>
<kbd class="kbd h-7 cursor-pointer hover:-translate-y-[2px] hover:bg-white/10">
<svg class="w-4.5 h-4.5" viewBox="0 0 24 24" fill="none"><path d="M7.91987 5C7.33602 5 6.78132 5.25513 6.40136 5.69842L2.11564 10.6984C1.47366 11.4474 1.47366 12.5526 2.11564 13.3016L6.40136 18.3016C6.78132 18.7449 7.33602 19 7.91987 19L19 19C20.1046 19 21 18.1046 21 17L21 7C21 5.89543 20.1046 5 19 5L7.91987 5Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"/><path d="M15 10.0001L11 14.0001" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"/><path d="M11 10.0001L15 14.0001" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"/></svg>
</kbd>
</div>
<div class="my-1 flex w-full justify-center gap-1">
<kbd class="kbd h-7 cursor-pointer hover:-translate-y-[2px] hover:bg-white/10">123</kbd>
<kbd class="kbd h-7 cursor-pointer hover:-translate-y-[2px] hover:bg-white/10 hover:tooltip hover:tooltip-primary" data-tip=",">,</kbd>
<kbd class="kbd h-7 cursor-pointer hover:-translate-y-[2px] hover:bg-white/10 w-39.5 text-xs text-primary-content/60">&lt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Space&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &gt;</kbd>
<kbd class="kbd h-7 cursor-pointer hover:-translate-y-[2px] hover:bg-white/10 hover:tooltip hover:tooltip-primary" data-tip=".">.</kbd>
<kbd class="kbd h-7 cursor-pointer hover:-translate-y-[2px] hover:bg-white/10">
<svg class="w-4 h-4" viewBox="0 0 24 24" fill="currentColor"><path fill-rule="evenodd" d="M20.239 3.749a.75.75 0 0 0-.75.75V15H5.549l2.47-2.47a.75.75 0 0 0-1.06-1.06l-3.75 3.75a.75.75 0 0 0 0 1.06l3.75 3.75a.75.75 0 1 0 1.06-1.06L5.55 16.5h14.69a.75.75 0 0 0 .75-.75V4.5a.75.75 0 0 0-.75-.751Z" clip-rule="evenodd"/></svg>
</kbd>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="flex flex-col items-center">
{#if isRotated}
<div style="box-shadow: 0 0 200px rgba(18, 68, 227, 0.8)" class="absolute mockup-phone shadow-2xl shadow-primary/50 border-black/40 border-[3.5px] bg-white/55 -z-1 -translate-y-178 translate-x-5 scale-93 max-w-90 min-w-90"></div>
<div style="border-bottom: 1.5px solid" class="absolute rounded-lg -translate-y-128 translate-x-44 rotate-90 z-9 w-25 h-[10px] bg-black/65"></div>
<div style="border-bottom: 1.5px solid" class="absolute rounded-lg -translate-y-100 translate-x-44 rotate-90 z-9 w-15 h-[10px] bg-black/65"></div>
<div style="border-left: 1.5px solid; border-bottom: 1.5px solid;" class="absolute rounded-lg ml-3 mt-[3px] w-10 h-3 border-2 border-white/15 bg-black/80"></div>
{:else}
<div style="box-shadow: 0 0 200px rgba(18, 68, 227, 0.8)" class="absolute mockup-phone -z-1 -translate-y-177 scale-93 w-80"></div>
{/if}
</div>
</div>

View file

@ -8,8 +8,103 @@
let { records = $bindable(), record, i, fqdn, error }: { records: DnsRecord[], record: DnsRecord, i: number, fqdn: string, error: string } = $props(); let { records = $bindable(), record, i, fqdn, error }: { records: DnsRecord[], record: DnsRecord, i: number, fqdn: string, error: string } = $props();
let isEdit = $state(false); let isEdit = $state(false);
let recordDraft = $state($state.snapshot(record)); $effect(() => {
records.length;
isEdit = false;
})
let errorMessage = $state(''); let errorMessage = $state('');
// svelte-ignore state_referenced_locally
let recordDraft = $state($state.snapshot(record));
// svelte-ignore state_referenced_locally
let hasToken = $state(record.has_token);
let tokenScript = $derived.by(() => {
if (record.record_type === "A") {
return "#!/bin/bash\n" +
"IP=$(curl -s http://ipv4.icanhazip.com)\n" +
`curl -X PUT https://hexname.com/api/v1/ddns/ipv4/${token}/$IP`
} else if (record.record_type === "AAAA") {
return "#!/bin/bash\n" +
"IP=$(curl -s http://ipv6.icanhazip.com)\n" +
`curl -X PUT https://hexname.com/api/v1/ddns/ipv6/${token}/$IP`
} else {
return "A weird error happened. Please contact support with this screenshot.";
}
});
let copied = $state(false);
let resetTimer: NodeJS.Timeout | undefined;
function copyToken() {
if (copied) return;
navigator.clipboard.writeText(tokenScript);
copied = true;
let btn = document.getElementById("copy-btn")
btn?.classList.add("swap-active");
clearTimeout(resetTimer);
resetTimer = setTimeout(() => {
copied = false;
btn?.classList.remove("swap-active");
}, 1000);
}
let modal: HTMLDialogElement | null = $state(null);
let token = $state('');
async function generateToken() {
try {
let res = await fetch(`${PUBLIC_BACKEND_API_HOST}/api/v1/record/ddns-token`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({"id": record.id })});
if (!res.ok) {
errorMessage = (await res.json()).msg || "Something went wrong";
console.log(errorMessage);
return;
}
let data = await res.json();
if (!res.ok) {
errorMessage = data?.msg || "Something went wrong";
console.log(errorMessage);
return;
}
token = data.token;
modal?.showModal();
} catch (err: any) {
errorMessage = err?.msg || "Network error";
console.log(errorMessage);
}
}
async function revokeToken() {
try {
let res = await fetch(`${PUBLIC_BACKEND_API_HOST}/api/v1/record/ddns-token`, {
method: 'DELETE',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({"id": record.id })});
if (!res.ok) {
errorMessage = (await res.json()).msg || "Something went wrong";
console.log(errorMessage);
return;
}
if (!res.ok) {
errorMessage = "Something went wrong";
console.log(errorMessage);
return;
}
hasToken = false;
} catch (err: any) {
errorMessage = err?.msg || "Network error";
console.log(errorMessage);
}
}
function triggerMenu() { function triggerMenu() {
if (isEdit) { if (isEdit) {
@ -69,7 +164,6 @@
} }
records = handleUiRecordUpdates(records, data); records = handleUiRecordUpdates(records, data);
alert("Record successfully updated!")
} catch (err: any) { } catch (err: any) {
errorMessage = err?.msg || "Network error"; errorMessage = err?.msg || "Network error";
console.log(errorMessage); console.log(errorMessage);
@ -101,10 +195,11 @@
<tr <tr
class={isEdit class={isEdit
? "bg-base-300" ? "bg-primary/30"
// ? "bg-base-300"
: :
`${ `${
i % 2 === 0 ? '[&>td]:bg-base-100' : '[&>td]:bg-base-200' i % 2 === 0 ? '[&>td]:bg-base-100' : '[&>td]:bg-base-200/60'
}` }`
} }
> >
@ -124,12 +219,12 @@
</td> </td>
<td class="w-0 p-0 px-4"> <td class="w-0 p-0 px-4">
{#if isEdit} {#if isEdit}
<button class="btn btn-xs tooltip rounded-md p-0 w-7 h-7" data-tip="Discard changes" onclick={triggerMenu}> <button class="btn btn-xs tooltip rounded-md p-0 w-7 h-7" data-tip="Discard changes" aria-label="close icon" onclick={triggerMenu}>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" /></svg> <svg fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" /></svg>
</button> </button>
{:else} {:else}
<button class="btn btn-xs tooltip rounded-md p-0 w-7 h-7" data-tip="Edit" onclick={triggerMenu}> <button class="btn btn-xs tooltip rounded-md p-0 w-7 h-7" data-tip="Edit" aria-label="pencil icon" onclick={triggerMenu}>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6"><path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10" /></svg> <svg fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6"><path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10" /></svg>
</button> </button>
{/if} {/if}
</td> </td>
@ -154,7 +249,7 @@
<label class="fieldset-legend mr-1" for="record-priority">Priority</label> <label class="fieldset-legend mr-1" for="record-priority">Priority</label>
<div class="tooltip tooltip-info mt-1" data-tip="This field is useful if you have multiple mailservers. The server with the lower priority is tried first. If it fails to receive mail, the one with the next lowest priority is tried. Set the same priority values for for load-balancing."> <div class="tooltip tooltip-info mt-1" data-tip="This field is useful if you have multiple mailservers. The server with the lower priority is tried first. If it fails to receive mail, the one with the next lowest priority is tried. Set the same priority values for for load-balancing.">
<div role="alert" class="alert m-0 p-0 gap-2 flex flex-column justify-center ml-auto "> <div role="alert" class="alert m-0 p-0 gap-2 flex flex-column justify-center ml-auto ">
<svg class="stroke-primary-content h-4 w-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg> <svg class="stroke-primary-content h-4 w-4" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
</div> </div>
</div> </div>
</div> </div>
@ -171,7 +266,7 @@
<label class="fieldset-legend mr-1" for="record-priority">Priority</label> <label class="fieldset-legend mr-1" for="record-priority">Priority</label>
<div class="tooltip tooltip-info mt-1" data-tip="This field is useful if you have multiple servers. The server with the lower priority is prioritized for traffic."> <div class="tooltip tooltip-info mt-1" data-tip="This field is useful if you have multiple servers. The server with the lower priority is prioritized for traffic.">
<div role="alert" class="alert m-0 p-0 gap-2 flex flex-column justify-center ml-auto "> <div role="alert" class="alert m-0 p-0 gap-2 flex flex-column justify-center ml-auto ">
<svg class="stroke-primary-content h-4 w-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg> <svg class="stroke-primary-content h-4 w-4" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
</div> </div>
</div> </div>
</div> </div>
@ -185,7 +280,7 @@
<label class="fieldset-legend mr-1" for="record-weight">Weight</label> <label class="fieldset-legend mr-1" for="record-weight">Weight</label>
<div class="tooltip tooltip-info mt-1" data-tip="This field serves a similar purpose as the Priority, except it is looked at second. So priority takes precedence."> <div class="tooltip tooltip-info mt-1" data-tip="This field serves a similar purpose as the Priority, except it is looked at second. So priority takes precedence.">
<div role="alert" class="alert m-0 p-0 gap-2 flex flex-column justify-center ml-auto "> <div role="alert" class="alert m-0 p-0 gap-2 flex flex-column justify-center ml-auto ">
<svg class="stroke-primary-content h-4 w-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg> <svg class="stroke-primary-content h-4 w-4" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
</div> </div>
</div> </div>
</div> </div>
@ -210,6 +305,7 @@
<div class="align-right validator-hint mt-1">{error}</div> <div class="align-right validator-hint mt-1">{error}</div>
</div> </div>
</div> </div>
<div class="flex flex-col sm:flex-row"> <div class="flex flex-col sm:flex-row">
<label class="m-2 form-control flex flex-1 flex-col"> <label class="m-2 form-control flex flex-1 flex-col">
<div class="flex flex-row"> <div class="flex flex-row">
@ -226,7 +322,7 @@
<label class="fieldset-legend mr-1" for="record-ttl">TTL</label> <label class="fieldset-legend mr-1" for="record-ttl">TTL</label>
<div class="tooltip tooltip-info mt-1" data-tip="TTL or 'Time To Live' controls how long the record is allowed to be cached on different devices. Set a lower number if you expect your record to change value very often."> <div class="tooltip tooltip-info mt-1" data-tip="TTL or 'Time To Live' controls how long the record is allowed to be cached on different devices. Set a lower number if you expect your record to change value very often.">
<div role="alert" class="alert m-0 p-0 gap-2 flex flex-column justify-center ml-auto "> <div role="alert" class="alert m-0 p-0 gap-2 flex flex-column justify-center ml-auto ">
<svg class="stroke-primary-content h-4 w-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg> <svg class="stroke-primary-content h-4 w-4" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
</div> </div>
</div> </div>
</div> </div>
@ -245,6 +341,55 @@
bind:checked={recordDraft.is_active} bind:checked={recordDraft.is_active}
/> />
</label> </label>
{#if record.record_type === 'A' || record.record_type === "AAAA"}
{#if hasToken}
<button class="btn text-error" type="button" onclick={() => modal?.showModal()}>Revoke DDNS token</button>
<dialog bind:this={modal} class="modal">
<div class="modal-box">
<h3 class="text-lg font-bold">Are you sure you want to revoke this DDNS token?</h3>
<p class="py-4">You won't be able to use the token to update this record anymore.<br>You can generate a new token anytime.</p>
<div class="modal-action gap-6">
<button class="btn w-30 btn-primary mr-auto" type="button" onclick={() => modal?.close()}>Go back</button>
<button class="btn w-30 btn-error ml-auto" type="button" onclick={() => { revokeToken(); modal?.close();}}>Revoke</button>
</div>
</div>
</dialog>
{:else}
<button class="btn text-success" type="button" onclick={generateToken}>Generate DDNS token</button>
<dialog bind:this={modal} class="modal">
<div class="modal-box w-fill lg:w-250 max-w-none">
<h3 class="text-lg font-bold">DDNS token generated!</h3>
<p class="py-4">This token will only be shown once now. Make sure to save it.</p>
<code>{token}</code>
<p class="py-4">Or use this Bash script to update your IP:</p>
<div class="mockup-code my-2 relative bg-base-200">
<label id="copy-btn" class="btn btn-circle swap swap-rotate absolute top-2 right-2">
<input type="checkbox" bind:checked={copied} onclick={(e) => {e.preventDefault(); copyToken();}}/>
<svg class="size-6 swap-off" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M15.666 3.888A2.25 2.25 0 0 0 13.5 2.25h-3c-1.03 0-1.9.693-2.166 1.638m7.332 0c.055.194.084.4.084.612v0a.75.75 0 0 1-.75.75H9a.75.75 0 0 1-.75-.75v0c0-.212.03-.418.084-.612m7.332 0c.646.049 1.288.11 1.927.184 1.1.128 1.907 1.077 1.907 2.185V19.5a2.25 2.25 0 0 1-2.25 2.25H6.75A2.25 2.25 0 0 1 4.5 19.5V6.257c0-1.108.806-2.057 1.907-2.185a48.208 48.208 0 0 1 1.927-.184"/></svg>
<svg class="size-6 swap-on" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="m4.5 12.75 6 6 9-13.5"/></svg>
</label>
<div class="overflow-x-auto p-2">
{#if record.record_type === 'A'}
<pre><code>#!/bin/bash</code></pre>
<pre><code>IP=$(curl -s http://ipv4.icanhazip.com)</code></pre>
<pre><code>curl -X PUT https://hexname.com/api/v1/ddns/ipv4/{token}/$IP</code></pre>
{:else if record.record_type === 'AAAA'}
<pre><code>#!/bin/bash</code></pre>
<pre><code>IP=$(curl -s http://ipv6.icanhazip.com)</code></pre>
<pre><code>curl -X PUT https://hexname.com/api/v1/ddns/ipv6/{token}/$IP</code></pre>
{:else}
A weird error happened. Please contact support with this screenshot.
{/if}
</div>
</div>
<div class="modal-action">
<button class="btn btn-primary w-30" type="button" onclick={() => { modal?.close(); hasToken = true; token = '';} }>Got it!</button>
</div>
</div>
</dialog>
{/if}
{/if}
<button class="btn btn-error m-2 p-0 w-full sm:w-30" type="button" onclick={handleDeleteRecord}>Delete record</button> <button class="btn btn-error m-2 p-0 w-full sm:w-30" type="button" onclick={handleDeleteRecord}>Delete record</button>
<button class="btn btn-primary m-2 p-0 w-full sm:w-30" type="submit">Save</button> <button class="btn btn-primary m-2 p-0 w-full sm:w-30" type="submit">Save</button>
</div> </div>
@ -252,7 +397,7 @@
<RecordExplanation recordType={recordDraft.record_type} name={recordDraft.name} value={recordDraft.value} displayName={getDisplayName(recordDraft.record_type, recordDraft.name)} displayValue={getDisplayValue(recordDraft.record_type, recordDraft.value, fqdn)} {fqdn}/> <RecordExplanation recordType={recordDraft.record_type} name={recordDraft.name} value={recordDraft.value} displayName={getDisplayName(recordDraft.record_type, recordDraft.name)} displayValue={getDisplayValue(recordDraft.record_type, recordDraft.value, fqdn)} {fqdn}/>
{#if errorMessage} {#if errorMessage}
<div class="mt-3 h-12 flex items-center"> <div class="mt-3 h-12 flex items-center">
<ErrorPopup {errorMessage} duration={10000} /> <ErrorPopup bind:errorMessage={errorMessage} duration={10000} />
</div> </div>
{/if} {/if}
</form> </form>

View file

@ -1,24 +1,49 @@
<script lang="ts"> <script lang="ts">
import { domains } from "./domains.svelte"; import { domains } from "./domains.svelte";
import { auth } from '$lib/auth.svelte';
let errorMessage: string | null = $state(null); let { sideMenuOpen = $bindable(), isDashboard } = $props()
</script> </script>
<aside class="bg-base-200"> {#if sideMenuOpen}
<ul class="menu overflow-y-auto h-full w-0 sm:w-60 hidden lg:block max-h-full scroll"> <button aria-label="close side menu" class={`fixed inset-0 top-16
${isDashboard ? "not-lg:bg-black/40 not-lg:backdrop-blur-sm z-30 lg:-z-10"
: "bg-black/40 backdrop-blur-sm z-30"}`}
onclick={() => {sideMenuOpen = false}}
></button>
{/if}
<aside
class={`
fixed top-16 w-60 bg-white/6 transition-transform
${sideMenuOpen ? 'translate-x-0' : '-translate-x-60.25'}
lg:translate-x-0.
duration-250 ease-in-out
z-31
`}
>
<ul class="menu bg-white/6 h-[calc(100vh-65px)] z-9 w-60 block min-h-0 overflow-y-auto">
{#if isDashboard}
<li class="bg-base-300 opacity-0 lg:opacity-100 h-screen fixed -z-1 w-60 top-0 left-0 m-0"></li>
{/if}
<li class="md:hidden block">
<a href="/">Home</a>
<a href="/about">About us</a>
<a href="/faq">FAQ</a>
</li>
{#if auth.isAuthenticated}
<div class="sm:hidden divider m-0"></div>
<li> <li>
<a href="/dashboard/register-domain"> <a href="/dashboard/register-domain">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-4"> <svg fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-4">
<path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15"/> <path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15"/>
</svg> </svg>
Register a new domain Register a new domain
</a> </a>
</li> </li>
{/if}
{#if !domains.loadingSubdomains} {#if !domains.loadingSubdomains}
<div class="divider m-0"></div> <div class="divider m-0"></div>
<li> <li>
<details open> <a href="/dashboard">Manage your DNS records</a>
<summary>Manage your DNS records</summary>
<ul> <ul>
{#each domains.subdomains as sub} {#each domains.subdomains as sub}
<li><a href="/dashboard/{sub.id}"> <li><a href="/dashboard/{sub.id}">
@ -26,10 +51,10 @@
</a></li> </a></li>
{/each} {/each}
</ul> </ul>
</details>
</li> </li>
{:else if domains.loadingFailed} {:else if domains.loadingFailed}
<li class="bg-error rounded"><a class="text-error-content" href="/logout">Loading your domains failed. Please refresh the page or try logging out and back in</a></li> <li class="bg-error rounded"><a class="text-error-content" href="/logout">Loading your domains failed. Please refresh the page or try logging out and back in</a></li>
{/if} {/if}
</ul> </ul>
<div class="divider divider-vertical bg-primary-content/35 fixed w-0.25 h-[calc(100vh-65px)] top-0 z-10 m-0 ml-60">&nbsp;</div>
</aside> </aside>

View file

@ -11,6 +11,7 @@ export interface DnsRecord {
priority?: number; priority?: number;
weight?: number; weight?: number;
port?: number; port?: number;
has_token?: boolean;
} }
export interface RecordsResponse { export interface RecordsResponse {

23
src/lib/slideIn.ts Normal file
View file

@ -0,0 +1,23 @@
export function slideIn(node: HTMLElement) {
const observer = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting) {
node.classList.add("opacity-100");
node.classList.remove("opacity-0", "lg:translate-x-60", "lg:-translate-x-60", "translate-x-30", "-translate-x-30", "lg:-translate-x-60", "not-lg:translate-y-40");
observer.unobserve(node);
}
},
{
threshold: 0,
rootMargin: "0px 0px -20% 0px"
}
);
observer.observe(node);
return {
destroy() {
observer.disconnect();
}
};
}

View file

@ -1,12 +1,17 @@
<script lang="ts"> <script lang="ts">
import './layout.css'; import './layout.css';
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import { PUBLIC_BACKEND_API_HOST } from '$env/static/public';
import favicon from '$lib/assets/favicon.svg'; import favicon from '$lib/assets/favicon.svg';
// import homeOg from '$lib/assets/home-og.png';
import MainNavbar from '$lib/MainNavbar.svelte'; import MainNavbar from '$lib/MainNavbar.svelte';
import SideMenu from '$lib/SideMenu.svelte'; import SideMenu from '$lib/SideMenu.svelte';
import { auth, initUserAuthStatus } from '$lib/auth.svelte'; import { auth, initUserAuthStatus } from '$lib/auth.svelte';
import { domains, getSubdomains, getBaseDomains } from '$lib/domains.svelte'; import { getSubdomains, getBaseDomains } from '$lib/domains.svelte';
import Footer from '$lib/Footer.svelte';
import { page } from '$app/state';
import { afterNavigate } from '$app/navigation';
let { children } = $props();
onMount(async () => { onMount(async () => {
await initUserAuthStatus(); await initUserAuthStatus();
@ -17,23 +22,57 @@
}; };
}); });
let { children } = $props(); let isDashboard: boolean = $derived(
page.url.pathname.startsWith('/dashboard')
);
let sideMenuOpen = $state(false);
afterNavigate(() => {
sideMenuOpen = isDashboard && window.matchMedia('(min-width: 1024px)').matches;
})
let innerWidth: number | null | undefined = $state();
let isMobile: boolean = $derived.by(() =>{
if (!innerWidth) return false;
return innerWidth < 768;
});
</script> </script>
<svelte:window bind:innerWidth/>
<svelte:head> <svelte:head>
<link rel="icon" href={favicon}/> <link rel="icon" href={favicon}/>
<link rel="apple-touch-icon" href={favicon}>
<!-- <meta name="twitter:image" content={homeOg}>
<meta property="og:image" content={homeOg}> -->
<meta property="og:url" content="{page.url.toString()}">
<meta name="twitter:url" content="{page.url.toString()}">
</svelte:head> </svelte:head>
<div class="flex flex-col h-screen">
<main class="bg-base-300">
<MainNavbar bind:sideMenuOpen {isMobile}/>
<div class="flex flex-row min-h-0 flex-grow">
<!-- {#if auth.isAuthenticated} -->
<div class={sideMenuOpen && isDashboard ? "w-0 lg:w-60" : "w-0"}>
<SideMenu bind:sideMenuOpen={sideMenuOpen} {isDashboard}/>
</div>
<!-- {/if} -->
<div class="flex-grow mt-16 bg-base-300 not-sm:overflow-auto">
{@render children()}
<Footer/>
</div>
</div>
</main>
<!-- <div class="flex flex-col h-screen">
<MainNavbar/> <MainNavbar/>
<div class="flex flex-row min-h-0 flex-grow"> <div class="flex flex-row min-h-0 flex-grow">
{#if auth.isAuthenticated} {#if auth.isAuthenticated}
<SideMenu/> <SideMenu/>
<!-- {:else}
<SideMenu/> -->
{/if} {/if}
<div class="flex-grow overflow-auto p-2 sm:p-12"> <div class="flex-grow overflow-auto sm:p-12 bg-base-300">
{@render children()} {@render children()}
</div> </div>
</div> </div>
</div> </div> -->

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Before After
Before After

View file

@ -1,41 +1,144 @@
<div class="flex flex-col items-center min-h-full"> <script>
<div class="w-4xl"> import Phone from "$lib/Phone.svelte";
</script>
<svelte:head>
<title>About us | HexName - Free, uncomplicated DNS management</title>
<meta property="og:title" content="About us | HexName - Free, uncomplicated DNS management">
<meta name="twitter:title" content="About us | HexName - Free, uncomplicated DNS management">
<meta name="description" content="Find out our goal at HexName and meet the team who keep the DNS infrastructure running - so you can focus on what truly matters.">
<meta property="og:description" content="Find out our goal at HexName and meet the team who keep the DNS infrastructure running - so you can focus on what truly matters.">
<meta name="twitter:description" content="Find out our goal at HexName and meet the team who keep the DNS infrastructure running - so you can focus on what truly matters.">
<meta name="robots" content="index, follow">
</svelte:head>
<div class="flex flex-col items-center">
<div class="max-w-4xl m-4">
<div class="hero bg-base-200"> <div class="hero bg-base-200">
<div class="hero-content flex-col lg:flex-row-reverse"> <div class="hero-content flex-col sm:flex-row">
<div class="mockup-code w-110"> <div class="w-full">
<pre data-prefix="$"><code>Question?</code></pre>
<pre data-prefix=">" class="text-warning"><code>Answering...</code></pre>
<pre data-prefix=">" class="text-success"><code>Done!</code></pre>
</div>
<div>
<h1 class="text-3xl font-bold">Our mission</h1> <h1 class="text-3xl font-bold">Our mission</h1>
<div class="py-6"> <div class="flex flex-col sm:flex-row items-center justify-center">
We saw that the available solutions for free DNS management as well as DDNS were lackluster. <div class="py-6 leading-8">
We thought that this was unacceptable, and decided to create the simplest solution for managing your DNS records, with more freedom than anyone on the market. We saw that the available solutions for free subdomain registration, its DNS management as well as DDNS were lackluster.
We thought that this was unacceptable, and decided to create the simplest solution for managing your DNS, with more freedom than anyone on the market.
</div> </div>
<a href="/register" class="btn btn-primary w-40">Get started</a> <div class="flex flex-row items-center px-25 sm:pl-35 my-10 not-sm:mt-4 not-sm:translate-x-3 sm:-my-6">
<div class="scale-48 -m-45">
<Phone isRotated={false}/>
</div>
</div>
</div>
<a href="/register" class="btn btn-primary w-full sm:w-40">Get started</a>
</div> </div>
</div> </div>
</div> </div>
<div class="divider"></div> <div class="divider"></div>
<h2 class="legend text-xl font-bold p-4 m-4">About the team</h2> <section class="flex flex-col items-center text-primary-content w-full my-8">
<h2 class="text-4xl font-semibold max-w-2xl">
Meet the <span class="bg-gradient-to-t from-primary to-base-300">team</span>!
</h2>
<p class="text-center max-w-lg mt-3">
HexName was developed by a team of passionate tech-enthusiasts with years of experience in the field. HexName was developed by a team of passionate tech-enthusiasts with years of experience in the field.
</p>
</section>
<div class="hero bg-base-200"> <div class="hero bg-base-200 mb-16">
<div class="hero-content flex-col sm:flex-row-reverse">
<img
class="max-w-sm rounded-lg shadow-2xl"
alt="man in suit"
src="https://img.daisyui.com/images/stock/photo-1635805737707-575885ab0820.webp"
/>
<div>
<h2 class="text-3xl font-bold">Founder and CEO</h2>
<h3 class="text-md italic">Luka Dekanozishvili</h3>
<p class="py-6">
As a founder and CEO, Mr. Dekanozishvili is responsible for the strategy, vision, and direction.
His most important goal while guiding the company is ensuring that useful products are made, that people are going to use.
His leadership style emphasizes ownership, clarity, and actually getting things done fast.
</p>
<button class="btn btn-primary not-sm:w-full"><a href="https://www.linkedin.com/in/lukadeka">Get in touch!</a></button>
</div>
</div>
</div>
<div class="hero bg-base-200 mb-16">
<div class="hero-content flex-col lg:flex-row"> <div class="hero-content flex-col lg:flex-row">
<img <img
src="https://img.daisyui.com/images/stock/photo-1635805737707-575885ab0820.webp"
class="max-w-sm rounded-lg shadow-2xl" class="max-w-sm rounded-lg shadow-2xl"
alt="man in suit"
src="https://img.daisyui.com/images/stock/photo-1635805737707-575885ab0820.webp"
/> />
<div> <div>
<h2 class="text-3xl font-bold">Head of Marketing</h2> <h2 class="text-3xl font-bold">Head of Marketing</h2>
<h3 class="text-md italic">Luka Dekanozishvili</h3> <h3 class="text-md italic">Luka Dekanozishvili</h3>
<p class="py-6"> <p class="py-6">
Mr. Dekanozishvili is our Head of Marketing as well as our Senior Marketing Manager. He excells in Search Engine Optimization, and helped build up the reputation of HexName from the ground up. Mr. Dekanozishvili is our Head of Marketing as well as our Senior Marketing Manager.
He excels in Search Engine Optimization, and helped build up the reputation of HexName from the ground up.
</p> </p>
<button class="btn btn-primary">Get in touch!</button> <button class="btn btn-primary not-sm:w-full"><a href="https://www.linkedin.com/in/lukadeka">Get in touch!</a></button>
</div>
</div>
</div>
<div class="hero bg-base-200 mb-16">
<div class="hero-content flex-col lg:flex-row-reverse">
<img
class="max-w-sm rounded-lg shadow-2xl"
alt="man in suit"
src="https://img.daisyui.com/images/stock/photo-1635805737707-575885ab0820.webp"
/>
<div>
<h2 class="text-3xl font-bold">Senior Software Engineer</h2>
<h3 class="text-md italic">Luka Dekanozishvili</h3>
<p class="py-6">
With numerous years of experience leading and building company-wide projects, Luka Dekanozishvili is an expert at backend as well as frontend development.
He specializes in scalability, maintainability, as well as ensuring a high-quality product.
</p>
<button class="btn btn-primary not-sm:w-full"><a href="https://www.linkedin.com/in/lukadeka">Get in touch!</a></button>
</div>
</div>
</div>
<div class="hero bg-base-200 mb-16">
<div class="hero-content flex-col lg:flex-row">
<img
class="max-w-sm rounded-lg shadow-2xl"
alt="man in suit"
src="https://img.daisyui.com/images/stock/photo-1635805737707-575885ab0820.webp"
/>
<div>
<h2 class="text-3xl font-bold">Principal DevOps Engineer</h2>
<h3 class="text-md italic">Luka Dekanozishvili</h3>
<p class="py-6">
With extensive hands-on experience deploying, monitoring, and maintaining production systems, Luka single-handedly designed the entire deployment infrastructure.
He specializes in automating everything that can be automated, keeping systems reliable, simple, and rapidly fixing issues to ensure a high uptime.
<!-- When something is “handled,” it is usually because he handled it personally. -->
</p>
<button class="btn btn-primary not-sm:w-full"><a href="https://www.linkedin.com/in/lukadeka">Get in touch!</a></button>
</div>
</div>
</div>
<div class="hero bg-base-200 mb-16">
<div class="hero-content flex-col lg:flex-row-reverse">
<img
class="max-w-sm rounded-lg shadow-2xl"
alt="man in suit"
src="https://img.daisyui.com/images/stock/photo-1635805737707-575885ab0820.webp"
/>
<div>
<h2 class="text-3xl font-bold">UX & UI Design Lead</h2>
<h3 class="text-md italic">Luka Dekanozishvili</h3>
<p class="py-6">
Luka brings years of experience designing user interfaces that balance aesthetics with usability.
He is responsible for layout decisions, color schemes, accessibility considerations, and ensuring the product is maximally intuitive.
He ensures this by paying attention to every detail, and arguing with himself about every little design choice beforehand.
</p>
<button class="btn btn-primary not-sm:w-full"><a href="https://www.linkedin.com/in/lukadeka">Get in touch!</a></button>
</div> </div>
</div> </div>
</div> </div>

View file

@ -0,0 +1,91 @@
<svelte:head>
<title>HexName - Free, uncomplicated DNS management</title>
<meta property="og:title" content="HexName - Free, uncomplicated DNS management">
<meta name="twitter:title" content="HexName - Free, uncomplicated DNS management">
<meta name="description" content="Register our premium domains and manage DNS and DynDNS - so you can focus on what truly matters.">
<meta property="og:description" content="Register our premium domains and manage DNS and DynDNS - so you can focus on what truly matters.">
<meta name="twitter:description" content="Register our premium domains and manage DNS and DynDNS - so you can focus on what truly matters.">
<meta name="robots" content="noindex, nofollow">
</svelte:head>
<div class="text-primary-content max-w-7/9 sm:max-w-2/3 m-auto">
<div class="m-8">
<h1 class="text-4xl">Cookie policy</h1>
<p>Last updated January 09, 2026</p>
<hr>
</div>
<p>
This Cookie Policy explains how HexName ("<strong>Company</strong>", "<strong>we</strong>", "<strong>us</strong>", or "<strong>our</strong>") uses cookies when you visit our website at <strong>hexname.com</strong> (the "<strong>Website</strong>").
</p>
<p>
We are committed to protecting your privacy. Our Website uses <strong>only one strictly necessary cookie</strong> and does <strong>not</strong> use cookies for analytics, marketing, advertising, tracking, or personalization purposes.
</p>
<h2 class="text-2xl text-secondary p-4 font-bold">What are cookies?</h2>
<p>
Cookies are small data files that are placed on your computer or mobile device when you visit a website. They are commonly used to enable core website functionality, such as user authentication and security.
</p>
<h2 class="text-2xl text-secondary p-4 font-bold">Cookies we use</h2>
<p>
We use a single first-party, essential cookie that is required for the secure operation of user accounts.
</p>
<h3 class="text-xl text-secondary p-4 font-bold">Essential authentication cookie</h3>
<table>
<tbody>
<tr>
<td><strong>Name:</strong></td>
<td>session-token</td>
</tr>
<tr>
<td><strong>Purpose:</strong></td>
<td>
Used to authenticate users after login and to maintain a secure session while the user is signed in.
</td>
</tr>
<tr>
<td><strong>Provider:</strong></td>
<td>hexname.com</td>
</tr>
<tr>
<td><strong>Type:</strong></td>
<td>First-party, strictly necessary</td>
</tr>
<tr>
<td><strong>Expires in:</strong></td>
<td>2 days</td>
</tr>
</tbody>
</table>
<h2 class="text-2xl text-secondary p-4 font-bold">Cookies we do not use</h2>
<p>
HexName does <strong>not</strong> use:
</p>
<ul class="list-disc ml-6">
<li>Analytics or performance cookies</li>
<li>Advertising or targeting cookies</li>
<li>Social media cookies</li>
<li>Third-party cookies of any kind</li>
<li>Tracking pixels, web beacons, or similar technologies</li>
</ul>
<h2 class="text-2xl text-secondary p-4 font-bold">How can I control cookies?</h2>
<p>
Because we only use a strictly necessary cookie, it cannot be disabled through our Website. If you disable cookies entirely through your browser settings, you may not be able to log in or use authenticated features of the Website.
</p>
<h2 class="text-2xl text-secondary p-4 font-bold">Updates to this Cookie Policy</h2>
<p>
We may update this Cookie Policy from time to time to reflect operational, legal, or regulatory changes. Any updates will be posted on this page, and the “Last updated” date will be revised accordingly.
</p>
<h2 class="text-2xl text-secondary p-4 font-bold">Contact us</h2>
<p>
If you have any questions about our use of cookies, please contact us at
<a class="link text-accent italic" href="mailto:privacy@hexname.com">privacy@hexname.com</a>.
</p>
</div>

View file

@ -1,11 +1,63 @@
<script lang="ts"> <script lang="ts">
import { auth } from '$lib/auth.svelte'; import { domains } from '$lib/domains.svelte';
function toggleAuth() {
auth.isAuthenticated = !auth.isAuthenticated;
}
</script> </script>
<div class="flex flex-col items-center justify-center min-h-full"> <svelte:head>
<button on:click={toggleAuth} class="btn btn-primary">Toggle isAuthenticated</button> <title>Dashboard | HexName - Free, uncomplicated DNS management</title>
<meta property="og:title" content="Dashboard | HexName - Free, uncomplicated DNS management">
<meta name="twitter:title" content="Dashboard | HexName - Free, uncomplicated DNS management">
<meta name="description" content="Register our premium domains and manage DNS and DynDNS - so you can focus on what truly matters.">
<meta property="og:description" content="Register our premium domains and manage DNS and DynDNS - so you can focus on what truly matters.">
<meta name="twitter:description" content="Register our premium domains and manage DNS and DynDNS - so you can focus on what truly matters.">
<meta name="robots" content="noindex, nofollow">
</svelte:head>
<div class="flex flex-col items-center justify-center w-full p-4">
<h2 class="text-3xl font-semibold max-w-2xl py-8">
Your domains
</h2>
<div class="w-full mx-35 max-w-md rounded-box border border-base-content/10 bg-base-100">
<table class="w-full table nth-2:bg-base-100 nth-4:bg-base-200">
<thead>
<tr>
<th>Name</th>
</tr>
</thead>
<tbody>
{#if domains.loadingSubdomains}
<tr>
<td colspan="6" class="text-center text-base-content/60">
Loading records…
</td>
</tr>
{:else if domains.loadingFailed}
<tr>
<td colspan="6" class="text-center text-error">
An error occured while loading your domains. Please refresh the page.
</td>
</tr>
{:else if domains.subdomains.length === 0}
<tr>
<td colspan="6" class="text-center text-base-content/60">
No domains found. Register your first domain <a href="/dashboard/register-domain">here</a>!
</td>
</tr>
{:else}
{#each domains.subdomains as sub}
<tr>
<td class="p-1 pl-1">
<a href="/dashboard/{sub.id}">
<div class="p-2 w-full h-full">
{sub.name}.{sub.domain}
</div>
</a>
</td>
</tr>
{/each}
{/if}
</tbody>
</table>
</div>
</div> </div>

View file

@ -119,7 +119,6 @@
} }
records = handleUiRecordUpdates(records, data); records = handleUiRecordUpdates(records, data);
alert("Record successfully created!");
} catch (err: any) { } catch (err: any) {
errorMessage = err?.msg || "Network error"; errorMessage = err?.msg || "Network error";
console.log(errorMessage); console.log(errorMessage);
@ -148,12 +147,22 @@
</script> </script>
<div class="flex flex-col items-center px-4 w-full"> <svelte:head>
<form class="bg-base-200 border-base-300 rounded-box w-full max-w-6xl border p-4 z-3" onsubmit={handleSubmit}> <title>Dashboard | HexName - Free, uncomplicated DNS management</title>
<meta property="og:title" content="Dashboard | HexName - Free, uncomplicated DNS management">
<meta name="twitter:title" content="Dashboard | HexName - Free, uncomplicated DNS management">
<meta name="description" content="Register our premium domains and manage DNS and DynDNS - so you can focus on what truly matters.">
<meta property="og:description" content="Register our premium domains and manage DNS and DynDNS - so you can focus on what truly matters.">
<meta name="twitter:description" content="Register our premium domains and manage DNS and DynDNS - so you can focus on what truly matters.">
<meta name="robots" content="noindex, nofollow">
</svelte:head>
<div class="flex flex-col items-center px-4 py-6 w-full z-2">
<form class="bg-base-200 border-base-300 rounded-box w-full max-w-6xl border p-4 mt-8 z-3" onsubmit={handleSubmit}>
<div class="sm:flex sm:flex-col sm:flex-row"> <div class="sm:flex sm:flex-col sm:flex-row">
<legend class="text-lg m-2 font-semibold">Create a new Record</legend> <legend class="text-lg m-2 font-semibold">Create a new Record</legend>
<div role="alert" class="alert m-0 p-0 gap-2 flex flex-column ml-auto"> <div role="alert" class="alert m-0 p-0 gap-2 flex flex-column ml-auto">
<svg class="stroke-info sm:m-0 m-2 h-4 w-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg> <svg class="stroke-info sm:m-0 m-2 h-4 w-4" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
<span class="text-xs text-info flex-1">Use '@' to signify your entire domain</span> <span class="text-xs text-info flex-1">Use '@' to signify your entire domain</span>
</div> </div>
</div> </div>
@ -192,7 +201,7 @@
<label class="fieldset-legend mr-1" for="record-priority">Priority</label> <label class="fieldset-legend mr-1" for="record-priority">Priority</label>
<div class="tooltip tooltip-info mt-1" data-tip="This field is useful if you have multiple mailservers. The server with the lower priority is tried first. If it fails to receive mail, the one with the next lowest priority is tried. Set the same priority values for for load-balancing."> <div class="tooltip tooltip-info mt-1" data-tip="This field is useful if you have multiple mailservers. The server with the lower priority is tried first. If it fails to receive mail, the one with the next lowest priority is tried. Set the same priority values for for load-balancing.">
<div role="alert" class="alert m-0 p-0 gap-2 flex flex-column justify-center ml-auto "> <div role="alert" class="alert m-0 p-0 gap-2 flex flex-column justify-center ml-auto ">
<svg class="stroke-primary-content h-4 w-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg> <svg class="stroke-primary-content h-4 w-4" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
</div> </div>
</div> </div>
</div> </div>
@ -209,7 +218,7 @@
<label class="fieldset-legend mr-1" for="record-priority">Priority</label> <label class="fieldset-legend mr-1" for="record-priority">Priority</label>
<div class="tooltip tooltip-info mt-1" data-tip="This field is useful if you have multiple servers. The server with the lower priority is prioritized for traffic."> <div class="tooltip tooltip-info mt-1" data-tip="This field is useful if you have multiple servers. The server with the lower priority is prioritized for traffic.">
<div role="alert" class="alert m-0 p-0 gap-2 flex flex-column justify-center ml-auto "> <div role="alert" class="alert m-0 p-0 gap-2 flex flex-column justify-center ml-auto ">
<svg class="stroke-primary-content h-4 w-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg> <svg class="stroke-primary-content h-4 w-4" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
</div> </div>
</div> </div>
</div> </div>
@ -223,7 +232,7 @@
<label class="fieldset-legend mr-1" for="record-weight">Weight</label> <label class="fieldset-legend mr-1" for="record-weight">Weight</label>
<div class="tooltip tooltip-info mt-1" data-tip="This field serves a similar purpose as the Priority, except it is looked at second. So priority takes precedence."> <div class="tooltip tooltip-info mt-1" data-tip="This field serves a similar purpose as the Priority, except it is looked at second. So priority takes precedence.">
<div role="alert" class="alert m-0 p-0 gap-2 flex flex-column justify-center ml-auto "> <div role="alert" class="alert m-0 p-0 gap-2 flex flex-column justify-center ml-auto ">
<svg class="stroke-primary-content h-4 w-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg> <svg class="stroke-primary-content h-4 w-4" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
</div> </div>
</div> </div>
</div> </div>
@ -265,7 +274,7 @@
<label class="fieldset-legend mr-1" for="record-ttl">TTL</label> <label class="fieldset-legend mr-1" for="record-ttl">TTL</label>
<div class="tooltip tooltip-info mt-1" data-tip="TTL or 'Time To Live' controls how long the record is allowed to be cached on different devices. Set a lower number if you expect your record to change value very often."> <div class="tooltip tooltip-info mt-1" data-tip="TTL or 'Time To Live' controls how long the record is allowed to be cached on different devices. Set a lower number if you expect your record to change value very often.">
<div role="alert" class="alert m-0 p-0 gap-2 flex flex-column justify-center ml-auto "> <div role="alert" class="alert m-0 p-0 gap-2 flex flex-column justify-center ml-auto ">
<svg class="stroke-primary-content h-4 w-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg> <svg class="stroke-primary-content h-4 w-4" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
</div> </div>
</div> </div>
</div> </div>
@ -289,7 +298,11 @@
<ErrorPopup {errorMessage} duration={10000} /> <ErrorPopup {errorMessage} duration={10000} />
</div> </div>
<h2 class="text-lg m-2 pb-4 font-semibold">Manage your records</h2>
<h2 class="text-3xl font-semibold max-w-2xl py-8">
Manage your records
</h2>
<div class="w-full max-w-6xl rounded-box border border-base-content/10 bg-base-100"> <div class="w-full max-w-6xl rounded-box border border-base-content/10 bg-base-100">
<table class="w-full table nth-2:bg-base-100 nth-4:bg-base-200"> <table class="w-full table nth-2:bg-base-100 nth-4:bg-base-200">
<thead> <thead>
@ -331,22 +344,5 @@
</table> </table>
</div> </div>
<a href="{"/dashboard/" + page.params.id + "/delete"}" class="btn btn-wide btn-error m-12">Delete subdomain</a> <a href="{"/dashboard/" + page.params.id + "/delete"}" class="btn btn-wide btn-error mt-18">Delete subdomain</a>
<!-- <button class="btn btn-wide btn-error m-12" onclick={delete_subdomain_modal.showModal()}>Delete subdomain</button> -->
<!-- <dialog id="delete_subdomain_modal" class="modal">
<div class="modal-box w-11/12 max-w-5xl">
<div class="flex flex-col justify-center items-center">
<h3 class="text-lg font-bold">Are you sure you want to delete this subdomain?</h3>
<p class="py-4">All of your records for this subdomain will be deleted and other users will be able to register your domain.</p>
<p>Make sure you understand the security implications of this before proceeding.</p>
<form method="dialog" class="w-full w-fill">
<div class="flex flex-row justify-center items-center">
<button class="btn btn-wide btn-primary m-2 mr-12">Cancel</button>
<button class="btn btn-wide btn-error m-2 ml-12">Proceed</button>
</div>
</form>
</div>
</div>
</dialog> -->
</div> </div>

View file

@ -35,7 +35,6 @@
domains.subdomains = domains.subdomains.filter((sub) => sub.id !== page.params.id); domains.subdomains = domains.subdomains.filter((sub) => sub.id !== page.params.id);
delete domains.subdomainsFromId[page.params.id ?? ""]; delete domains.subdomainsFromId[page.params.id ?? ""];
alert(data.msg || 'Subdomain successfully deleted');
goto("/dashboard"); goto("/dashboard");
} catch (err: any) { } catch (err: any) {
errorMessage = err?.msg || "Network error"; errorMessage = err?.msg || "Network error";
@ -43,6 +42,16 @@
} }
</script> </script>
<svelte:head>
<title>Dashboard | HexName - Free, uncomplicated DNS management</title>
<meta property="og:title" content="Dashboard | HexName - Free, uncomplicated DNS management">
<meta name="twitter:title" content="Dashboard | HexName - Free, uncomplicated DNS management">
<meta name="description" content="Register our premium domains and manage DNS and DynDNS - so you can focus on what truly matters.">
<meta property="og:description" content="Register our premium domains and manage DNS and DynDNS - so you can focus on what truly matters.">
<meta name="twitter:description" content="Register our premium domains and manage DNS and DynDNS - so you can focus on what truly matters.">
<meta name="robots" content="noindex, nofollow">
</svelte:head>
<div class="flex flex-col items-center justify-center min-h-full"> <div class="flex flex-col items-center justify-center min-h-full">
<form <form
class="formset bg-base-200 border-base-300 rounded-box w-xs border p-4 z-1 translate-y-2" class="formset bg-base-200 border-base-300 rounded-box w-xs border p-4 z-1 translate-y-2"
@ -54,15 +63,15 @@
<code class="bold">{fqdn}</code> <code class="bold">{fqdn}</code>
{/if} {/if}
<div role="alert" class="alert p-0 mt-4 mb-2 flex flex-column justify-center"> <div role="alert" class="alert p-0 mt-4 mb-2 flex flex-column justify-center">
<svg class="stroke-error h-4 w-4 flex-shrink-0" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg> <svg class="stroke-error h-4 w-4 flex-shrink-0" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
<span class="mr-auto text-xs text-error">All your DNS records for this domain will be deleted</span> <span class="mr-auto text-xs text-error">All your DNS records for this domain will be deleted</span>
</div> </div>
<div role="alert" class="alert p-0 my-2 flex flex-column justify-center"> <div role="alert" class="alert p-0 my-2 flex flex-column justify-center">
<svg class="stroke-error h-4 w-4 flex-shrink-0" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg> <svg class="stroke-error h-4 w-4 flex-shrink-0" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
<span class="mr-auto text-xs text-error">Anyone will be able to register this subdomain. Make sure you understand the security implications of this before proceeding</span> <span class="mr-auto text-xs text-error">Anyone will be able to register this subdomain. Make sure you understand the security implications of this before proceeding</span>
</div> </div>
<div class="flex flex-row justify-center items-center"> <div class="flex flex-row justify-center items-center">
<button class="btn btn-primary mt-2 ml-0 mr-auto w-32" type="submit">Go back</button> <button class="btn btn-primary mt-2 ml-0 mr-auto w-32" type="button"><a href="/dashboard/{page.params.id}">Go back</a></button>
<button class="btn btn-error mt-2 mr-0 ml-auto w-32" type="submit">I'm sure</button> <button class="btn btn-error mt-2 mr-0 ml-auto w-32" type="submit">I'm sure</button>
</div> </div>
</form> </form>

View file

@ -89,7 +89,17 @@
}); });
</script> </script>
<div class="flex flex-col items-center justify-center min-h-full"> <svelte:head>
<title>Dashboard | HexName - Free, uncomplicated DNS management</title>
<meta property="og:title" content="Dashboard | HexName - Free, uncomplicated DNS management">
<meta name="twitter:title" content="Dashboard | HexName - Free, uncomplicated DNS management">
<meta name="description" content="Register our premium domains and manage DNS and DynDNS - so you can focus on what truly matters.">
<meta property="og:description" content="Register our premium domains and manage DNS and DynDNS - so you can focus on what truly matters.">
<meta name="twitter:description" content="Register our premium domains and manage DNS and DynDNS - so you can focus on what truly matters.">
<meta name="robots" content="noindex, nofollow">
</svelte:head>
<div class="flex flex-col items-center justify-center w-full my-30">
<form <form
class="formset bg-base-200 border-base-300 rounded-box w-xs border p-4 z-1 translate-y-2" class="formset bg-base-200 border-base-300 rounded-box w-xs border p-4 z-1 translate-y-2"
onsubmit={handleSubmit}> onsubmit={handleSubmit}>

View file

@ -29,22 +29,32 @@
} }
</script> </script>
<div class="flex flex-col items-center justify-center min-h-full"> <svelte:head>
<title>Delete your account | HexName - Free, uncomplicated DNS management</title>
<meta property="og:title" content="Delete your account | HexName - Free, uncomplicated DNS management">
<meta name="twitter:title" content="Delete your account | HexName - Free, uncomplicated DNS management">
<meta name="description" content="Register our premium domains and manage DNS and DynDNS - so you can focus on what truly matters.">
<meta property="og:description" content="Register our premium domains and manage DNS and DynDNS - so you can focus on what truly matters.">
<meta name="twitter:description" content="Register our premium domains and manage DNS and DynDNS - so you can focus on what truly matters.">
<meta name="robots" content="noindex, nofollow">
</svelte:head>
<div class="flex flex-col items-center justify-center w-full my-46.75">
<form <form
class="formset bg-base-200 border-base-300 rounded-box w-xs border p-4 z-1 translate-y-2" class="formset bg-base-200 border-base-300 rounded-box w-xs border p-4 z-1 translate-y-2"
onsubmit={handleSubmit}> onsubmit={handleSubmit}>
<legend class="fieldset-legend">Are you sure you want to delete your account?</legend> <legend class="fieldset-legend">Are you sure you want to delete your account?</legend>
<button class="btn btn-error w-full mt-2 mb-3" type="submit">Delete my account</button> <button class="btn btn-error w-full mt-2 mb-3" type="submit">Delete my account</button>
<div role="alert" class="alert p-0 mb-2 flex flex-column justify-center"> <div role="alert" class="alert p-0 mb-2 flex flex-column justify-center">
<svg class="stroke-error h-4 w-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg> <svg class="stroke-error h-4 w-4" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
<span class="mr-auto text-xs text-error">This action is irreversible</span> <span class="mr-auto text-xs text-error">This action is irreversible</span>
</div> </div>
<div role="alert" class="alert p-0 my-2 flex flex-column justify-center"> <div role="alert" class="alert p-0 my-2 flex flex-column justify-center">
<svg class="stroke-error h-4 w-4 flex-shrink-0" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg> <svg class="stroke-error h-4 w-4 flex-shrink-0" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
<span class="mr-auto text-xs text-error">All your DNS records will be deleted</span> <span class="mr-auto text-xs text-error">All your DNS records will be deleted</span>
</div> </div>
<div role="alert" class="alert p-0 my-2 flex flex-column justify-center"> <div role="alert" class="alert p-0 my-2 flex flex-column justify-center">
<svg class="stroke-error h-4 w-4 flex-shrink-0" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg> <svg class="stroke-error h-4 w-4 flex-shrink-0" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
<span class="mr-auto text-xs text-error">Anyone will be able to register your currently owned subdomains. Make sure you understand the security implications of this</span> <span class="mr-auto text-xs text-error">Anyone will be able to register your currently owned subdomains. Make sure you understand the security implications of this</span>
</div> </div>
</form> </form>

View file

@ -1,19 +1,57 @@
<div class="flex flex-col items-center min-h-full"> <script lang="ts">
<div class="w-4xl"> import { page } from "$app/state";
let copied = $state(false);
let resetTimer: NodeJS.Timeout | undefined;
function copyToken() {
if (copied) return;
let tokenScript =
"#!/bin/bash\n" +
"IP=$(curl -s http://ipv4.icanhazip.com)\n" +
`curl -X PUT https://hexname.com/api/v1/ddns/ipv4/[YOUR_TOKEN_HERE]/$IP`;
navigator.clipboard.writeText(tokenScript);
copied = true;
let btn = document.getElementById("copy-btn")
btn?.classList.add("swap-active");
clearTimeout(resetTimer);
resetTimer = setTimeout(() => {
copied = false;
btn?.classList.remove("swap-active");
}, 1000);
}
</script>
<svelte:head>
<title>FAQ | HexName - Free, uncomplicated DNS management</title>
<meta property="og:title" content="FAQ | HexName - Free, uncomplicated DNS management">
<meta name="twitter:title" content="FAQ | HexName - Free, uncomplicated DNS management">
<meta name="description" content="Get answers for the most commonly asked questions about DNS/DynDNS/our services - so you can focus on what truly matters.">
<meta property="og:description" content="Get answers for the most commonly asked questions about DNS/DynDNS/our services - so you can focus on what truly matters.">
<meta name="twitter:description" content="Get answers for the most commonly asked questions about DNS/DynDNS/our services - so you can focus on what truly matters.">
<meta name="robots" content="index, follow">
</svelte:head>
<div class="flex flex-col items-center">
<div class="max-w-4xl m-4">
<div class="hero bg-base-200"> <div class="hero bg-base-200">
<div class="hero-content flex-col lg:flex-row-reverse"> <div class="hero-content flex-col sm:flex-row">
<div class="mockup-code w-110"> <div class="w-full">
<h1 class="text-3xl font-bold">Frequently asked questions</h1>
<div class="flex flex-col sm:flex-row items-center justify-center">
<div class="py-6 leading-8">
Find some of HexName's most frequently asked questions and answers about our services, security, getting started, and support.
</div>
<div class="mockup-code max-w-60 min-w-60 mx-4 not-sm:mb-6">
<pre data-prefix="$"><code>Question?</code></pre> <pre data-prefix="$"><code>Question?</code></pre>
<pre data-prefix=">" class="text-warning"><code>Answering...</code></pre> <pre data-prefix=">" class="text-warning"><code>Answering...</code></pre>
<pre data-prefix=">" class="text-success"><code>Done!</code></pre> <pre data-prefix=">" class="text-success"><code>Done!</code></pre>
</div> </div>
<div>
<h1 class="text-3xl font-bold">Frequently asked questions</h1>
<div class="py-6">
Find some of HexName's most frequently asked questions and answers about our services, security, getting started, and support.
</div> </div>
<a href="/register" class="btn btn-primary w-40">Get started</a> <a href="/register" class="btn btn-primary w-full sm:w-40">Get started</a>
</div> </div>
</div> </div>
</div> </div>
@ -58,6 +96,37 @@
</div> </div>
<div class="collapse collapse-arrow bg-base-200 border border-base-300">
<input type="radio"/>
<div class="collapse-title font-semibold">How do I use my DDNS token to update my A/AAAA record?</div>
<div class="collapse-content text-sm">
<div class="p-2">
To update your A/AAAA record using the token, you have to make an HTTP PUT request to the following URL: <code>https://hexname.com/api/v1/ddns/ipv4/[TOKEN]/[NEW_IP]</code>
<p></p>
Here is a basic Bash script you can set to periodically update your IP:
<div class="mockup-code my-4 relative bg-base-300">
<label id="copy-btn" class="btn btn-circle swap swap-rotate absolute top-2 right-2">
<input type="checkbox" bind:checked={copied} onclick={(e) => {e.preventDefault(); copyToken();}}/>
<svg class="size-6 swap-off" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M15.666 3.888A2.25 2.25 0 0 0 13.5 2.25h-3c-1.03 0-1.9.693-2.166 1.638m7.332 0c.055.194.084.4.084.612v0a.75.75 0 0 1-.75.75H9a.75.75 0 0 1-.75-.75v0c0-.212.03-.418.084-.612m7.332 0c.646.049 1.288.11 1.927.184 1.1.128 1.907 1.077 1.907 2.185V19.5a2.25 2.25 0 0 1-2.25 2.25H6.75A2.25 2.25 0 0 1 4.5 19.5V6.257c0-1.108.806-2.057 1.907-2.185a48.208 48.208 0 0 1 1.927-.184"/></svg>
<svg class="size-6 swap-on" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="m4.5 12.75 6 6 9-13.5"/></svg>
</label>
<div class="overflow-x-auto p-2">
<pre><code>#!/bin/bash</code></pre>
<pre><code>IP=$(curl -s http://ipv4.icanhazip.com)</code></pre>
<pre><code>curl -X PUT https://hexname.com/api/v1/ddns/ipv4/[YOUR_TOKEN_HERE]/$IP</code></pre>
</div>
</div>
The second line uses a public API to fetch your current IP.
The third line updates the record with the new IP using your token.
<p></p>
To update your AAAA record with your IPv6 address, replace <code>ipv4</code> in the script with <code>ipv6</code> in both places.
</div>
</div>
</div>
<div class="collapse collapse-arrow bg-base-200 border border-base-300"> <div class="collapse collapse-arrow bg-base-200 border border-base-300">
<input type="radio"/> <input type="radio"/>
<div class="collapse-title font-semibold">Is this service really free?</div> <div class="collapse-title font-semibold">Is this service really free?</div>

View file

@ -3,6 +3,7 @@
import ErrorPopup from "$lib/ErrorPopup.svelte"; import ErrorPopup from "$lib/ErrorPopup.svelte";
let email = ''; let email = '';
let emailSent = $state(false);
let errorMessage: string | null = $state(null); let errorMessage: string | null = $state(null);
async function handleSubmit(e: SubmitEvent) { async function handleSubmit(e: SubmitEvent) {
@ -23,14 +24,30 @@
return; return;
} }
alert(data.msg || 'Success!'); // TODO emailSent = true;
} catch (err: any) { } catch (err: any) {
errorMessage = err?.msg || "Network error"; errorMessage = err?.msg || "Network error";
} }
} }
</script> </script>
<div class="flex flex-col items-center justify-center min-h-full"> <svelte:head>
<title>Reset your password | HexName - Free, uncomplicated DNS management</title>
<meta property="og:title" content="Reset your password | HexName - Free, uncomplicated DNS management">
<meta name="twitter:title" content="Reset your password | HexName - Free, uncomplicated DNS management">
<meta name="description" content="Register our premium domains and manage DNS and DynDNS - so you can focus on what truly matters.">
<meta property="og:description" content="Register our premium domains and manage DNS and DynDNS - so you can focus on what truly matters.">
<meta name="twitter:description" content="Register our premium domains and manage DNS and DynDNS - so you can focus on what truly matters.">
<meta name="robots" content="index, follow">
</svelte:head>
{#if emailSent}
<div class="flex flex-col items-center justify-center w-full my-80">
<h2 class="text-2xl text-primary-content">Email sent!</h2>
<h3 class="text-xl text-primary-content">Please check <a href="mailto:" class="link link-primary">your inbox</a> to update your password.</h3>
</div>
{:else}
<div class="flex flex-col items-center justify-center w-full my-48.5">
<form <form
class="formset bg-base-200 border-base-300 rounded-box w-xs border p-4 z-1 translate-y-2" class="formset bg-base-200 border-base-300 rounded-box w-xs border p-4 z-1 translate-y-2"
onsubmit={handleSubmit}> onsubmit={handleSubmit}>
@ -42,7 +59,7 @@
</div> </div>
<button class="btn btn-primary w-full mt-2 mb-3" type="submit">Submit</button> <button class="btn btn-primary w-full mt-2 mb-3" type="submit">Submit</button>
<div role="alert" class="alert p-0 flex flex-column justify-center"> <div role="alert" class="alert p-0 flex flex-column justify-center">
<svg class="stroke-info h-4 w-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg> <svg class="stroke-info h-4 w-4" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
<span class="mr-auto text-xs text-info">An email will only be sent if the account exists</span> <span class="mr-auto text-xs text-info">An email will only be sent if the account exists</span>
</div> </div>
</form> </form>
@ -50,3 +67,4 @@
<ErrorPopup {errorMessage} /> <ErrorPopup {errorMessage} />
</div> </div>
</div> </div>
{/if}

View file

@ -7,17 +7,54 @@
default: true; default: true;
prefersdark: true; prefersdark: true;
color-scheme: "dark"; color-scheme: "dark";
--color-base-100: oklch(25.33% 0.016 252.42); --color-font: oklch(93% 0.032 255.585);
--color-base-200: oklch(23.26% 0.014 253.1); --color-base-100: #1a1a1c;
--color-base-300: oklch(21.15% 0.012 254.09); --color-base-200: #101012;
--color-base-300: #000000;
--color-base-content: oklch(92% 0.013 255.508); --color-base-content: oklch(92% 0.013 255.508);
--color-primary: oklch(48% 0.243 264.376); --color-primary: oklch(48% 0.243 264.376);
--color-primary-content: oklch(93% 0.032 255.585); --color-primary-content: oklch(93% 0.032 255.585);
--color-secondary: oklch(65% 0.241 354.308); --color-secondary: #ff0076;
--color-secondary-content: oklch(94% 0.028 342.258); --color-secondary-content: oklch(94% 0.028 342.258);
--color-accent: oklch(77% 0.152 181.912); --color-accent: oklch(77% 0.152 181.912);
--color-accent-content: oklch(38% 0.063 188.416); --color-accent-content: oklch(38% 0.063 188.416);
--color-neutral: oklch(14% 0.005 285.823); --color-neutral: oklch(14% 0.005 285.823);
--color-neutral-content: oklch(93% 0.032 255.585);
--color-info: oklch(74% 0.16 232.661);
--color-info-content: oklch(29% 0.066 243.157);
--color-success: oklch(79% 0.209 151.711);
--color-success-content: oklch(39% 0.095 152.535);
--color-warning: oklch(90% 0.182 98.111);
--color-warning-content: oklch(42% 0.095 57.708);
--color-error: oklch(64% 0.246 16.439);
--color-error-content: oklch(27% 0.105 12.094);
--radius-selector: 0.5rem;
--radius-field: 0.25rem;
--radius-box: 0.5rem;
--size-selector: 0.25rem;
--size-field: 0.25rem;
--border: 1px;
--depth: 0;
--noise: 0;
}
@plugin "daisyui/theme" {
name: "light";
default: false;
prefersdark: false;
color-scheme: "light";
--color-font: oklch(14% 0.005 285.823);
--color-base-100: oklch(100% 0 0);
--color-base-200: oklch(98% 0 0);
--color-base-300: oklch(95% 0 0);
--color-base-content: oklch(92% 0.013 255.508);
--color-primary: oklch(48% 0.243 264.376);
--color-primary-content: oklch(93% 0.032 255.585);
--color-secondary: #ff0076;
--color-secondary-content: oklch(94% 0.028 342.258);
--color-accent: oklch(77% 0.152 181.912);
--color-accent-content: oklch(38% 0.063 188.416); --color-neutral: oklch(14% 0.005 285.823);
--color-neutral-content: oklch(92% 0.004 286.32); --color-neutral-content: oklch(92% 0.004 286.32);
--color-info: oklch(74% 0.16 232.661); --color-info: oklch(74% 0.16 232.661);
--color-info-content: oklch(29% 0.066 243.157); --color-info-content: oklch(29% 0.066 243.157);
@ -61,4 +98,12 @@
transform: translateY(0); transform: translateY(0);
} }
} }
--animate-terminal-blink: blink 1.5s step-start infinite;
@keyframes blink {
50% {
opacity: 0;
} }
}
}

View file

@ -2,7 +2,7 @@
import { goto } from "$app/navigation"; import { goto } from "$app/navigation";
import { PUBLIC_BACKEND_API_HOST } from "$env/static/public"; import { PUBLIC_BACKEND_API_HOST } from "$env/static/public";
import ErrorPopup from "$lib/ErrorPopup.svelte"; import ErrorPopup from "$lib/ErrorPopup.svelte";
import { auth } from "$lib/auth.svelte"; import { auth, initUserAuthStatus } from "$lib/auth.svelte";
import { getSubdomains } from '$lib/domains.svelte'; import { getSubdomains } from '$lib/domains.svelte';
let email = ''; let email = '';
@ -30,6 +30,7 @@
getSubdomains(); getSubdomains();
auth.isAuthenticated = true; auth.isAuthenticated = true;
initUserAuthStatus(); // To get the email
goto("/dashboard"); goto("/dashboard");
} catch (err: any) { } catch (err: any) {
errorMessage = err?.msg || "Network error"; errorMessage = err?.msg || "Network error";
@ -38,7 +39,17 @@
} }
</script> </script>
<div class="flex flex-col items-center justify-center min-h-full"> <svelte:head>
<title>Log in | HexName - Free, uncomplicated DNS management</title>
<meta property="og:title" content="Log in | HexName - Free, uncomplicated DNS management">
<meta name="twitter:title" content="Log in | HexName - Free, uncomplicated DNS management">
<meta name="description" content="Register our premium domains and manage DNS and DynDNS - so you can focus on what truly matters.">
<meta property="og:description" content="Register our premium domains and manage DNS and DynDNS - so you can focus on what truly matters.">
<meta name="twitter:description" content="Register our premium domains and manage DNS and DynDNS - so you can focus on what truly matters.">
<meta name="robots" content="index, follow">
</svelte:head>
<div class="flex flex-col items-center justify-center w-full my-40">
<form <form
class="formset bg-base-200 border-base-300 rounded-box w-xs border p-4 z-1 translate-y-2" class="formset bg-base-200 border-base-300 rounded-box w-xs border p-4 z-1 translate-y-2"
onsubmit={handleSubmit}> onsubmit={handleSubmit}>
@ -48,14 +59,14 @@
<input class="input validator" id="email" name="email" autocomplete="email" type="email" bind:value={email} placeholder="you@example.com" required/> <input class="input validator" id="email" name="email" autocomplete="email" type="email" bind:value={email} placeholder="you@example.com" required/>
<div class="align-right validator-hint mt-1">Enter valid email address</div> <div class="align-right validator-hint mt-1">Enter valid email address</div>
</div> </div>
<div class="mt-2 mb-2"> <div class="my-2">
<label class="text-base-content" for="password">Password</label> <label class="text-base-content" for="password">Password</label>
<input class="input validator" minlength="12" title="The password must be at least 12 characters long" id="password" name="password" autocomplete="current-password" type="password" bind:value={password} placeholder="****************" required/> <input class="input validator" minlength="12" title="The password must be at least 12 characters long" id="password" name="password" autocomplete="current-password" type="password" bind:value={password} placeholder="****************" required/>
<p class="validator-hint">The password must be at least 12 characters long</p> <p class="validator-hint">The password must be at least 12 characters long</p>
</div> </div>
<div class="flex flex-row justify-between mt-2"> <div class="flex flex-row justify-between mt-2">
<button class="btn btn-primary w-35" type="submit">Login</button> <button class="btn btn-primary w-35" type="submit">Login</button>
<a class="mt-auto mb-auto text-xs text-primary-content" type="submit" href="/forgot-password">Forgot password</a> <a class="my-auto text-xs text-primary-content" type="submit" href="/forgot-password">Forgot password</a>
</div> </div>
</form> </form>
<div class="mt-3 h-12 flex items-center"> <div class="mt-3 h-12 flex items-center">

View file

@ -2,7 +2,7 @@
import { goto } from "$app/navigation"; import { goto } from "$app/navigation";
import { PUBLIC_BACKEND_API_HOST } from "$env/static/public"; import { PUBLIC_BACKEND_API_HOST } from "$env/static/public";
import { auth } from "$lib/auth.svelte"; import { auth } from "$lib/auth.svelte";
import { clearSubdomains, getSubdomains } from '$lib/domains.svelte'; import { clearSubdomains } from '$lib/domains.svelte';
import { onMount } from "svelte"; import { onMount } from "svelte";
onMount(async () => { onMount(async () => {
@ -19,9 +19,18 @@
return; return;
} }
// Clear subdomains
clearSubdomains(); clearSubdomains();
auth.isAuthenticated = false; auth.isAuthenticated = false;
goto("/redirect/login"); goto("/login");
}); });
</script> </script>
<svelte:head>
<title>HexName - Free, uncomplicated DNS management</title>
<meta property="og:title" content="HexName - Free, uncomplicated DNS management">
<meta name="twitter:title" content="HexName - Free, uncomplicated DNS management">
<meta name="description" content="Register our premium domains and manage DNS and DynDNS - so you can focus on what truly matters.">
<meta property="og:description" content="Register our premium domains and manage DNS and DynDNS - so you can focus on what truly matters.">
<meta name="twitter:description" content="Register our premium domains and manage DNS and DynDNS - so you can focus on what truly matters.">
<meta name="robots" content="noindex, nofollow">
</svelte:head>

View file

@ -0,0 +1,374 @@
<svelte:head>
<title>HexName - Free, uncomplicated DNS management</title>
<meta property="og:title" content="HexName - Free, uncomplicated DNS management">
<meta name="twitter:title" content="HexName - Free, uncomplicated DNS management">
<meta name="description" content="Register our premium domains and manage DNS and DynDNS - so you can focus on what truly matters.">
<meta property="og:description" content="Register our premium domains and manage DNS and DynDNS - so you can focus on what truly matters.">
<meta name="twitter:description" content="Register our premium domains and manage DNS and DynDNS - so you can focus on what truly matters.">
<meta name="robots" content="noindex, nofollow">
</svelte:head>
<div class="text-primary-content max-w-7/9 sm:max-w-2/3 m-auto">
<div class="m-8">
<h1 class="text-4xl">Privacy policy</h1>
<p>Last updated January 09, 2026</p>
<hr>
</div>
<p>This Privacy Notice for HexName ( " <strong>we</strong> ," " <strong>us</strong> ," or " <strong>our</strong> " ), describes how and why we might access, collect, store, use, and/or share ( " <strong>process</strong> " ) your personal information when you use our services ( " <strong>Services</strong> " ), including when you:</p>
<ul>
<li>Visit our website at hexname.com or any website of ours that links to this Privacy Notice</li>
</ul>
<ul>
<li>Engage with us in other related ways, including any marketing or events</li>
</ul>
<p><strong>Questions or concerns? </strong> Reading this Privacy Notice will help you understand your privacy rights and choices. We are responsible for making decisions about how your personal information is processed. If you do not agree with our policies and practices, please do not use our Services. If you still have any questions or concerns, please contact us at <a class="link text-accent italic" href="mailto:privacy@hexname.com">privacy@hexname.com</a> .</p>
<h2 class="text-2xl text-secondary p-4 font-bold">SUMMARY OF KEY POINTS</h2>
<p><strong>This summary provides key points from our Privacy Notice, but you can find out more details about any of these topics by clicking the link following each key point or by using our </strong> <a class="link text-accent italic" href="#toc"><strong>table of contents</strong></a> <strong> below to find the section you are looking for.</strong></p>
<p><strong>What personal information do we process?</strong> When you visit, use, or navigate our Services, we may process personal information depending on how you interact with us and the Services, the choices you make, and the products and features you use. Learn more about <a class="link text-accent italic" href="#personalinfo">personal information you disclose to us</a> .</p>
<p><strong>Do we process any sensitive personal information? </strong> Some of the information may be considered "special" or "sensitive" in certain jurisdictions, for example your racial or ethnic origins, sexual orientation, and religious beliefs. We do not process sensitive personal information.</p>
<p><strong>Do we collect any information from third parties?</strong> We do not collect any information from third parties.</p>
<p><strong>How do we process your information?</strong> We process your information to provide, improve, and administer our Services, communicate with you, for security and fraud prevention, and to comply with law. We may also process your information for other purposes with your consent. We process your information only when we have a valid legal reason to do so. Learn more about <a class="link text-accent italic" href="#infouse">how we process your information</a> .</p>
<p><strong>In what situations and with which parties do we share personal information?</strong> We may share information in specific situations and with specific third parties. Learn more about <a class="link text-accent italic" href="#whoshare">when and with whom we share your personal information</a> .</p>
<p><strong>How do we keep your information safe?</strong> We have adequate organizational and technical processes and procedures in place to protect your personal information. However, no electronic transmission over the internet or information storage technology can be guaranteed to be 100% secure, so we cannot promise or guarantee that hackers, cybercriminals, or other unauthorized third parties will not be able to defeat our security and improperly collect, access, steal, or modify your information. Learn more about <a class="link text-accent italic" href="#infosafe">how we keep your information safe</a> .</p>
<p><strong>What are your rights?</strong> Depending on where you are located geographically, the applicable privacy law may mean you have certain rights regarding your personal information. Learn more about <a class="link text-accent italic" href="#privacyrights">your privacy rights</a> .</p>
<p><strong>How do you exercise your rights?</strong> The easiest way to exercise your rights is by writing us an email.</p>
<p>Want to learn more about what we do with any information we collect? <a class="link text-accent italic" href="#toc">Review the Privacy Notice in full</a> .</p>
<h2 class="text-2xl text-secondary p-4 font-bold">TABLE OF CONTENTS</h2>
<p><a class="link text-accent italic" href="#infocollect">1. WHAT INFORMATION DO WE COLLECT?</a></p>
<p><a class="link text-accent italic" href="#infouse">2. HOW DO WE PROCESS YOUR INFORMATION?</a></p>
<p><a class="link text-accent italic" href="#legalbases">3. WHAT LEGAL BASES DO WE RELY ON TO PROCESS YOUR PERSONAL INFORMATION?</a></p>
<p><a class="link text-accent italic" href="#whoshare">4. WHEN AND WITH WHOM DO WE SHARE YOUR PERSONAL INFORMATION?</a></p>
<p><a class="link text-accent italic" href="#inforetain">5. HOW LONG DO WE KEEP YOUR INFORMATION?</a></p>
<p><a class="link text-accent italic" href="#infosafe">6. HOW DO WE KEEP YOUR INFORMATION SAFE?</a></p>
<p><a class="link text-accent italic" href="#infominors">7. DO WE COLLECT INFORMATION FROM MINORS?</a></p>
<p><a class="link text-accent italic" href="#privacyrights">8. WHAT ARE YOUR PRIVACY RIGHTS?</a></p>
<p><a class="link text-accent italic" href="#DNT">9. CONTROLS FOR DO-NOT-TRACK FEATURES</a></p>
<p><a class="link text-accent italic" href="#uslaws">10. DO UNITED STATES RESIDENTS HAVE SPECIFIC PRIVACY RIGHTS?</a></p>
<p><a class="link text-accent italic" href="#policyupdates">11. DO WE MAKE UPDATES TO THIS NOTICE?</a></p>
<p><a class="link text-accent italic" href="#contact">12. HOW CAN YOU CONTACT US ABOUT THIS NOTICE?</a></p>
<p><a class="link text-accent italic" href="#request">13. HOW CAN YOU REVIEW, UPDATE, OR DELETE THE DATA WE COLLECT FROM YOU?</a></p>
<h2 class="text-2xl text-secondary p-4 font-bold">1. WHAT INFORMATION DO WE COLLECT?</h2>
<h3 class="text-xl text-secondary p-4 font-bold">Personal information you disclose to us</h3><strong>In Short:</strong> We collect personal information that you provide to us.
<p>We collect personal information that you voluntarily provide to us when you register on the Services, express an interest in obtaining information about us or our products and Services, when you participate in activities on the Services, or otherwise when you contact us.</p>
<p><strong>Personal Information Provided by You.</strong> The personal information that we collect depends on the context of your interactions with us and the Services, the choices you make, and the products and features you use. The personal information we collect may include the following:</p>
<ul>
<li>email addresses</li>
</ul>
<ul>
<li>passwords</li>
</ul>
<p><strong>Sensitive Information.</strong> We do not process sensitive information.</p>
<p>All personal information that you provide to us must be true, complete, and accurate, and you must notify us of any changes to such personal information.</p>
<h2 class="text-2xl text-secondary p-4 font-bold">2. HOW DO WE PROCESS YOUR INFORMATION?</h2><strong>In Short: </strong> We process your information to provide, improve, and administer our Services, communicate with you, for security and fraud prevention, and to comply with law. We process the personal information for the following purposes listed below. We may also process your information for other purposes only with your prior explicit consent.
<p><strong>We process your personal information for a variety of reasons, depending on how you interact with our Services, including:</strong></p>
<ul>
<li><strong>To facilitate account creation and authentication and otherwise manage user accounts. </strong> We may process your information so you can create and log in to your account, as well as keep your account in working order.</li>
</ul>
<ul>
<li><strong>To deliver and facilitate delivery of services to the user. </strong> We may process your information to provide you with the requested service.</li>
</ul>
<ul>
<li><strong>To save or protect an individual's vital interest.</strong> We may process your information when necessary to save or protect an individual's vital interest, such as to prevent harm.</li>
</ul>
<h2 class="text-2xl text-secondary p-4 font-bold">3. WHAT LEGAL BASES DO WE RELY ON TO PROCESS YOUR INFORMATION?</h2><strong>In Short: </strong> We only process your personal information when we believe it is necessary and we have a valid legal reason (i.e. , legal basis) to do so under applicable law, like with your consent, to comply with laws, to provide you with services to enter into or fulfill our contractual obligations, to protect your rights, or to fulfill our legitimate business interests.
<p><strong>If you are located in the EU or UK, this section applies to you.</strong></p>
<p>The General Data Protection Regulation (GDPR) and UK GDPR require us to explain the valid legal bases we rely on in order to process your personal information. As such, we may rely on the following legal bases to process your personal information:</p>
<ul>
<li>
<strong>Consent. </strong> We may process your information if you have given us permission (i.e. , consent) to use your personal information for a specific purpose. You can withdraw your consent at any time. Learn more about <a class="link text-accent italic" href="#withdrawconsent">withdrawing your consent</a> .
</li>
</ul>
<ul>
<li><strong>Performance of a Contract.</strong> We may process your personal information when we believe it is necessary to fulfill our contractual obligations to you, including providing our Services or at your request prior to entering into a contract with you.</li>
</ul>
<ul>
<li><strong>Legal Obligations.</strong> We may process your information where we believe it is necessary for compliance with our legal obligations, such as to cooperate with a law enforcement body or regulatory agency, exercise or defend our legal rights, or disclose your information as evidence in litigation in which we are involved.</li>
</ul>
<ul>
<li><strong>Vital Interests.</strong> We may process your information where we believe it is necessary to protect your vital interests or the vital interests of a third party, such as situations involving potential threats to the safety of any person.</li>
</ul>
<p><strong>If you are located in Canada, this section applies to you.</strong></p>
<p>We may process your information if you have given us specific permission (i.e. , express consent) to use your personal information for a specific purpose, or in situations where your permission can be inferred (i.e. , implied consent). You can <a class="link text-accent italic" href="#withdrawconsent">withdraw your consent</a> at any time.</p>
<p>In some exceptional cases, we may be legally permitted under applicable law to process your information without your consent, including, for example:</p>
<ul>
<li>If collection is clearly in the interests of an individual and consent cannot be obtained in a timely way</li>
</ul>
<ul>
<li>For investigations and fraud detection and prevention</li>
</ul>
<ul>
<li>For business transactions provided certain conditions are met</li>
</ul>
<ul>
<li>If it is contained in a witness statement and the collection is necessary to assess, process, or settle an insurance claim</li>
</ul>
<ul>
<li>For identifying injured, ill, or deceased persons and communicating with next of kin</li>
</ul>
<ul>
<li>If we have reasonable grounds to believe an individual has been, is, or may be victim of financial abuse</li>
</ul>
<ul>
<li>If it is reasonable to expect collection and use with consent would compromise the availability or the accuracy of the information and the collection is reasonable for purposes related to investigating a breach of an agreement or a contravention of the laws of Canada or a province</li>
</ul>
<ul>
<li>If disclosure is required to comply with a subpoena, warrant, court order, or rules of the court relating to the production of records</li>
</ul>
<ul>
<li>If it was produced by an individual in the course of their employment, business, or profession and the collection is consistent with the purposes for which the information was produced</li>
</ul>
<ul>
<li>If the collection is solely for journalistic, artistic, or literary purposes</li>
</ul>
<ul>
<li>If the information is publicly available and is specified by the regulations</li>
</ul>
<ul>
<li>We may disclose de-identified information for approved research or statistics projects, subject to ethics oversight and confidentiality commitments</li>
</ul>
<h2 class="text-2xl text-secondary p-4 font-bold">4. WHEN AND WITH WHOM DO WE SHARE YOUR PERSONAL INFORMATION?</h2><strong>In Short:</strong> We may share information in specific situations described in this section and/or with the following third parties.
<p>We may need to share your personal information in the following situations:</p>
<ul>
<li><strong>Business Transfers.</strong> We may share or transfer your information in connection with, or during negotiations of, any merger, sale of company assets, financing, or acquisition of all or a portion of our business to another company.</li>
</ul>
<h2 class="text-2xl text-secondary p-4 font-bold">5. HOW LONG DO WE KEEP YOUR INFORMATION?</h2><strong>In Short: </strong> We keep your information for as long as necessary to fulfill the purposes outlined in this Privacy Notice unless otherwise required by law.
<p>We will only keep your personal information for as long as it is necessary for the purposes set out in this Privacy Notice, unless a longer retention period is required or permitted by law (such as tax, accounting, or other legal requirements). No purpose in this notice will require us keeping your personal information for longer than the period of time in which users have an account with us .</p>
<p>When we have no ongoing legitimate business need to process your personal information, we will either delete or anonymize such information, or, if this is not possible (for example, because your personal information has been stored in backup archives), then we will securely store your personal information and isolate it from any further processing until deletion is possible.</p>
<h2 class="text-2xl text-secondary p-4 font-bold">6. HOW DO WE KEEP YOUR INFORMATION SAFE?</h2><strong>In Short: </strong> We aim to protect your personal information through a system of organizational and technical security measures.
<p>We have implemented appropriate and reasonable technical and organizational security measures designed to protect the security of any personal information we process. However, despite our safeguards and efforts to secure your information, no electronic transmission over the Internet or information storage technology can be guaranteed to be 100% secure, so we cannot promise or guarantee that hackers, cybercriminals, or other unauthorized third parties will not be able to defeat our security and improperly collect, access, steal, or modify your information. Although we will do our best to protect your personal information, transmission of personal information to and from our Services is at your own risk. You should only access the Services within a secure environment.</p>
<h2 class="text-2xl text-secondary p-4 font-bold">7. DO WE COLLECT INFORMATION FROM MINORS?</h2><strong>In Short:</strong> We do not knowingly collect data from or market to children under 18 years of age or the equivalent age as specified by law in your jurisdiction .
<p>We do not knowingly collect, solicit data from, or market to children under 18 years of age or the equivalent age as specified by law in your jurisdiction , nor do we knowingly sell such personal information. By using the Services, you represent that you are at least 18 or the equivalent age as specified by law in your jurisdiction or that you are the parent or guardian of such a minor and consent to such minor dependent's use of the Services. If we learn that personal information from users less than 18 years of age or the equivalent age as specified by law in your jurisdiction has been collected, we will deactivate the account and take reasonable measures to promptly delete such data from our records. If you become aware of any data we may have collected from children under age 18 or the equivalent age as specified by law in your jurisdiction , please contact us at <a class="link text-accent italic" href="mailto:privacy@hexname.com">privacy@hexname.com</a> .</p>
<h2 class="text-2xl text-secondary p-4 font-bold">8. WHAT ARE YOUR PRIVACY RIGHTS?</h2><strong>In Short:</strong> Depending on your state of residence in the US or in some regions, such as the European Economic Area (EEA), United Kingdom (UK), Switzerland, and Canada , you have rights that allow you greater access to and control over your personal information. You may review, change, or terminate your account at any time, depending on your country, province, or state of residence.
<p>In some regions (like the EEA, UK, Switzerland, and Canada ), you have certain rights under applicable data protection laws. These may include the right (i) to request access and obtain a copy of your personal information, (ii) to request rectification or erasure; (iii) to restrict the processing of your personal information; (iv) if applicable, to data portability; and (v) not to be subject to automated decision-making. If a decision that produces legal or similarly significant effects is made solely by automated means, we will inform you, explain the main factors, and offer a simple way to request human review. In certain circumstances, you may also have the right to object to the processing of your personal information. You can make such a request by contacting us by using the contact details provided in the section " <a class="link text-accent italic" href="#contact">HOW CAN YOU CONTACT US ABOUT THIS NOTICE?</a> " below.</p>
<p>We will consider and act upon any request in accordance with applicable data protection laws.</p>
<p>If you are located in the EEA or UK and you believe we are unlawfully processing your personal information, you also have the right to complain to your <a class="link text-accent italic" href="https://ec.europa.eu/justice/data-protection/bodies/authorities/index_en.htm">Member State data protection authority</a> or <a href="https://ico.org.uk/make-a-complaint/data-protection-complaints/data-protection-complaints/">UK data protection authority</a> .</p>
<p>If you are located in Switzerland, you may contact the <a class="link text-accent italic" href="https://www.edoeb.admin.ch/edoeb/en/home.html">Federal Data Protection and Information Commissioner</a> .</p>
<p><strong>Withdrawing your consent:</strong> If we are relying on your consent to process your personal information, which may be express and/or implied consent depending on the applicable law, you have the right to withdraw your consent at any time. You can withdraw your consent at any time by contacting us by using the contact details provided in the section " <a class="link text-accent italic" href="#contact">HOW CAN YOU CONTACT US ABOUT THIS NOTICE?</a> " below .</p>
<p>However, please note that this will not affect the lawfulness of the processing before its withdrawal nor, when applicable law allows, will it affect the processing of your personal information conducted in reliance on lawful processing grounds other than consent.</p>
<h3 class="text-xl text-secondary p-4 font-bold">Account Information</h3>If you would at any time like to review or change the information in your account or terminate your account, you can:
<ul>
<li>Log in to your account settings and update your user account.</li>
</ul>
<p>Upon your request to terminate your account, we will deactivate or delete your account and information from our active databases. However, we may retain some information in our files to prevent fraud, troubleshoot problems, assist with any investigations, enforce our legal terms and/or comply with applicable legal requirements.</p>
<p>If you have questions or comments about your privacy rights, you may email us at <a class="link text-accent italic" href="mailto:privacy@hexname.com">privacy@hexname.com</a> .</p>
<h2 class="text-2xl text-secondary p-4 font-bold">9. CONTROLS FOR DO-NOT-TRACK FEATURES</h2>Most web browsers and some mobile operating systems and mobile applications include a Do-Not-Track ( "DNT" ) feature or setting you can activate to signal your privacy preference not to have data about your online browsing activities monitored and collected. At this stage, no uniform technology standard for recognizing and implementing DNT signals has been finalized . As such, we do not currently respond to DNT browser signals or any other mechanism that automatically communicates your choice not to be tracked online. If a standard for online tracking is adopted that we must follow in the future, we will inform you about that practice in a revised version of this Privacy Notice.
<p>California law requires us to let you know how we respond to web browser DNT signals. Because there currently is not an industry or legal standard for recognizing or honoring DNT signals, we do not respond to them at this time.</p>
<h2 class="text-2xl text-secondary p-4 font-bold">10. DO UNITED STATES RESIDENTS HAVE SPECIFIC PRIVACY RIGHTS?</h2><strong>In Short: </strong> If you are a resident of California, Colorado, Connecticut, Delaware, Florida, Indiana, Iowa, Kentucky, Maryland, Minnesota, Montana, Nebraska, New Hampshire, New Jersey, Oregon, Rhode Island, Tennessee, Texas, Utah, or Virginia , you may have the right to request access to and receive details about the personal information we maintain about you and how we have processed it, correct inaccuracies, get a copy of, or delete your personal information. You may also have the right to withdraw your consent to our processing of your personal information. These rights may be limited in some circumstances by applicable law. More information is provided below.
<h3 class="text-xl text-secondary p-4 font-bold">Categories of Personal Information We Collect</h3>The table below shows the categories of personal information we have collected in the past twelve (12) months. The table includes illustrative examples of each category and does not reflect the personal information we collect from you. For a comprehensive inventory of all personal information we process, please refer to the section " <a class="link text-accent italic" href="#infocollect">WHAT INFORMATION DO WE COLLECT?</a> "
<table>
<thead>
<tr>
<th><strong>Category</strong></th>
<th><strong>Examples</strong></th>
<th><strong>Collected</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td>
<p>A. Identifiers</p>
</td>
<td>
<p>Contact details, such as real name, alias, postal address, telephone or mobile contact number, unique personal identifier, online identifier, Internet Protocol address, email address, and account name</p>
</td>
<td>
<p>NO</p>
</td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td>
<p>B. Personal information as defined in the California Customer Records statute</p>
</td>
<td>
<p>Name, contact information, education, employment, employment history, and financial information</p>
</td>
<td>
<p>NO</p>
</td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td>
<p>C . Protected classification characteristics under state or federal law</p>
</td>
<td>
<p>Gender, age, date of birth, race and ethnicity, national origin, marital status, and other demographic data</p>
</td>
<td>
<p>NO</p>
</td>
</tr>
<tr>
<td>
<p>D . Commercial information</p>
</td>
<td>
<p>Transaction information, purchase history, financial details, and payment information</p>
</td>
<td>
<p>NO</p>
</td>
</tr>
<tr>
<td>
<p>E . Biometric information</p>
</td>
<td>
<p>Fingerprints and voiceprints</p>
</td>
<td>
<p>NO</p>
</td>
</tr>
<tr>
<td>
<p>F . Internet or other similar network activity</p>
</td>
<td>
<p>Browsing history, search history, online behavior , interest data, and interactions with our and other websites, applications, systems, and advertisements</p>
</td>
<td>
<p>NO</p>
</td>
</tr>
<tr>
<td>
<p>G . Geolocation data</p>
</td>
<td>
<p>Device location</p>
</td>
<td>
<p>NO</p>
</td>
</tr>
<tr>
<td>
<p>H . Audio, electronic, sensory, or similar information</p>
</td>
<td>
<p>Images and audio, video or call recordings created in connection with our business activities</p>
</td>
<td>
<p>NO</p>
</td>
</tr>
<tr>
<td>
<p>I . Professional or employment-related information</p>
</td>
<td>
<p>Business contact details in order to provide you our Services at a business level or job title, work history, and professional qualifications if you apply for a job with us</p>
</td>
<td>
<p>NO</p>
</td>
</tr>
<tr>
<td>
<p>J . Education Information</p>
</td>
<td>
<p>Student records and directory information</p>
</td>
<td>
<p>NO</p>
</td>
</tr>
<tr>
<td>
<p>K . Inferences drawn from collected personal information</p>
</td>
<td>
<p>Inferences drawn from any of the collected personal information listed above to create a profile or summary about, for example, an individual's preferences and characteristics</p>
</td>
<td>
<p>NO</p>
</td>
</tr>
<tr>
<td>L . Sensitive personal Information</td>
<td>
<p>NO</p>
</td>
</tr>
</tbody>
</table>
<p>We may also collect other personal information outside of these categories through instances where you interact with us in person, online, or by phone or mail in the context of:</p>
<ul>
<li>Receiving help through our customer support channels;</li>
</ul>
<ul>
<li>Participation in customer surveys or contests; and</li>
</ul>
<ul>
<li>Facilitation in the delivery of our Services and to respond to your inquiries.</li>
</ul>
<h3 class="text-xl text-secondary p-4 font-bold">Sources of Personal Information</h3>Learn more about the sources of personal information we collect in " <a class="link text-accent italic" href="#infocollect">WHAT INFORMATION DO WE COLLECT?</a> "
<h3 class="text-xl text-secondary p-4 font-bold">How We Use and Share Personal Information</h3>Learn more about how we use your personal information in the section, " <a class="link text-accent italic" href="#infouse">HOW DO WE PROCESS YOUR INFORMATION?</a> "
<p><strong>Will your information be shared with anyone else?</strong></p>
<p>We may disclose your personal information with our service providers pursuant to a written contract between us and each service provider. Learn more about how we disclose personal information to in the section, " <a class="link text-accent italic" href="#whoshare">WHEN AND WITH WHOM DO WE SHARE YOUR PERSONAL INFORMATION?</a> "</p>
<p>We may use your personal information for our own business purposes, such as for undertaking internal research for technological development and demonstration. This is not considered to be "selling" of your personal information.</p>
<p>We have not disclosed, sold, or shared any personal information to third parties for a business or commercial purpose in the preceding twelve (12) months. Wewill not sell or share personal information in the future belonging to website visitors, users, and other consumers.</p>
<h3 class="text-xl text-secondary p-4 font-bold">Your Rights</h3>You have rights under certain US state data protection laws. However, these rights are not absolute, and in certain cases, we may decline your request as permitted by law. These rights include:
<ul>
<li><strong>Right to know</strong> whether or not we are processing your personal data</li>
</ul>
<ul>
<li><strong>Right to access </strong> your personal data</li>
</ul>
<ul>
<li><strong>Right to correct </strong> inaccuracies in your personal data</li>
</ul>
<ul>
<li><strong>Right to request</strong> the deletion of your personal data</li>
</ul>
<ul>
<li><strong>Right to obtain a copy </strong> of the personal data you previously shared with us</li>
</ul>
<ul>
<li><strong>Right to non-discrimination</strong> for exercising your rights</li>
</ul>
<ul>
<li><strong>Right to opt out</strong> of the processing of your personal data if it is used for targeted advertising (or sharing as defined under California's privacy law) , the sale of personal data, or profiling in furtherance of decisions that produce legal or similarly significant effects ( "profiling" )</li>
</ul>
<p>Depending upon the state where you live, you may also have the following rights:</p>
<ul>
<li>Right to access the categories of personal data being processed (as permitted by applicable law, including the privacy law in Minnesota)</li>
</ul>
<ul>
<li>Right to obtain a list of the categories of third parties to which we have disclosed personal data (as permitted by applicable law, including the privacy law in California, Delaware, and Maryland )</li>
</ul>
<ul>
<li>Right to obtain a list of specific third parties to which we have disclosed personal data (as permitted by applicable law, including the privacy law in Minnesota and Oregon )</li>
</ul>
<ul>
<li>Right to obtain a list of third parties to which we have sold personal data (as permitted by applicable law, including the privacy law in Connecticut)</li>
</ul>
<ul>
<li>Right to review, understand, question, and depending on where you live, correct how personal data has been profiled (as permitted by applicable law, including the privacy law in Connecticut and Minnesota )</li>
</ul>
<ul>
<li>Right to limit use and disclosure of sensitive personal data (as permitted by applicable law, including the privacy law in California)</li>
</ul>
<ul>
<li>Right to opt out of the collection of sensitive data and personal data collected through the operation of a voice or facial recognition feature (as permitted by applicable law, including the privacy law in Florida)</li>
</ul>
<h3 class="text-xl text-secondary p-4 font-bold">How to Exercise Your Rights</h3>To exercise these rights, you can contact us by emailing us at <a class="link text-accent italic" href="mailto:privacy@hexname.com">privacy@hexname.com</a> .
<p>Under certain US state data protection laws, you can designate an authorized agent to make a request on your behalf. We may deny a request from an authorized agent that does not submit proof that they have been validly authorized to act on your behalf in accordance with applicable laws.</p>
<h3 class="text-xl text-secondary p-4 font-bold">Request Verification</h3>Upon receiving your request, we will need to verify your identity to determine you are the same person about whom we have the information in our system. We will only use personal information provided in your request to verify your identity or authority to make the request. However, if we cannot verify your identity from the information already maintained by us, we may request that you provide additional information for the purposes of verifying your identity and for security or fraud-prevention purposes.
<p>If you submit the request through an authorized agent, we may need to collect additional information to verify your identity before processing your request and the agent will need to provide a written and signed permission from you to submit such request on your behalf.</p>
<h3 class="text-xl text-secondary p-4 font-bold">Appeals</h3>Under certain US state data protection laws, if we decline to take action regarding your request, you may appeal our decision by emailing us at <a class="link text-accent italic" href="mailto:privacy@hexname.com">privacy@hexname.com</a> . We will inform you in writing of any action taken or not taken in response to the appeal, including a written explanation of the reasons for the decisions. If your appeal is denied, you may submit a complaint to your state attorney general.
<h3 class="text-xl text-secondary p-4 font-bold">California "Shine The Light" Law</h3>California Civil Code Section 1798.83, also known as the "Shine The Light" law, permits our users who are California residents to request and obtain from us, once a year and free of charge, information about categories of personal information (if any) we disclosed to third parties for direct marketing purposes and the names and addresses of all third parties with which we shared personal information in the immediately preceding calendar year. If you are a California resident and would like to make such a request, please submit your request in writing to us by using the contact details provided in the section " <a class="link text-accent italic" href="#contact">HOW CAN YOU CONTACT US ABOUT THIS NOTICE?</a> "
<h2 class="text-2xl text-secondary p-4 font-bold">11. DO WE MAKE UPDATES TO THIS NOTICE?</h2><strong>In Short: </strong> Yes, we will update this notice as necessary to stay compliant with relevant laws.
<p>We may update this Privacy Notice from time to time. The updated version will be indicated by an updated "Revised" date at the top of this Privacy Notice. If we make material changes to this Privacy Notice, we may notify you either by prominently posting a notice of such changes or by directly sending you a notification. We encourage you to review this Privacy Notice frequently to be informed of how we are protecting your information.</p>
<h2 class="text-2xl text-secondary p-4 font-bold">12. HOW CAN YOU CONTACT US ABOUT THIS NOTICE?</h2>If you have questions or comments about this notice, you may email us at <a class="link text-accent italic" href="mailto:privacy@hexname.com">privacy@hexname.com</a>
<h2 class="text-2xl text-secondary p-4 font-bold">13. HOW CAN YOU REVIEW, UPDATE, OR DELETE THE DATA WE COLLECT FROM YOU?</h2>Based on the applicable laws of your country or state of residence in the US , you may have the right to request access to the personal information we collect from you, details about how we have processed it, correct inaccuracies, or delete your personal information. You may also have the right to withdraw your consent to our processing of your personal information. These rights may be limited in some circumstances by applicable law. To request to review, update, or delete your personal information, please email us at privacy@hexname.com.
</div>

View file

@ -1 +0,0 @@
export const ssr = false;

View file

@ -1,15 +0,0 @@
<script lang="ts">
import { goto } from '$app/navigation';
import { page } from '$app/state';
let target = page.params.url;
setTimeout(() => {
goto("/" + target);
}, 1500);
</script>
<div class="flex flex-col items-center justify-center min-h-full">
<h2 class="text-4xl text-primary-content">Redirecting you to the {target} page</h2>
<span class="loading loading-dots loading-lg translate-y-3 ml-1"></span>
</div>

View file

@ -1,10 +1,12 @@
<script lang="ts"> <script lang="ts">
import { goto } from "$app/navigation";
import { PUBLIC_BACKEND_API_HOST } from "$env/static/public"; import { PUBLIC_BACKEND_API_HOST } from "$env/static/public";
import ErrorPopup from "$lib/ErrorPopup.svelte"; import ErrorPopup from "$lib/ErrorPopup.svelte";
let email = ''; let email = '';
let password = ''; let password = '';
let errorMessage: string | null = $state(null); let errorMessage: string | null = $state(null);
let emailSent = $state(false);
async function handleSubmit(e: SubmitEvent) { async function handleSubmit(e: SubmitEvent) {
e.preventDefault(); e.preventDefault();
@ -25,7 +27,7 @@
return; return;
} }
alert(data.msg || 'Success!'); // TODO emailSent = true;
} catch (err: any) { } catch (err: any) {
errorMessage = err?.msg || "Network error"; errorMessage = err?.msg || "Network error";
console.log(errorMessage); console.log(errorMessage);
@ -33,30 +35,23 @@
} }
</script> </script>
<!-- <div class="container flex flex-col items-center justify-center mx-auto min-h-screen w-full h-full py-8"> --> <svelte:head>
<!-- <div class="container flex flex-col items-center justify-center"> --> <title>Register | HexName - Free, uncomplicated DNS management</title>
<!-- <div class="absolute h-2/5 pt-auto"> --> <meta property="og:title" content="Register | HexName - Free, uncomplicated DNS management">
<!-- <div class="container flex flex-col items-center justify-center mx-auto min-h-screen py-8"> <meta name="twitter:title" content="Register | HexName - Free, uncomplicated DNS management">
<form <meta name="description" content="Register our premium domains and manage DNS and DynDNS - so you can focus on what truly matters.">
class="formset bg-base-200 border-base-300 rounded-box w-xs border p-4 z-1" <meta property="og:description" content="Register our premium domains and manage DNS and DynDNS - so you can focus on what truly matters.">
onsubmit={handleSubmit}> <meta name="twitter:description" content="Register our premium domains and manage DNS and DynDNS - so you can focus on what truly matters.">
<legend class="fieldset-legend">Create your account</legend> <meta name="robots" content="index, follow">
<div class="mt-4 mb-4"> </svelte:head>
<label class="label" for="email">Email</label>
<input class="input" id="email" name="email" autocomplete="email" type="email" bind:value={email} placeholder="you@example.com" required/>
</div>
<div class="mt-4 mb-4">
<label class="label" for="password">Password</label>
<input class="input" id="password" name="password" autocomplete="new-password" type="password" bind:value={password} placeholder="****************" required/>
</div>
<button class="btn btn-primary w-full mt-2" type="submit">Register</button>
</form>
<div class="flex-wrap">
<ErrorPopup {errorMessage}/>
</div>
</div> -->
<div class="flex flex-col items-center justify-center min-h-full"> {#if emailSent}
<div class="flex flex-col items-center justify-center w-full my-80">
<h2 class="text-2xl text-primary-content">Email sent!</h2>
<h3 class="text-xl text-primary-content">Please check <a href="mailto:" class="link link-primary">your inbox</a> to confirm your account.</h3>
</div>
{:else}
<div class="flex flex-col items-center justify-center w-full my-40">
<form <form
class="formset bg-base-200 border-base-300 rounded-box w-xs border p-4 z-1 translate-y-2" class="formset bg-base-200 border-base-300 rounded-box w-xs border p-4 z-1 translate-y-2"
onsubmit={handleSubmit}> onsubmit={handleSubmit}>
@ -66,7 +61,7 @@
<input class="input validator" id="email" name="email" autocomplete="email" type="email" bind:value={email} placeholder="you@example.com" required/> <input class="input validator" id="email" name="email" autocomplete="email" type="email" bind:value={email} placeholder="you@example.com" required/>
<div class="align-right validator-hint mt-1">Enter valid email address</div> <div class="align-right validator-hint mt-1">Enter valid email address</div>
</div> </div>
<div class="mt-2 mb-2"> <div class="my-2">
<label class="text-primary-content" for="password">Password</label> <label class="text-primary-content" for="password">Password</label>
<input class="input validator" minlength="12" title="The password must be at least 12 characters long" id="password" name="password" autocomplete="current-password" type="password" bind:value={password} placeholder="****************" required/> <input class="input validator" minlength="12" title="The password must be at least 12 characters long" id="password" name="password" autocomplete="current-password" type="password" bind:value={password} placeholder="****************" required/>
<p class="validator-hint">The password must be at least 12 characters long</p> <p class="validator-hint">The password must be at least 12 characters long</p>
@ -77,3 +72,4 @@
<ErrorPopup {errorMessage} /> <ErrorPopup {errorMessage} />
</div> </div>
</div> </div>
{/if}

View file

@ -0,0 +1,146 @@
<svelte:head>
<title>HexName - Free, uncomplicated DNS management</title>
<meta property="og:title" content="HexName - Free, uncomplicated DNS management">
<meta name="twitter:title" content="HexName - Free, uncomplicated DNS management">
<meta name="description" content="Register our premium domains and manage DNS and DynDNS - so you can focus on what truly matters.">
<meta property="og:description" content="Register our premium domains and manage DNS and DynDNS - so you can focus on what truly matters.">
<meta name="twitter:description" content="Register our premium domains and manage DNS and DynDNS - so you can focus on what truly matters.">
<meta name="robots" content="noindex, nofollow">
</svelte:head>
<div class="text-primary-content max-w-7/9 sm:max-w-2/3 m-auto">
<div class="m-8">
<h1 class="text-4xl">Terms of use</h1>
<p>Last updated January 09, 2026</p>
<hr>
</div>
<h2 class="text-2xl text-secondary p-4 font-bold"><strong>AGREEMENT TO OUR LEGAL TERMS</strong></h2>
<p>We are HexName ("<strong>Company</strong>," "<strong>we</strong>," "<strong>us</strong>," "<strong>our</strong>").</p>
<p>We operate, as well as any other related products and services that refer or link to these legal terms (the "<strong>Legal Terms</strong>") (collectively, the "<strong>Services</strong>").</p>
<p>You can contact us by email at <a class="link text-accent italic" href="mailto:privacy@hexname.com">privacy@hexname.com</a></p>
<p>These Legal Terms constitute a legally binding agreement made between you, whether personally or on behalf of an entity ("<strong>you</strong>"), and HexName, concerning your access to and use of the Services. You agree that by accessing the Services, you have read, understood, and agreed to be bound by all of these Legal Terms. IF YOU DO NOT AGREE WITH ALL OF THESE LEGAL TERMS, THEN YOU ARE EXPRESSLY PROHIBITED FROM USING THE SERVICES AND YOU MUST DISCONTINUE USE IMMEDIATELY.</p>
<p>Supplemental terms and conditions or documents that may be posted on the Services from time to time are hereby expressly incorporated herein by reference. We reserve the right, in our sole discretion, to make changes or modifications to these Legal Terms at any time and for any reason. We will alert you about any changes by updating the "Last updated" date of these Legal Terms, and you waive any right to receive specific notice of each such change. It is your responsibility to periodically review these Legal Terms to stay informed of updates. You will be subject to, and will be deemed to have been made aware of and to have accepted, the changes in any revised Legal Terms by your continued use of the Services after the date such revised Legal Terms are posted.</p>
<p>We recommend that you print a copy of these Legal Terms for your records.</p>
<h2 class="text-2xl text-secondary p-4 font-bold"><strong>TABLE OF CONTENTS</strong></h2>
<p><a class="link text-accent italic" href="#services">1. OUR SERVICES</a></p>
<p><a class="link text-accent italic" href="#ip">2. INTELLECTUAL PROPERTY RIGHTS</a></p>
<p><a class="link text-accent italic" href="#userreps">3. USER REPRESENTATIONS</a></p>
<p><a class="link text-accent italic" href="#prohibited">4. PROHIBITED ACTIVITIES</a> </p>
<p><a class="link text-accent italic" href="#ugc">5. USER GENERATED CONTRIBUTIONS</a> </p>
<p><a class="link text-accent italic" href="#license">6. CONTRIBUTION LICENSE</a> </p>
<p><a class="link text-accent italic" href="#sitemanage">7. SERVICES MANAGEMENT</a> </p>
<p><a class="link text-accent italic" href="#terms">8. TERM AND TERMINATION</a> </p>
<p><a class="link text-accent italic" href="#modifications">9. MODIFICATIONS AND INTERRUPTIONS</a> </p>
<p><a class="link text-accent italic" href="#law">10. GOVERNING LAW</a> </p>
<p><a class="link text-accent italic" href="#disputes">11. DISPUTE RESOLUTION</a> </p>
<p><a class="link text-accent italic" href="#corrections">12. CORRECTIONS</a> </p>
<p><a class="link text-accent italic" href="#disclaimer">13. DISCLAIMER</a> </p>
<p><a class="link text-accent italic" href="#liability">14. LIMITATIONS OF LIABILITY</a> </p>
<p><a class="link text-accent italic" href="#indemnification">15. INDEMNIFICATION</a> </p>
<p><a class="link text-accent italic" href="#userdata">16. USER DATA</a> </p>
<p><a class="link text-accent italic" href="#electronic">17. ELECTRONIC COMMUNICATIONS, TRANSACTIONS, AND SIGNATURES</a> </p>
<p><a class="link text-accent italic" href="#misc">18. MISCELLANEOUS</a> </p>
<p><a class="link text-accent italic" href="#contact">19. CONTACT US</a></p>
<h2 class="text-2xl text-secondary p-4 font-bold"><strong>1. OUR SERVICES</strong></h2>
<p>The information provided when using the Services is not intended for distribution to or use by any person or entity in any jurisdiction or country where such distribution or use would be contrary to law or regulation or which would subject us to any registration requirement within such jurisdiction or country. Accordingly, those persons who choose to access the Services from other locations do so on their own initiative and are solely responsible for compliance with local laws, if and to the extent local laws are applicable.</p>
<h2 class="text-2xl text-secondary p-4 font-bold"><strong>2. INTELLECTUAL PROPERTY RIGHTS</strong></h2>
<h3 class="text-xl text-secondary p-4 font-bold"><strong>Our intellectual property</strong></h3>
<p>We are the owner or the licensee of all intellectual property rights in our Services, including all source code, databases, functionality, software, website designs, audio, video, text, photographs, and graphics in the Services (collectively, the "Content"), as well as the trademarks, service marks, and logos contained therein (the "Marks").</p>
<p>Our Content and Marks are protected by copyright and trademark laws (and various other intellectual property rights and unfair competition laws) and treaties around the world.</p>
<p>The Content and Marks are provided in or through the Services "AS IS" for your personal, non-commercial use or internal business purpose only.</p>
<h3 class="text-xl text-secondary p-4 font-bold"><strong>Your use of our Services</strong></h3>
<p>Subject to your compliance with these Legal Terms, including the "<a class="link text-accent italic" href="#prohibited">PROHIBITED ACTIVITIES</a>" section below, we grant you a non-exclusive, non-transferable, revocable license to:</p>
<ul>
<li>access the Services; and</li>
<li>download or print a copy of any portion of the Content to which you have properly gained access,</li>
</ul>
<p>solely for your personal, non-commercial use or internal business purpose.</p>
<p>Except as set out in this section or elsewhere in our Legal Terms, no part of the Services and no Content or Marks may be copied, reproduced, aggregated, republished, uploaded, posted, publicly displayed, encoded, translated, transmitted, distributed, sold, licensed, or otherwise exploited for any commercial purpose whatsoever, without our express prior written permission.</p>
<p>If you wish to make any use of the Services, Content, or Marks other than as set out in this section or elsewhere in our Legal Terms, please address your request to: <a class="link text-accent italic" href="mailto:privacy@hexname.com">privacy@hexname.com</a>. If we ever grant you the permission to post, reproduce, or publicly display any part of our Services or Content, you must identify us as the owners or licensors of the Services, Content, or Marks and ensure that any copyright or proprietary notice appears or is visible on posting, reproducing, or displaying our Content.</p>
<p>We reserve all rights not expressly granted to you in and to the Services, Content, and Marks.</p>
<p>Any breach of these Intellectual Property Rights will constitute a material breach of our Legal Terms and your right to use our Services will terminate immediately.</p>
<h3 class="text-xl text-secondary p-4 font-bold"><strong>Your submissions</strong></h3>
<p>Please review this section and the "<a class="link text-accent italic" href="#prohibited">PROHIBITED ACTIVITIES</a>" section carefully prior to using our Services to understand the (a) rights you give us and (b) obligations you have when you post or upload any content through the Services.</p>
<p><strong>Submissions:</strong> By directly sending us any question, comment, suggestion, idea, feedback, or other information about the Services ("Submissions"), you agree to assign to us all intellectual property rights in such Submission. You agree that we shall own this Submission and be entitled to its unrestricted use and dissemination for any lawful purpose, commercial or otherwise, without acknowledgment or compensation to you.</p>
<p><strong>You are responsible for what you post or upload:</strong> By sending us Submissions through any part of the Services you:</p>
<ul>
<li>confirm that you have read and agree with our "<a class="link text-accent italic" href="#prohibited">PROHIBITED ACTIVITIES</a>" and will not post, send, publish, upload, or transmit through the Services any Submission that is illegal, harassing, hateful, harmful, defamatory, obscene, bullying, abusive, discriminatory, threatening to any person or group, sexually explicit, false, inaccurate, deceitful, or misleading;
</li>
<li>to the extent permissible by applicable law, waive any and all moral rights to any such Submission;</li>
<li>warrant that any such Submission are original to you or that you have the necessary rights and licenses to submit such Submissions and that you have full authority to grant us the above-mentioned rights in relation to your Submissions; and</li>
<li>warrant and represent that your Submissions do not constitute confidential information.</li>
</ul>
<p>You are solely responsible for your Submissions and you expressly agree to reimburse us for any and all losses that we may suffer because of your breach of (a) this section, (b) any third party's intellectual property rights, or (c) applicable law.</p>
<h2 class="text-2xl text-secondary p-4 font-bold"><strong>3. USER REPRESENTATIONS</strong></h2>
<p>By using the Services, you represent and warrant that: (1) you have the legal capacity and you agree to comply with these Legal Terms; (2) you are not a minor in the jurisdiction in which you reside; (3) you will not access the Services through automated or non-human means, whether through a bot, script or otherwise; (4) you will not use the Services for any illegal or unauthorized purpose; and (5) your use of the Services will not violate any applicable law or regulation.</p>
<p>If you provide any information that is untrue, inaccurate, not current, or incomplete, we have the right to suspend or terminate your account and refuse any and all current or future use of the Services (or any portion thereof).</p>
<h2 class="text-2xl text-secondary p-4 font-bold"><strong>4. PROHIBITED ACTIVITIES</strong></h2>
<p>You may not access or use the Services for any purpose other than that for which we make the Services available. The Services may not be used in connection with any commercial endeavors except those that are specifically endorsed or approved by us.</p>
<p>As a user of the Services, you agree not to:</p>
<ul>
<li>Systematically retrieve data or other content from the Services to create or compile, directly or indirectly, a collection, compilation, database, or directory without written permission from us.</li>
<li>Trick, defraud, or mislead us and other users, especially in any attempt to learn sensitive account information such as user passwords.</li>
<li>Circumvent, disable, or otherwise interfere with security-related features of the Services, including features that prevent or restrict the use or copying of any Content or enforce limitations on the use of the Services and/or the Content contained therein.</li>
<li>Disparage, tarnish, or otherwise harm, in our opinion, us and/or the Services.</li>
<li>Use any information obtained from the Services in order to harass, abuse, or harm another person.</li>
<li>Make improper use of our support services or submit false reports of abuse or misconduct.</li>
<li>Use the Services in a manner inconsistent with any applicable laws or regulations.</li>
<li>Engage in unauthorized framing of or linking to the Services.</li>
<li>Upload or transmit (or attempt to upload or to transmit) viruses, Trojan horses, or other material, including excessive use of capital letters and spamming (continuous posting of repetitive text), that interferes with any party's uninterrupted use and enjoyment of the Services or modifies, impairs, disrupts, alters, or interferes with the use, features, functions, operation, or maintenance of the Services.</li>
<li>Engage in any automated use of the system, such as using scripts to send comments or messages, or using any data mining, robots, or similar data gathering and extraction tools.</li>
<li>Delete the copyright or other proprietary rights notice from any Content.</li>
<li>Attempt to impersonate another user or person or use the username of another user.</li>
<li>Upload or transmit (or attempt to upload or to transmit) any material that acts as a passive or active information collection or transmission mechanism, including without limitation, clear graphics interchange formats ("gifs"), 1×1 pixels, web bugs, cookies, or other similar devices (sometimes referred to as "spyware" or "passive collection mechanisms" or "pcms").</li>
<li>Interfere with, disrupt, or create an undue burden on the Services or the networks or services connected to the Services.</li>
<li>Harass, annoy, intimidate, or threaten any of our employees or agents engaged in providing any portion of the Services to you.</li>
<li>Attempt to bypass any measures of the Services designed to prevent or restrict access to the Services, or any portion of the Services.</li>
<li>Copy or adapt the Services' software, including but not limited to Flash, PHP, HTML, JavaScript, or other code.</li>
<li>Except as permitted by applicable law, decipher, decompile, disassemble, or reverse engineer any of the software comprising or in any way making up a part of the Services.</li>
<li>Except as may be the result of standard search engine or Internet browser usage, use, launch, develop, or distribute any automated system, including without limitation, any spider, robot, cheat utility, scraper, or offline reader that accesses the Services, or use or launch any unauthorized script or other software.</li>
<li>Use a buying agent or purchasing agent to make purchases on the Services.</li>
<li>Make any unauthorized use of the Services, including collecting usernames and/or email addresses of users by electronic or other means for the purpose of sending unsolicited email, or creating user accounts by automated means or under false pretenses.</li>
<li>Use the Services as part of any effort to compete with us or otherwise use the Services and/or the Content for any revenue-generating endeavor or commercial enterprise.</li>
</ul>
<h2 class="text-2xl text-secondary p-4 font-bold"><strong>5. USER GENERATED CONTRIBUTIONS</strong></h2>
<p>The Services does not offer users to submit or post content. We may provide you with the opportunity to create, submit, post, display, transmit, perform, publish, distribute, or broadcast content and materials to us or on the Services, including but not limited to text, writings, video, audio, photographs, graphics, comments, suggestions, or personal information or other material (collectively, "Contributions"). Contributions may be viewable by other users of the Services and through third-party websites. When you create or make available any Contributions, you thereby represent and warrant that:</p>
<h2 class="text-2xl text-secondary p-4 font-bold"><strong>6. CONTRIBUTION LICENSE</strong></h2>
<p>You and Services agree that we may access, store, process, and use any information and personal data that you provide and your choices (including settings).</p>
<p>By submitting suggestions or other feedback regarding the Services, you agree that we can use and share such feedback for any purpose without compensation to you.</p>
<p>We do not assert any ownership over your Contributions. You retain full ownership of all of your Contributions and any intellectual property rights or other proprietary rights associated with your Contributions. We are not liable for any statements or representations in your Contributions provided by you in any area on the Services. You are solely responsible for your Contributions to the Services and you expressly agree to exonerate us from any and all responsibility and to refrain from any legal action against us regarding your Contributions.</p>
<h2 class="text-2xl text-secondary p-4 font-bold"><strong>7. SERVICES MANAGEMENT</strong></h2>
<p>We reserve the right, but not the obligation, to: (1) monitor the Services for violations of these Legal Terms; (2) take appropriate legal action against anyone who, in our sole discretion, violates the law or these Legal Terms, including without limitation, reporting such user to law enforcement authorities; (3) in our sole discretion and without limitation, refuse, restrict access to, limit the availability of, or disable (to the extent technologically feasible) any of your Contributions or any portion thereof; (4) in our sole discretion and without limitation, notice, or liability, to remove from the Services or otherwise disable all files and content that are excessive in size or are in any way burdensome to our systems; and (5) otherwise manage the Services in a manner designed to protect our rights and property and to facilitate the proper functioning of the Services.</p>
<h2 class="text-2xl text-secondary p-4 font-bold"><strong>8. TERM AND TERMINATION</strong></h2>
<p>These Legal Terms shall remain in full force and effect while you use the Services. WITHOUT LIMITING ANY OTHER PROVISION OF THESE LEGAL TERMS, WE RESERVE THE RIGHT TO, IN OUR SOLE DISCRETION AND WITHOUT NOTICE OR LIABILITY, DENY ACCESS TO AND USE OF THE SERVICES (INCLUDING BLOCKING CERTAIN IP ADDRESSES), TO ANY PERSON FOR ANY REASON OR FOR NO REASON, INCLUDING WITHOUT LIMITATION FOR BREACH OF ANY REPRESENTATION, WARRANTY, OR COVENANT CONTAINED IN THESE LEGAL TERMS OR OF ANY APPLICABLE LAW OR REGULATION. WE MAY TERMINATE YOUR USE OR PARTICIPATION IN THE SERVICES OR DELETE ANY CONTENT OR INFORMATION THAT YOU POSTED AT ANY TIME, WITHOUT WARNING, IN OUR SOLE DISCRETION.</p>
<p>If we terminate or suspend your account for any reason, you are prohibited from registering and creating a new account under your name, a fake or borrowed name, or the name of any third party, even if you may be acting on behalf of the third party. In addition to terminating or suspending your account, we reserve the right to take appropriate legal action, including without limitation pursuing civil, criminal, and injunctive redress.</p>
<h2 class="text-2xl text-secondary p-4 font-bold"><strong>9. MODIFICATIONS AND INTERRUPTIONS</strong></h2>
<p>We reserve the right to change, modify, or remove the contents of the Services at any time or for any reason at our sole discretion without notice. However, we have no obligation to update any information on our Services. We will not be liable to you or any third party for any modification, price change, suspension, or discontinuance of the Services.</p>
<p>We cannot guarantee the Services will be available at all times. We may experience hardware, software, or other problems or need to perform maintenance related to the Services, resulting in interruptions, delays, or errors. We reserve the right to change, revise, update, suspend, discontinue, or otherwise modify the Services at any time or for any reason without notice to you. You agree that we have no liability whatsoever for any loss, damage, or inconvenience caused by your inability to access or use the Services during any downtime or discontinuance of the Services. Nothing in these Legal Terms will be construed to obligate us to maintain and support the Services or to supply any corrections, updates, or releases in connection therewith.</p>
<h2 class="text-2xl text-secondary p-4 font-bold"><strong>10. GOVERNING LAW</strong></h2>
<p>These Legal Terms shall be governed by and defined following the laws of Germany. HexName and yourself irrevocably consent that the courts of Germany shall have exclusive jurisdiction to resolve any dispute which may arise in connection with these Legal Terms.</p>
<h2 class="text-2xl text-secondary p-4 font-bold"><strong>11. DISPUTE RESOLUTION</strong></h2>
<h3 class="text-xl text-secondary p-4 font-bold"><strong>Informal Negotiations</strong></h3>
<p>To expedite resolution and control the cost of any dispute, controversy, or claim related to these Legal Terms (each a "Dispute" and collectively, the "Disputes") brought by either you or us (individually, a "Party" and collectively, the "Parties"), the Parties agree to first attempt to negotiate any Dispute (except those Disputes expressly provided below) informally for at least 30 days before initiating arbitration. Such informal negotiations commence upon written notice from one Party to the other Party.</p>
<h3 class="text-xl text-secondary p-4 font-bold"><strong>Binding Arbitration</strong></h3>
<p>Any dispute arising out of or in connection with these Legal Terms, including any question regarding its existence, validity, or termination, shall be referred to and finally resolved by the International Commercial Arbitration Court under the European Arbitration Chamber (Belgium, Brussels, Avenue Louise, 146) according to the Rules of this ICAC, which, as a result of referring to it, is considered as the part of this clause. The number of arbitrators shall be 1. The seat, or legal place, or arbitration shall be Germany. The language of the proceedings shall be English. The governing law of these Legal Terms shall be substantive law of Germany.</p>
<h3 class="text-xl text-secondary p-4 font-bold"><strong>Restrictions</strong></h3>
<p>The Parties agree that any arbitration shall be limited to the Dispute between the Parties individually. To the full extent permitted by law, (a) no arbitration shall be joined with any other proceeding; (b) there is no right or authority for any Dispute to be arbitrated on a class-action basis or to utilize class action procedures; and (c) there is no right or authority for any Dispute to be brought in a purported representative capacity on behalf of the general public or any other persons.</p>
<h3 class="text-xl text-secondary p-4 font-bold"><strong>Exceptions to Informal Negotiations and Arbitration</strong></h3>
<p>The Parties agree that the following Disputes are not subject to the above provisions concerning informal negotiations binding arbitration: (a) any Disputes seeking to enforce or protect, or concerning the validity of, any of the intellectual property rights of a Party; (b) any Dispute related to, or arising from, allegations of theft, piracy, invasion of privacy, or unauthorized use; and (c) any claim for injunctive relief. If this provision is found to be illegal or unenforceable, then neither Party will elect to arbitrate any Dispute falling within that portion of this provision found to be illegal or unenforceable and such Dispute shall be decided by a court of competent jurisdiction within the courts listed for jurisdiction above, and the Parties agree to submit to the personal jurisdiction of that court.</p>
<h2 class="text-2xl text-secondary p-4 font-bold"><strong>12. CORRECTIONS</strong></h2>
<p>There may be information on the Services that contains typographical errors, inaccuracies, or omissions, including descriptions, pricing, availability, and various other information. We reserve the right to correct any errors, inaccuracies, or omissions and to change or update the information on the Services at any time, without prior notice.</p>
<h2 class="text-2xl text-secondary p-4 font-bold"><strong>13. DISCLAIMER</strong></h2>
<p>THE SERVICES ARE PROVIDED ON AN AS-IS AND AS-AVAILABLE BASIS. YOU AGREE THAT YOUR USE OF THE SERVICES WILL BE AT YOUR SOLE RISK. TO THE FULLEST EXTENT PERMITTED BY LAW, WE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, IN CONNECTION WITH THE SERVICES AND YOUR USE THEREOF, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. WE MAKE NO WARRANTIES OR REPRESENTATIONS ABOUT THE ACCURACY OR COMPLETENESS OF THE SERVICES' CONTENT OR THE CONTENT OF ANY WEBSITES OR MOBILE APPLICATIONS LINKED TO THE SERVICES AND WE WILL ASSUME NO LIABILITY OR RESPONSIBILITY FOR ANY (1) ERRORS, MISTAKES, OR INACCURACIES OF CONTENT AND MATERIALS, (2) PERSONAL INJURY OR PROPERTY DAMAGE, OF ANY NATURE WHATSOEVER, RESULTING FROM YOUR ACCESS TO AND USE OF THE SERVICES, (3) ANY UNAUTHORIZED ACCESS TO OR USE OF OUR SECURE SERVERS AND/OR ANY AND ALL PERSONAL INFORMATION AND/OR FINANCIAL INFORMATION STORED THEREIN, (4) ANY INTERRUPTION OR CESSATION OF TRANSMISSION TO OR FROM THE SERVICES, (5) ANY BUGS, VIRUSES, TROJAN HORSES, OR THE LIKE WHICH MAY BE TRANSMITTED TO OR THROUGH THE SERVICES BY ANY THIRD PARTY, AND/OR (6) ANY ERRORS OR OMISSIONS IN ANY CONTENT AND MATERIALS OR FOR ANY LOSS OR DAMAGE OF ANY KIND INCURRED AS A RESULT OF THE USE OF ANY CONTENT POSTED, TRANSMITTED, OR OTHERWISE MADE AVAILABLE VIA THE SERVICES. WE DO NOT WARRANT, ENDORSE, GUARANTEE, OR ASSUME RESPONSIBILITY FOR ANY PRODUCT OR SERVICE ADVERTISED OR OFFERED BY A THIRD PARTY THROUGH THE SERVICES, ANY HYPERLINKED WEBSITE, OR ANY WEBSITE OR MOBILE APPLICATION FEATURED IN ANY BANNER OR OTHER ADVERTISING, AND WE WILL NOT BE A PARTY TO OR IN ANY WAY BE RESPONSIBLE FOR MONITORING ANY TRANSACTION BETWEEN YOU AND ANY THIRD-PARTY PROVIDERS OF PRODUCTS OR SERVICES. AS WITH THE PURCHASE OF A PRODUCT OR SERVICE THROUGH ANY MEDIUM OR IN ANY ENVIRONMENT, YOU SHOULD USE YOUR BEST JUDGMENT AND EXERCISE CAUTION WHERE APPROPRIATE.</p>
<h2 class="text-2xl text-secondary p-4 font-bold"><strong>14. LIMITATIONS OF LIABILITY</strong></h2>
<p>IN NO EVENT WILL WE OR OUR DIRECTORS, EMPLOYEES, OR AGENTS BE LIABLE TO YOU OR ANY THIRD PARTY FOR ANY DIRECT, INDIRECT, CONSEQUENTIAL, EXEMPLARY, INCIDENTAL, SPECIAL, OR PUNITIVE DAMAGES, INCLUDING LOST PROFIT, LOST REVENUE, LOSS OF DATA, OR OTHER DAMAGES ARISING FROM YOUR USE OF THE SERVICES, EVEN IF WE HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. NOTWITHSTANDING ANYTHING TO THE CONTRARY CONTAINED HEREIN, OUR LIABILITY TO YOU FOR ANY CAUSE WHATSOEVER AND REGARDLESS OF THE FORM OF THE ACTION, WILL AT ALL TIMES BE LIMITED TO THE LESSER OF THE AMOUNT PAID, IF ANY, BY YOU TO US OR . CERTAIN US STATE LAWS AND INTERNATIONAL LAWS DO NOT ALLOW LIMITATIONS ON IMPLIED WARRANTIES OR THE EXCLUSION OR LIMITATION OF CERTAIN DAMAGES. IF THESE LAWS APPLY TO YOU, SOME OR ALL OF THE ABOVE DISCLAIMERS OR LIMITATIONS MAY NOT APPLY TO YOU, AND YOU MAY HAVE ADDITIONAL RIGHTS.</p>
<h2 class="text-2xl text-secondary p-4 font-bold"><strong>15. INDEMNIFICATION</strong></h2>
<p>You agree to defend, indemnify, and hold us harmless, including our subsidiaries, affiliates, and all of our respective officers, agents, partners, and employees, from and against any loss, damage, liability, claim, or demand, including reasonable attorneys' fees and expenses, made by any third party due to or arising out of: (1) use of the Services; (2) breach of these Legal Terms; (3) any breach of your representations and warranties set forth in these Legal Terms; (4) your violation of the rights of a third party, including but not limited to intellectual property rights; or (5) any overt harmful act toward any other user of the Services with whom you connected via the Services. Notwithstanding the foregoing, we reserve the right, at your expense, to assume the exclusive defense and control of any matter for which you are required to indemnify us, and you agree to cooperate, at your expense, with our defense of such claims. We will use reasonable efforts to notify you of any such claim, action, or proceeding which is subject to this indemnification upon becoming aware of it.</p>
<h2 class="text-2xl text-secondary p-4 font-bold"><strong>16. USER DATA</strong></h2>
<p>We will maintain certain data that you transmit to the Services for the purpose of managing the performance of the Services, as well as data relating to your use of the Services. Although we perform regular routine backups of data, you are solely responsible for all data that you transmit or that relates to any activity you have undertaken using the Services. You agree that we shall have no liability to you for any loss or corruption of any such data, and you hereby waive any right of action against us arising from any such loss or corruption of such data.</p>
<h2 class="text-2xl text-secondary p-4 font-bold"><strong>17. ELECTRONIC COMMUNICATIONS, TRANSACTIONS, AND SIGNATURES</strong></h2>
<p>Visiting the Services, sending us emails, and completing online forms constitute electronic communications. You consent to receive electronic communications, and you agree that all agreements, notices, disclosures, and other communications we provide to you electronically, via email and on the Services, satisfy any legal requirement that such communication be in writing. YOU HEREBY AGREE TO THE USE OF ELECTRONIC SIGNATURES, CONTRACTS, ORDERS, AND OTHER RECORDS, AND TO ELECTRONIC DELIVERY OF NOTICES, POLICIES, AND RECORDS OF TRANSACTIONS INITIATED OR COMPLETED BY US OR VIA THE SERVICES. You hereby waive any rights or requirements under any statutes, regulations, rules, ordinances, or other laws in any jurisdiction which require an original signature or delivery or retention of non-electronic records, or to payments or the granting of credits by any means other than electronic means.</p>
<h2 class="text-2xl text-secondary p-4 font-bold"><strong>18. MISCELLANEOUS</strong></h2>
<p>These Legal Terms and any policies or operating rules posted by us on the Services or in respect to the Services constitute the entire agreement and understanding between you and us. Our failure to exercise or enforce any right or provision of these Legal Terms shall not operate as a waiver of such right or provision. These Legal Terms operate to the fullest extent permissible by law. We may assign any or all of our rights and obligations to others at any time. We shall not be responsible or liable for any loss, damage, delay, or failure to act caused by any cause beyond our reasonable control. If any provision or part of a provision of these Legal Terms is determined to be unlawful, void, or unenforceable, that provision or part of the provision is deemed severable from these Legal Terms and does not affect the validity and enforceability of any remaining provisions. There is no joint venture, partnership, employment or agency relationship created between you and us as a result of these Legal Terms or use of the Services. You agree that these Legal Terms will not be construed against us by virtue of having drafted them. You hereby waive any and all defenses you may have based on the electronic form of these Legal Terms and the lack of signing by the parties hereto to execute these Legal Terms.</p>
<h2 class="text-2xl text-secondary p-4 font-bold"><strong>19. CONTACT US</strong></h2>
<p>In order to resolve a complaint regarding the Services or to receive further information regarding use of the Services, please contact us at:</p>
<p><strong><a class="link text-accent italic" href="mailto:privacy@hexname.com">privacy@hexname.com</a></strong></p>
</div>

View file

@ -1,4 +1,5 @@
<script lang="ts"> <script lang="ts">
import { goto } from "$app/navigation";
import { page } from "$app/state"; import { page } from "$app/state";
import { PUBLIC_BACKEND_API_HOST } from "$env/static/public"; import { PUBLIC_BACKEND_API_HOST } from "$env/static/public";
import { onMount } from "svelte"; import { onMount } from "svelte";
@ -22,6 +23,9 @@
success = false; success = false;
} else { } else {
success = true; success = true;
setTimeout(() => {
goto("/login");
}, 2000);
} }
} catch (err: any) { } catch (err: any) {
errorMessage = err?.msg || "Network error"; errorMessage = err?.msg || "Network error";
@ -30,18 +34,28 @@
}); });
</script> </script>
<svelte:head>
<title>HexName - Free, uncomplicated DNS management</title>
<meta property="og:title" content="HexName - Free, uncomplicated DNS management">
<meta name="twitter:title" content="HexName - Free, uncomplicated DNS management">
<meta name="description" content="Register our premium domains and manage DNS and DynDNS - so you can focus on what truly matters.">
<meta property="og:description" content="Register our premium domains and manage DNS and DynDNS - so you can focus on what truly matters.">
<meta name="twitter:description" content="Register our premium domains and manage DNS and DynDNS - so you can focus on what truly matters.">
<meta name="robots" content="noindex, nofollow">
</svelte:head>
{#if success === undefined} {#if success === undefined}
<div class="container flex items-center justify-center mx-auto min-h-screen py-8"> <div class="flex flex-col items-center justify-center w-full my-80">
<h2 class="text-4xl text-primary-content">Verifying your email</h2> <h2 class="text-4xl text-primary-content">Verifying your email</h2>
<span class="loading loading-dots loading-lg translate-y-3 ml-1"></span> <span class="loading loading-dots loading-lg translate-y-3 ml-1"></span>
</div> </div>
{:else if success} {:else if success}
<div class="container flex flex-col items-center justify-center mx-auto min-h-screen py-8"> <div class="flex flex-col items-center justify-center w-full my-80">
<h2 class="text-2xl text-primary-content">Email successfully verified!</h2> <h2 class="text-2xl text-primary-content">Email successfully verified!</h2>
<h3 class="text-xl text-primary-content">You may log in now.</h3> <h3 class="text-xl text-primary-content">You may log in now.</h3>
</div> </div>
{:else} {:else}
<div class="container flex flex-col items-center justify-center mx-auto min-h-screen py-8"> <div class="flex flex-col items-center justify-center w-full my-80">
<h2 class="text-2xl text-primary-content">Failed to verify your email:</h2> <h2 class="text-2xl text-primary-content">Failed to verify your email:</h2>
<h3 class="text-xl text-primary-content">{errorMessage}</h3> <h3 class="text-xl text-primary-content">{errorMessage}</h3>
</div> </div>