From 0c78d614bfecf0f9b3c4f8ad9e96ab45227bdb6b Mon Sep 17 00:00:00 2001 From: youhavetrouble Date: Tue, 3 Oct 2023 21:57:18 +0200 Subject: [PATCH] Initial commit --- .gitignore | 28 ++ CNAME | 1 + bun.lockb | Bin 0 -> 25659 bytes index.html | 13 + package-lock.json | 714 ++++++++++++++++++++++++++++++ package.json | 19 + public/data/aetherytes.json | 63 +++ public/data/items.json | 22 + public/data/nodes.json | 37 ++ public/data/zones.json | 12 + src/App.vue | 174 ++++++++ src/assets/main.css | 22 + src/components/GatheringNode.vue | 128 ++++++ src/components/SortedNodeList.vue | 80 ++++ src/entities/Aetheryte.ts | 16 + src/entities/Item.ts | 20 + src/entities/Node.ts | 62 +++ src/entities/TimeRange.ts | 34 ++ src/entities/Zone.ts | 11 + src/enums/Job.ts | 15 + src/enums/NodeType.ts | 15 + src/main.js | 6 + src/util/EorzeaTime.ts | 62 +++ vite.config.js | 16 + 24 files changed, 1570 insertions(+) create mode 100644 .gitignore create mode 100644 CNAME create mode 100755 bun.lockb create mode 100644 index.html create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 public/data/aetherytes.json create mode 100644 public/data/items.json create mode 100644 public/data/nodes.json create mode 100644 public/data/zones.json create mode 100644 src/App.vue create mode 100644 src/assets/main.css create mode 100644 src/components/GatheringNode.vue create mode 100644 src/components/SortedNodeList.vue create mode 100644 src/entities/Aetheryte.ts create mode 100644 src/entities/Item.ts create mode 100644 src/entities/Node.ts create mode 100644 src/entities/TimeRange.ts create mode 100644 src/entities/Zone.ts create mode 100644 src/enums/Job.ts create mode 100644 src/enums/NodeType.ts create mode 100644 src/main.js create mode 100644 src/util/EorzeaTime.ts create mode 100644 vite.config.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..38adffa --- /dev/null +++ b/.gitignore @@ -0,0 +1,28 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +.DS_Store +dist +dist-ssr +coverage +*.local + +/cypress/videos/ +/cypress/screenshots/ + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/CNAME b/CNAME new file mode 100644 index 0000000..ca3a466 --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +dol.yht.one \ No newline at end of file diff --git a/bun.lockb b/bun.lockb new file mode 100755 index 0000000000000000000000000000000000000000..8a8f9b84418b2c9fca198d236b5d5d52062c2b7e GIT binary patch literal 25659 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 literal 0 HcmV?d00001 diff --git a/index.html b/index.html new file mode 100644 index 0000000..af5820d --- /dev/null +++ b/index.html @@ -0,0 +1,13 @@ + + + + + + + Disciple of Land + + +
+ + + diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..6ad7ab8 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,714 @@ +{ + "name": "discipleofland", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "discipleofland", + "version": "0.0.0", + "dependencies": { + "vue": "^3.3.4" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^4.2.3", + "vite": "^4.3.9" + } + }, + "node_modules/@babel/parser": { + "version": "7.22.16", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.16.tgz", + "integrity": "sha512-+gPfKv8UWeKKeJTUxe59+OobVcrYHETCsORl61EmSkmgymguYk/X5bp7GuUIXaFsc6y++v8ZxPsLSSuujqDphA==", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", + "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", + "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", + "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", + "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", + "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", + "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", + "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", + "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", + "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", + "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", + "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", + "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", + "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", + "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", + "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", + "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", + "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", + "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", + "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", + "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", + "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", + "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + }, + "node_modules/@vitejs/plugin-vue": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.3.4.tgz", + "integrity": "sha512-ciXNIHKPriERBisHFBvnTbfKa6r9SAesOYXeGDzgegcvy9Q4xdScSHAmKbNT0M3O0S9LKhIf5/G+UYG4NnnzYw==", + "dev": true, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.0.0", + "vue": "^3.2.25" + } + }, + "node_modules/@vue/compiler-core": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.3.4.tgz", + "integrity": "sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g==", + "dependencies": { + "@babel/parser": "^7.21.3", + "@vue/shared": "3.3.4", + "estree-walker": "^2.0.2", + "source-map-js": "^1.0.2" + } + }, + "node_modules/@vue/compiler-dom": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.3.4.tgz", + "integrity": "sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w==", + "dependencies": { + "@vue/compiler-core": "3.3.4", + "@vue/shared": "3.3.4" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.3.4.tgz", + "integrity": "sha512-6y/d8uw+5TkCuzBkgLS0v3lSM3hJDntFEiUORM11pQ/hKvkhSKZrXW6i69UyXlJQisJxuUEJKAWEqWbWsLeNKQ==", + "dependencies": { + "@babel/parser": "^7.20.15", + "@vue/compiler-core": "3.3.4", + "@vue/compiler-dom": "3.3.4", + "@vue/compiler-ssr": "3.3.4", + "@vue/reactivity-transform": "3.3.4", + "@vue/shared": "3.3.4", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.0", + "postcss": "^8.1.10", + "source-map-js": "^1.0.2" + } + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.3.4.tgz", + "integrity": "sha512-m0v6oKpup2nMSehwA6Uuu+j+wEwcy7QmwMkVNVfrV9P2qE5KshC6RwOCq8fjGS/Eak/uNb8AaWekfiXxbBB6gQ==", + "dependencies": { + "@vue/compiler-dom": "3.3.4", + "@vue/shared": "3.3.4" + } + }, + "node_modules/@vue/reactivity": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.3.4.tgz", + "integrity": "sha512-kLTDLwd0B1jG08NBF3R5rqULtv/f8x3rOFByTDz4J53ttIQEDmALqKqXY0J+XQeN0aV2FBxY8nJDf88yvOPAqQ==", + "dependencies": { + "@vue/shared": "3.3.4" + } + }, + "node_modules/@vue/reactivity-transform": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.3.4.tgz", + "integrity": "sha512-MXgwjako4nu5WFLAjpBnCj/ieqcjE2aJBINUNQzkZQfzIZA4xn+0fV1tIYBJvvva3N3OvKGofRLvQIwEQPpaXw==", + "dependencies": { + "@babel/parser": "^7.20.15", + "@vue/compiler-core": "3.3.4", + "@vue/shared": "3.3.4", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.0" + } + }, + "node_modules/@vue/runtime-core": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.3.4.tgz", + "integrity": "sha512-R+bqxMN6pWO7zGI4OMlmvePOdP2c93GsHFM/siJI7O2nxFRzj55pLwkpCedEY+bTMgp5miZ8CxfIZo3S+gFqvA==", + "dependencies": { + "@vue/reactivity": "3.3.4", + "@vue/shared": "3.3.4" + } + }, + "node_modules/@vue/runtime-dom": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.3.4.tgz", + "integrity": "sha512-Aj5bTJ3u5sFsUckRghsNjVTtxZQ1OyMWCr5dZRAPijF/0Vy4xEoRCwLyHXcj4D0UFbJ4lbx3gPTgg06K/GnPnQ==", + "dependencies": { + "@vue/runtime-core": "3.3.4", + "@vue/shared": "3.3.4", + "csstype": "^3.1.1" + } + }, + "node_modules/@vue/server-renderer": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.3.4.tgz", + "integrity": "sha512-Q6jDDzR23ViIb67v+vM1Dqntu+HUexQcsWKhhQa4ARVzxOY2HbC7QRW/ggkDBd5BU+uM1sV6XOAP0b216o34JQ==", + "dependencies": { + "@vue/compiler-ssr": "3.3.4", + "@vue/shared": "3.3.4" + }, + "peerDependencies": { + "vue": "3.3.4" + } + }, + "node_modules/@vue/shared": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.3.4.tgz", + "integrity": "sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==" + }, + "node_modules/csstype": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", + "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" + }, + "node_modules/esbuild": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.18.20", + "@esbuild/android-arm64": "0.18.20", + "@esbuild/android-x64": "0.18.20", + "@esbuild/darwin-arm64": "0.18.20", + "@esbuild/darwin-x64": "0.18.20", + "@esbuild/freebsd-arm64": "0.18.20", + "@esbuild/freebsd-x64": "0.18.20", + "@esbuild/linux-arm": "0.18.20", + "@esbuild/linux-arm64": "0.18.20", + "@esbuild/linux-ia32": "0.18.20", + "@esbuild/linux-loong64": "0.18.20", + "@esbuild/linux-mips64el": "0.18.20", + "@esbuild/linux-ppc64": "0.18.20", + "@esbuild/linux-riscv64": "0.18.20", + "@esbuild/linux-s390x": "0.18.20", + "@esbuild/linux-x64": "0.18.20", + "@esbuild/netbsd-x64": "0.18.20", + "@esbuild/openbsd-x64": "0.18.20", + "@esbuild/sunos-x64": "0.18.20", + "@esbuild/win32-arm64": "0.18.20", + "@esbuild/win32-ia32": "0.18.20", + "@esbuild/win32-x64": "0.18.20" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/magic-string": { + "version": "0.30.3", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.3.tgz", + "integrity": "sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw==", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/nanoid": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "node_modules/postcss": { + "version": "8.4.29", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.29.tgz", + "integrity": "sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/rollup": { + "version": "3.29.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.2.tgz", + "integrity": "sha512-CJouHoZ27v6siztc21eEQGo0kIcE5D1gVPA571ez0mMYb25LGYGKnVNXpEj5MGlepmDWGXNjDB5q7uNiPHC11A==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=14.18.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/vite": { + "version": "4.4.9", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.9.tgz", + "integrity": "sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==", + "dev": true, + "dependencies": { + "esbuild": "^0.18.10", + "postcss": "^8.4.27", + "rollup": "^3.27.1" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@types/node": ">= 14", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vue": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.3.4.tgz", + "integrity": "sha512-VTyEYn3yvIeY1Py0WaYGZsXnz3y5UnGi62GjVEqvEGPl6nxbOrCXbVOTQWBEJUqAyTUk2uJ5JLVnYJ6ZzGbrSw==", + "dependencies": { + "@vue/compiler-dom": "3.3.4", + "@vue/compiler-sfc": "3.3.4", + "@vue/runtime-dom": "3.3.4", + "@vue/server-renderer": "3.3.4", + "@vue/shared": "3.3.4" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..f234a28 --- /dev/null +++ b/package.json @@ -0,0 +1,19 @@ +{ + "name": "discipleofland", + "version": "0.0.0", + "private": true, + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview" + }, + "dependencies": { + "sass": "^1.67.0", + "typescript": "^5.2.2", + "vue": "^3.3.4" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^4.2.3", + "vite": "^4.3.9" + } +} diff --git a/public/data/aetherytes.json b/public/data/aetherytes.json new file mode 100644 index 0000000..4e7832f --- /dev/null +++ b/public/data/aetherytes.json @@ -0,0 +1,63 @@ +[ + { + "position": { + "zone": "labyrinthos", + "x": 30.3, + "y": 11.9 + }, + "name": { + "en": "The Archeion" + } + }, + { + "position": { + "zone": "labyrinthos", + "x": 21.6, + "y": 20.4 + }, + "name": { + "en": "Sharlayan Hamlet" + } + }, + { + "position": { + "zone": "labyrinthos", + "x": 6.8, + "y": 27.5 + }, + "name": { + "en": "Aporia" + } + }, + { + "position": { + "zone": "thavnair", + "x": 29.5, + "y": 16.5 + }, + "name": { + "en": "Palaka's Stand" + } + }, + { + "position": { + "zone": "thavnair", + "x": 10.9, + "y": 22.2 + }, + "name": { + "en": "The Great Work" + } + }, + { + "position": { + "zone": "thavnair", + "x": 25.3, + "y": 34.0 + }, + "name": { + "en": "Yedlihmad" + } + } +] + diff --git a/public/data/items.json b/public/data/items.json new file mode 100644 index 0000000..506f1bd --- /dev/null +++ b/public/data/items.json @@ -0,0 +1,22 @@ +{ + "rarefied-iceberg-lettuce": { + "name": "Rarefied Iceberg Lettuce", + "scrip-color": "purple", + "level": 90 + }, + "rarefied-dark-rye": { + "name": "Rarefied Dark Rye", + "scrip-color": "white", + "level": 89 + }, + "rarefied-palm-log": { + "name": "Rarefied Palm Log", + "scrip-color": "white", + "level": 81 + }, + "rarefied-coconut": { + "name": "Rarefied Coconut", + "scrip-color": "white", + "level": 85 + } +} diff --git a/public/data/nodes.json b/public/data/nodes.json new file mode 100644 index 0000000..2e19702 --- /dev/null +++ b/public/data/nodes.json @@ -0,0 +1,37 @@ +[ + { + "job": "botanist", + "type": "unspoiled", + "position": { + "zone": "labyrinthos", + "x": 9.7, + "y": 22.2 + }, + "times": [ + "06:00-08:00", + "18:00-20:00" + ], + "items": [ + "rarefied-dark-rye", + "rarefied-iceberg-lettuce" + ] + }, + { + "job": "botanist", + "type": "unspoiled", + "position": { + "zone": "thavnair", + "x": 14.3, + "y": 14.5 + }, + "times": [ + "02:00-04:00", + "14:00-16:00" + ], + "items": [ + "rarefied-palm-log", + "rarefied-coconut" + ] + } +] + diff --git a/public/data/zones.json b/public/data/zones.json new file mode 100644 index 0000000..4400ab5 --- /dev/null +++ b/public/data/zones.json @@ -0,0 +1,12 @@ +{ + "labyrinthos": { + "name": { + "en": "Labyrinthos" + } + }, + "thavnair": { + "name": { + "en": "Thavnair" + } + } +} \ No newline at end of file diff --git a/src/App.vue b/src/App.vue new file mode 100644 index 0000000..daec56c --- /dev/null +++ b/src/App.vue @@ -0,0 +1,174 @@ + + + + diff --git a/src/assets/main.css b/src/assets/main.css new file mode 100644 index 0000000..0c279a8 --- /dev/null +++ b/src/assets/main.css @@ -0,0 +1,22 @@ +* { + box-sizing: border-box; + font-family: 'Roboto', sans-serif; + font-size: 16px; + font-weight: 400; + color: #eaeaea; +} + +body { + background-color: #2a2a2a; + margin: 0; + padding: 0; +} +#app { + max-width: 1280px; + margin: 0 auto; + display: flex; + flex-direction: column; + gap: 0.5rem; + + font-weight: normal; +} diff --git a/src/components/GatheringNode.vue b/src/components/GatheringNode.vue new file mode 100644 index 0000000..a3c4dfe --- /dev/null +++ b/src/components/GatheringNode.vue @@ -0,0 +1,128 @@ + + + + + \ No newline at end of file diff --git a/src/components/SortedNodeList.vue b/src/components/SortedNodeList.vue new file mode 100644 index 0000000..af91e18 --- /dev/null +++ b/src/components/SortedNodeList.vue @@ -0,0 +1,80 @@ + + + + + \ No newline at end of file diff --git a/src/entities/Aetheryte.ts b/src/entities/Aetheryte.ts new file mode 100644 index 0000000..7339d23 --- /dev/null +++ b/src/entities/Aetheryte.ts @@ -0,0 +1,16 @@ +export default class Aetheryte { + + readonly position: { x: number, y: number, zone: string }; + readonly name: { + en: string, + } + + constructor( + data: any, + ) { + this.position = data.position; + this.name = data.name.en; + } + + +} \ No newline at end of file diff --git a/src/entities/Item.ts b/src/entities/Item.ts new file mode 100644 index 0000000..a15c453 --- /dev/null +++ b/src/entities/Item.ts @@ -0,0 +1,20 @@ +export default class Item { + + readonly id: string; + readonly name: string; + readonly level: number; + readonly scripType: ScripType; + + constructor(id: string, data: any) { + this.id = id; + this.name = data?.name; + this.level = data?.level; + this.scripType = data?.scripType ? ScripType[data.scripType.toUpperCase()] : null; + } + +} + +enum ScripType { + WHITE = 'white', + PURPLE = 'purple', +} \ No newline at end of file diff --git a/src/entities/Node.ts b/src/entities/Node.ts new file mode 100644 index 0000000..d20ef93 --- /dev/null +++ b/src/entities/Node.ts @@ -0,0 +1,62 @@ +import {Job} from "../enums/Job"; +import {NodeType} from "../enums/NodeType"; +import Item from "./Item"; +import Aetheryte from "./Aetheryte"; +import TimeRange from "./TimeRange"; +import EorzeaTime from "../util/EorzeaTime"; + +export default class Node { + + readonly job: Job; + readonly nodeType: NodeType; + readonly location: { x: number, y: number, zone: string }; + readonly times: Array; + readonly nearestAetheryte: Aetheryte; + readonly items: Item[]; + + constructor( + job: Job, + nodeType: NodeType, + location: { x: number, y: number, zone: string }, + times: Array, + items: Item[], + nearestAetheryte: Aetheryte, + ) { + this.job = job; + this.nodeType = nodeType; + this.location = location; + this.times = times; + this.items = items; + this.nearestAetheryte = nearestAetheryte; + } + + isActive(eorzeaTime: EorzeaTime): boolean { + for (const timeRange of this.times) { + if (timeRange.isWithinTimeFrame(eorzeaTime.getHours(), eorzeaTime.getMinutes())) return true; + } + return false; + } + + getCountdownToActive(eorzeaTime: EorzeaTime): number { + let countdown: number = Infinity; + for (const timeRange of this.times) { + const nextTimeFrame: number = timeRange.getNextTimeFrame(eorzeaTime); + if (nextTimeFrame < countdown) countdown = nextTimeFrame; + } + return countdown; + } + + getNextActiveTime(eorzeaTime: EorzeaTime): EorzeaTime { + let countdownTimeStamp: number = Infinity; + for (const timeRange of this.times) { + const nextTimeFrame: number = timeRange.getNextTimeFrame(eorzeaTime); + if (nextTimeFrame < countdownTimeStamp) countdownTimeStamp = nextTimeFrame; + } + return EorzeaTime.fromEorzeaTime(new Date(this.getCountdownToActive(eorzeaTime))); + } + + getSecondsToNextActiveTime(eorzeaTime: EorzeaTime): number { + return Math.floor((this.getNextActiveTime(eorzeaTime).realDate.getTime() - eorzeaTime.realDate.getTime()) / 1000); + } + +} \ No newline at end of file diff --git a/src/entities/TimeRange.ts b/src/entities/TimeRange.ts new file mode 100644 index 0000000..d5e5988 --- /dev/null +++ b/src/entities/TimeRange.ts @@ -0,0 +1,34 @@ +import EorzeaTime from "../util/EorzeaTime"; + +export default class TimeRange { + + private readonly from: [number, number]; + private readonly to: [number, number]; + + constructor(fromHour: number, fromMinute: number, toHour: number, toMinute: number) { + this.from = [fromHour, fromMinute]; + this.to = [toHour, toMinute]; + } + + public isWithinTimeFrame(hour: number, minute: number): boolean { + return ( + this.from[0] < hour || this.from[0] == hour && this.from[1] <= minute) + && (hour < this.to[0] || hour == this.to[0] && minute <= this.to[1] + ); + } + + /** + * Returns a timestamp when the time range will be active again + */ + public getNextTimeFrame(eorzeaTimeFrom: EorzeaTime): number { + const targetDate = new Date(eorzeaTimeFrom.eorzeaDate.getTime()); + targetDate.setUTCHours(this.from[0], 0, 0, 0); + if (eorzeaTimeFrom.getHours() >= this.to[0]) { + targetDate.setUTCHours(this.from[0] + 24); + } + return targetDate.getTime(); + } + + + +} \ No newline at end of file diff --git a/src/entities/Zone.ts b/src/entities/Zone.ts new file mode 100644 index 0000000..fa05c39 --- /dev/null +++ b/src/entities/Zone.ts @@ -0,0 +1,11 @@ +export default class Zone { + + name: { + en: string, + } + + constructor(data: any) { + this.name = data.name; + } + +} \ No newline at end of file diff --git a/src/enums/Job.ts b/src/enums/Job.ts new file mode 100644 index 0000000..b5de7f6 --- /dev/null +++ b/src/enums/Job.ts @@ -0,0 +1,15 @@ +export enum Job { + BOTANIST = "botanist", + MINER = "miner", +} + +export function jobFromString(str: string): Job | null { + switch (str.toLowerCase()) { + case "botanist": + return Job.BOTANIST; + case "miner": + return Job.MINER; + default: + return null; + } +} \ No newline at end of file diff --git a/src/enums/NodeType.ts b/src/enums/NodeType.ts new file mode 100644 index 0000000..6103820 --- /dev/null +++ b/src/enums/NodeType.ts @@ -0,0 +1,15 @@ +export enum NodeType { + UNSPOILED = "unspoiled", + LEGENDARY = "legendary", +} + +export function nodeTypeFromString(str: string): NodeType | null { + switch (str.toLowerCase()) { + case "unspoiled": + return NodeType.UNSPOILED; + case "legendary": + return NodeType.LEGENDARY; + default: + return null; + } +} \ No newline at end of file diff --git a/src/main.js b/src/main.js new file mode 100644 index 0000000..0ac3a5f --- /dev/null +++ b/src/main.js @@ -0,0 +1,6 @@ +import './assets/main.css' + +import { createApp } from 'vue' +import App from './App.vue' + +createApp(App).mount('#app') diff --git a/src/util/EorzeaTime.ts b/src/util/EorzeaTime.ts new file mode 100644 index 0000000..deb8e20 --- /dev/null +++ b/src/util/EorzeaTime.ts @@ -0,0 +1,62 @@ +export default class EorzeaTime { + + /** + * The real life date + */ + readonly realDate: Date; + + /** + * The Eorzean date + * @private + */ + readonly eorzeaDate: Date; + + private constructor(realDate: Date = new Date()) { + this.realDate = realDate; + this.eorzeaDate = new Date(realDate.getTime() * (3600 / 175)); + } + + /** + * Returns Eorzean hours + */ + getHours(): number { + return this.eorzeaDate.getUTCHours(); + } + + /** + * Returns Eorzean minutes + */ + getMinutes(): number { + return this.eorzeaDate.getUTCMinutes(); + } + + /** + * Returns Eorzean seconds + */ + getSeconds(): number { + return this.eorzeaDate.getUTCSeconds(); + } + + /** + * Returns Eorzean timestamp + */ + getTime(): number { + return this.eorzeaDate.getTime(); + } + + getPrettyTime(): string { + const hours: string = this.getHours().toString(); + let minutes: string = this.getMinutes().toString(); + if (minutes.length === 1) minutes = '0' + minutes; + return `${hours}:${minutes}`; + } + + public static fromRealTime(realDate: Date): EorzeaTime { + return new EorzeaTime(realDate); + } + + public static fromEorzeaTime(eorzeaDate: Date): EorzeaTime { + return new EorzeaTime(new Date(eorzeaDate.getTime() / (3600 / 175))); + } + +} \ No newline at end of file diff --git a/vite.config.js b/vite.config.js new file mode 100644 index 0000000..5c45e1d --- /dev/null +++ b/vite.config.js @@ -0,0 +1,16 @@ +import { fileURLToPath, URL } from 'node:url' + +import { defineConfig } from 'vite' +import vue from '@vitejs/plugin-vue' + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [ + vue(), + ], + resolve: { + alias: { + '@': fileURLToPath(new URL('./src', import.meta.url)) + } + } +})