runescape
Version:
A library to interact with the non-existent RuneScape API.
1,227 lines (1,212 loc) • 50.6 kB
JavaScript
var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
// source/utility/error.ts
var ErrorCode = {
// Profile.
/**
* The generic error when fetching a player's profile data as viewed on RuneMetrics.
*/
ProfileError: "ProfileError",
/**
* This seems to be returned on banned players.
*/
ProfileNotAMember: "ProfileNotAMember",
/**
* The RuneMetrics profile of this player is not public.
*/
ProfilePrivate: "ProfilePrivate",
/**
* It is supposable this player does not exist.
*/
ProfileNone: "ProfileNone"
};
var Messages = {
/**
* The generic error when fetching a player's profile data as viewed on RuneMetrics.
*/
[ErrorCode.ProfileError]: "Failed to fetch the RuneMetrics profile of this player.",
/**
* This seems to be returned on banned players.
*/
[ErrorCode.ProfileNotAMember]: "This player is banned.",
/**
* The RuneMetrics profile of this player is not public.
*/
[ErrorCode.ProfilePrivate]: "This player's RuneMetrics profile is not public.",
/**
* It is supposable this player does not exist.
*/
[ErrorCode.ProfileNone]: "Unknown player."
};
var RuneScapeAPIError = class extends Error {
static {
__name(this, "RuneScapeAPIError");
}
/**
* The status code of the error.
*/
statusCode;
/**
* The fully quallified URL of the request.
*/
url;
/**
* Constructs an error for the API.
*
* @param name - The name of this error
* @param statusCode - The status code of the error
* @param url - The fully quallified URL of the request
*/
constructor(name, statusCode, url) {
super(name);
this.statusCode = statusCode;
this.url = url;
}
};
var RuneScapeError = class extends Error {
static {
__name(this, "RuneScapeError");
}
/**
* The defined error code.
*/
code;
/**
* The raw error that yielded this error.
*/
rawCode;
/**
* The fully quallified URL of the request.
*/
url;
/**
* Constructs a defined error from the library.
*
* @param code - The defined error code
* @param rawCode - The raw error that yielded this error
* @param url - The fully quallified URL of the request
*/
constructor(code, rawCode, url) {
super(Messages[code]);
this.code = code;
this.rawCode = rawCode;
this.url = url;
}
get name() {
return `${super.name} [${this.rawCode}]`;
}
};
// source/clan.ts
import { parse } from "csv-parse/sync";
// source/utility/make-request.ts
function makeRequest(url, abortSignal) {
const options = {};
if (abortSignal) {
options.signal = abortSignal;
}
return fetch(url, options);
}
__name(makeRequest, "makeRequest");
// source/clan.ts
var ClanRank = /* @__PURE__ */ ((ClanRank2) => {
ClanRank2[ClanRank2["Owner"] = 0] = "Owner";
ClanRank2[ClanRank2["DeputyOwner"] = 1] = "DeputyOwner";
ClanRank2[ClanRank2["Overseer"] = 2] = "Overseer";
ClanRank2[ClanRank2["Coordinator"] = 3] = "Coordinator";
ClanRank2[ClanRank2["Organiser"] = 4] = "Organiser";
ClanRank2[ClanRank2["Administrator"] = 5] = "Administrator";
ClanRank2[ClanRank2["General"] = 6] = "General";
ClanRank2[ClanRank2["Captain"] = 7] = "Captain";
ClanRank2[ClanRank2["Lieutenant"] = 8] = "Lieutenant";
ClanRank2[ClanRank2["Sergeant"] = 9] = "Sergeant";
ClanRank2[ClanRank2["Corporal"] = 10] = "Corporal";
ClanRank2[ClanRank2["Recruit"] = 11] = "Recruit";
return ClanRank2;
})(ClanRank || {});
var APIClanRankToClanRank = {
Owner: 0 /* Owner */,
"Deputy Owner": 1 /* DeputyOwner */,
Overseer: 2 /* Overseer */,
Coordinator: 3 /* Coordinator */,
Organiser: 4 /* Organiser */,
Administrator: 5 /* Administrator */,
General: 6 /* General */,
Captain: 7 /* Captain */,
Lieutenant: 8 /* Lieutenant */,
Sergeant: 9 /* Sergeant */,
Corporal: 10 /* Corporal */,
Recruit: 11 /* Recruit */
};
async function fetchClanMembers({
clanName,
abortSignal
}) {
const url = `https://secure.runescape.com/m=clan-hiscores/members_lite.ws?clanName=${clanName}`;
const response = await makeRequest(url, abortSignal);
if (!response.ok) {
throw new RuneScapeAPIError("Error fetching clan members.", response.status, url);
}
const text = await response.text();
return parse(text, {
cast: /* @__PURE__ */ __name((value, { column }) => (
// Spaces in player names are "�".
column === "clanmate" ? value.replace(/�/g, " ") : column === "clanRank" ? APIClanRankToClanRank[value] : column === "totalXP" || column === "kills" ? Number(value) : value
), "cast"),
columns: /* @__PURE__ */ __name(() => [
{ name: "clanmate" },
{ name: "clanRank" },
{ name: "totalXP" },
{ name: "kills" }
], "columns"),
trim: true
});
}
__name(fetchClanMembers, "fetchClanMembers");
// source/guthixian-cache.ts
function guthixianCache(timestamp) {
return new Date(timestamp).getUTCHours() % 3 === 0;
}
__name(guthixianCache, "guthixianCache");
// source/hi-scores.ts
var Skill = /* @__PURE__ */ ((Skill2) => {
Skill2["Agility"] = "Agility";
Skill2["Archaeology"] = "Archaeology";
Skill2["Attack"] = "Attack";
Skill2["Constitution"] = "Constitution";
Skill2["Construction"] = "Construction";
Skill2["Cooking"] = "Cooking";
Skill2["Crafting"] = "Crafting";
Skill2["Defence"] = "Defence";
Skill2["Divination"] = "Divination";
Skill2["Dungeoneering"] = "Dungeoneering";
Skill2["Farming"] = "Farming";
Skill2["Firemaking"] = "Firemaking";
Skill2["Fishing"] = "Fishing";
Skill2["Fletching"] = "Fletching";
Skill2["Herblore"] = "Herblore";
Skill2["Hunter"] = "Hunter";
Skill2["Invention"] = "Invention";
Skill2["Magic"] = "Magic";
Skill2["Mining"] = "Mining";
Skill2["Prayer"] = "Prayer";
Skill2["Ranged"] = "Ranged";
Skill2["Runecrafting"] = "Runecrafting";
Skill2["Slayer"] = "Slayer";
Skill2["Smithing"] = "Smithing";
Skill2["Strength"] = "Strength";
Skill2["Summoning"] = "Summoning";
Skill2["Thieving"] = "Thieving";
Skill2["Woodcutting"] = "Woodcutting";
return Skill2;
})(Skill || {});
async function hiScore({ name, abortSignal }) {
const urlSearchParams = new URLSearchParams();
urlSearchParams.set("player", name);
const url = `https://secure.runescape.com/m=hiscore/index_lite.ws?${urlSearchParams}`;
const response = await makeRequest(url, abortSignal);
if (!response.ok) {
throw new RuneScapeAPIError("Error fetching HiScore data.", response.status, url);
}
const body = await response.text();
const dataLine = body.split("\n").map((line) => line.split(","));
return {
total: {
name: "Total",
rank: Number(dataLine[0][0]),
level: Number(dataLine[0][1]),
totalXP: Number(dataLine[0][2])
},
attack: {
name: "Attack" /* Attack */,
rank: Number(dataLine[1][0]),
level: Number(dataLine[1][1]),
totalXP: Number(dataLine[1][2])
},
defence: {
name: "Defence" /* Defence */,
rank: Number(dataLine[2][0]),
level: Number(dataLine[2][1]),
totalXP: Number(dataLine[2][2])
},
strength: {
name: "Strength" /* Strength */,
rank: Number(dataLine[3][0]),
level: Number(dataLine[3][1]),
totalXP: Number(dataLine[3][2])
},
constitution: {
name: "Constitution" /* Constitution */,
rank: Number(dataLine[4][0]),
level: Number(dataLine[4][1]),
totalXP: Number(dataLine[4][2])
},
ranged: {
name: "Ranged" /* Ranged */,
rank: Number(dataLine[5][0]),
level: Number(dataLine[5][1]),
totalXP: Number(dataLine[5][2])
},
prayer: {
name: "Prayer" /* Prayer */,
rank: Number(dataLine[6][0]),
level: Number(dataLine[6][1]),
totalXP: Number(dataLine[6][2])
},
magic: {
name: "Magic" /* Magic */,
rank: Number(dataLine[7][0]),
level: Number(dataLine[7][1]),
totalXP: Number(dataLine[7][2])
},
cooking: {
name: "Cooking" /* Cooking */,
rank: Number(dataLine[8][0]),
level: Number(dataLine[8][1]),
totalXP: Number(dataLine[8][2])
},
woodcutting: {
name: "Woodcutting" /* Woodcutting */,
rank: Number(dataLine[9][0]),
level: Number(dataLine[9][1]),
totalXP: Number(dataLine[9][2])
},
fletching: {
name: "Fletching" /* Fletching */,
rank: Number(dataLine[10][0]),
level: Number(dataLine[10][1]),
totalXP: Number(dataLine[10][2])
},
fishing: {
name: "Fishing" /* Fishing */,
rank: Number(dataLine[11][0]),
level: Number(dataLine[11][1]),
totalXP: Number(dataLine[11][2])
},
firemaking: {
name: "Firemaking" /* Firemaking */,
rank: Number(dataLine[12][0]),
level: Number(dataLine[12][1]),
totalXP: Number(dataLine[12][2])
},
crafting: {
name: "Crafting" /* Crafting */,
rank: Number(dataLine[13][0]),
level: Number(dataLine[13][1]),
totalXP: Number(dataLine[13][2])
},
smithing: {
name: "Smithing" /* Smithing */,
rank: Number(dataLine[14][0]),
level: Number(dataLine[14][1]),
totalXP: Number(dataLine[14][2])
},
mining: {
name: "Mining" /* Mining */,
rank: Number(dataLine[15][0]),
level: Number(dataLine[15][1]),
totalXP: Number(dataLine[15][2])
},
herblore: {
name: "Herblore" /* Herblore */,
rank: Number(dataLine[16][0]),
level: Number(dataLine[16][1]),
totalXP: Number(dataLine[16][2])
},
agility: {
name: "Agility" /* Agility */,
rank: Number(dataLine[17][0]),
level: Number(dataLine[17][1]),
totalXP: Number(dataLine[17][2])
},
thieving: {
name: "Thieving" /* Thieving */,
rank: Number(dataLine[18][0]),
level: Number(dataLine[18][1]),
totalXP: Number(dataLine[18][2])
},
slayer: {
name: "Slayer" /* Slayer */,
rank: Number(dataLine[19][0]),
level: Number(dataLine[19][1]),
totalXP: Number(dataLine[19][2])
},
farming: {
name: "Farming" /* Farming */,
rank: Number(dataLine[20][0]),
level: Number(dataLine[20][1]),
totalXP: Number(dataLine[20][2])
},
runecrafting: {
name: "Runecrafting" /* Runecrafting */,
rank: Number(dataLine[21][0]),
level: Number(dataLine[21][1]),
totalXP: Number(dataLine[21][2])
},
hunter: {
name: "Hunter" /* Hunter */,
rank: Number(dataLine[22][0]),
level: Number(dataLine[22][1]),
totalXP: Number(dataLine[22][2])
},
construction: {
name: "Construction" /* Construction */,
rank: Number(dataLine[23][0]),
level: Number(dataLine[23][1]),
totalXP: Number(dataLine[23][2])
},
summoning: {
name: "Summoning" /* Summoning */,
rank: Number(dataLine[24][0]),
level: Number(dataLine[24][1]),
totalXP: Number(dataLine[24][2])
},
dungeoneering: {
name: "Dungeoneering" /* Dungeoneering */,
rank: Number(dataLine[25][0]),
level: Number(dataLine[25][1]),
totalXP: Number(dataLine[25][2])
},
divination: {
name: "Divination" /* Divination */,
rank: Number(dataLine[26][0]),
level: Number(dataLine[26][1]),
totalXP: Number(dataLine[26][2])
},
invention: {
name: "Invention" /* Invention */,
rank: Number(dataLine[27][0]),
level: Number(dataLine[27][1]),
totalXP: Number(dataLine[27][2])
},
archaeology: {
name: "Archaeology" /* Archaeology */,
rank: Number(dataLine[28][0]),
level: Number(dataLine[28][1]),
totalXP: Number(dataLine[28][2])
}
};
}
__name(hiScore, "hiScore");
async function groupIronman({
groupSize,
size,
page,
isCompetitive,
abortSignal
}) {
const urlSearchParams = new URLSearchParams();
urlSearchParams.set("groupSize", String(groupSize));
if (size !== void 0) {
urlSearchParams.set("size", String(size));
}
if (page !== void 0) {
urlSearchParams.set("page", String(page));
}
if (isCompetitive !== void 0) {
urlSearchParams.set("isCompetitive", String(isCompetitive));
}
const url = `https://secure.runescape.com/m=runescape_gim_hiscores/v1/groupScores?${urlSearchParams}`;
const response = await makeRequest(url, abortSignal);
if (!response.ok) {
throw new RuneScapeAPIError("Error fetching Group Ironman HiScore data.", response.status, url);
}
return response.json();
}
__name(groupIronman, "groupIronman");
// source/utility/functions.ts
var MULTI = 0x5deece66dn;
var MASK = 281474976710656n;
var c0 = 0xe66dn;
var c1 = 0xdeecn;
var c2 = 0x0005n;
var chunk = 65536n;
function runedate(timestamp) {
return Math.floor((timestamp - Date.UTC(2002, 1, 27)) / 864e5 * 100) / 100;
}
__name(runedate, "runedate");
function multiplyAvoidLimit(seed) {
const s0 = seed % chunk;
const s1 = BigInt(Math.floor(Number(seed / chunk))) % chunk;
const s2 = BigInt(Math.floor(Number(seed / chunk / chunk)));
let carry = 11n;
let r0 = s0 * c0 + carry;
carry = BigInt(Math.floor(Number(r0 / chunk)));
r0 %= chunk;
let r1 = s1 * c0 + s0 * c1 + carry;
carry = BigInt(Math.floor(Number(r1 / chunk)));
r1 %= chunk;
let r2 = s2 * c0 + s1 * c1 + s0 * c2 + carry;
r2 %= chunk;
return r2 * chunk * chunk + r1 * chunk + r0;
}
__name(multiplyAvoidLimit, "multiplyAvoidLimit");
function nextInt(seed, no, repeats = 1) {
let computedSeed = seed ^ MULTI % MASK;
for (let index = 0; index < repeats; index++) {
computedSeed = multiplyAvoidLimit(computedSeed);
}
computedSeed >>= 17n;
return computedSeed % no;
}
__name(nextInt, "nextInt");
function transformName(name, delimiter) {
return name.replaceAll(" ", delimiter);
}
__name(transformName, "transformName");
// source/jewels.ts
var Jewel = /* @__PURE__ */ ((Jewel2) => {
Jewel2["ApmekenAmethyst"] = "Apmeken Amethyst";
Jewel2["ScabariteCrystal"] = "Scabarite Crystal";
return Jewel2;
})(Jewel || {});
function jewel(timestamp) {
const slot = nextInt(BigInt(Math.trunc(runedate(timestamp))) * 2n ** 32n, 5n);
switch (slot) {
case 0n:
return "Scabarite Crystal" /* ScabariteCrystal */;
case 2n:
return "Apmeken Amethyst" /* ApmekenAmethyst */;
default:
return null;
}
}
__name(jewel, "jewel");
// source/miscellaneous.ts
function avatar({ name, width, height }) {
const urlSearchParams = new URLSearchParams();
if (width !== void 0) {
urlSearchParams.set("w", String(width));
}
if (height !== void 0) {
urlSearchParams.set("h", String(height));
}
return `https://secure.runescape.com/m=avatar-rs/${transformName(name, "%20")}/chat.png${String(urlSearchParams) ? `?${urlSearchParams}` : ""}`;
}
__name(avatar, "avatar");
var ClanPage = /* @__PURE__ */ ((ClanPage2) => {
ClanPage2["RuneInfo"] = "RuneInfo";
ClanPage2["RunePixels"] = "Runepixels";
ClanPage2["RuneScape"] = "RuneScape";
return ClanPage2;
})(ClanPage || {});
function clanPage({ clan }) {
return {
["RuneScape" /* RuneScape */]: `https://services.runescape.com/m=clan-home/clan/${transformName(clan, "%20")}`,
["RuneInfo" /* RuneInfo */]: `https://runeinfo.com/clan/${transformName(clan, "%20")}`,
["Runepixels" /* RunePixels */]: `https://runepixels.com/clans/${transformName(clan, "-")}`
};
}
__name(clanPage, "clanPage");
var PlayerPage = /* @__PURE__ */ ((PlayerPage2) => {
PlayerPage2["RuneInfo"] = "RuneInfo";
PlayerPage2["RuneMetrics"] = "RuneMetrics";
PlayerPage2["RunePixels"] = "Runepixels";
PlayerPage2["RuneScape"] = "RuneScape";
PlayerPage2["RuneTracker"] = "RuneTracker";
return PlayerPage2;
})(PlayerPage || {});
function playerPage({ name }) {
const urlSearchParams = new URLSearchParams();
urlSearchParams.set("user1", name);
return {
["RuneScape" /* RuneScape */]: `https://secure.runescape.com/m=hiscore/compare?${urlSearchParams}`,
["RuneMetrics" /* RuneMetrics */]: `https://apps.runescape.com/runemetrics/app/overview/player/${transformName(
name,
"%20"
)}`,
["RuneInfo" /* RuneInfo */]: `https://runeinfo.com/profile/${transformName(name, "%20")}`,
["Runepixels" /* RunePixels */]: `https://runepixels.com/players/${transformName(name, "-")}`,
["RuneTracker" /* RuneTracker */]: `https://runetracker.org/track-${transformName(name, "+")}`
};
}
__name(playerPage, "playerPage");
async function playerCount({ abortSignal } = {}) {
const urlSearchParams = new URLSearchParams();
urlSearchParams.set("varname", "iPlayerCount");
urlSearchParams.set("callback", "jQuery000000000000000_0000000000");
const url = `https://runescape.com/player_count.js?${urlSearchParams}`;
const response = await makeRequest(url, abortSignal);
if (!response.ok) {
throw new RuneScapeAPIError("Error fetching the player count.", response.status, url);
}
const body = await response.text();
return Number(body.slice(body.indexOf("(") + 1, body.indexOf(")")));
}
__name(playerCount, "playerCount");
async function createdAccounts({
abortSignal
} = {}) {
const url = "https://secure.runescape.com/m=account-creation-reports/rsusertotal.ws";
const response = await makeRequest(url, abortSignal);
if (!response.ok) {
throw new RuneScapeAPIError(
"Error fetching the amount of created accounts.",
response.status,
url
);
}
const body = await response.json();
return {
accounts: body.accounts,
accountsFormatted: body.accountsformatted
};
}
__name(createdAccounts, "createdAccounts");
// source/player-details.ts
async function playerDetails({
names,
abortSignal
}) {
const urlSearchParams = new URLSearchParams();
urlSearchParams.set("names", JSON.stringify(names));
urlSearchParams.set("callback", "jQuery000000000000000_0000000000");
const response = await makeRequest(
`https://secure.runescape.com/m=website-data/playerDetails.ws?${urlSearchParams}`,
abortSignal
);
const body = await response.text();
const json = JSON.parse(body.slice(body.indexOf("["), body.indexOf("]") + 1));
return json.map(({ isSuffix, recruiting, name, clan, title }) => ({
isSuffix,
recruiting: recruiting ?? null,
name,
clan: clan ?? null,
title: title === "" ? null : title
}));
}
__name(playerDetails, "playerDetails");
// source/raven.ts
var INITIAL_TIMESTAMP = Date.UTC(2014, 9, 4);
function raven(timestamp) {
return Math.floor((timestamp - INITIAL_TIMESTAMP) / 864e5) % 13 === 0;
}
__name(raven, "raven");
// source/rune-metrics.ts
import dayjs from "dayjs";
import utc from "dayjs/plugin/utc.js";
var SkillId = /* @__PURE__ */ ((SkillId2) => {
SkillId2[SkillId2["Attack"] = 0] = "Attack";
SkillId2[SkillId2["Defence"] = 1] = "Defence";
SkillId2[SkillId2["Strength"] = 2] = "Strength";
SkillId2[SkillId2["Constitution"] = 3] = "Constitution";
SkillId2[SkillId2["Ranged"] = 4] = "Ranged";
SkillId2[SkillId2["Prayer"] = 5] = "Prayer";
SkillId2[SkillId2["Magic"] = 6] = "Magic";
SkillId2[SkillId2["Cooking"] = 7] = "Cooking";
SkillId2[SkillId2["Woodcutting"] = 8] = "Woodcutting";
SkillId2[SkillId2["Fletching"] = 9] = "Fletching";
SkillId2[SkillId2["Fishing"] = 10] = "Fishing";
SkillId2[SkillId2["Firemaking"] = 11] = "Firemaking";
SkillId2[SkillId2["Crafting"] = 12] = "Crafting";
SkillId2[SkillId2["Smithing"] = 13] = "Smithing";
SkillId2[SkillId2["Mining"] = 14] = "Mining";
SkillId2[SkillId2["Herblore"] = 15] = "Herblore";
SkillId2[SkillId2["Agility"] = 16] = "Agility";
SkillId2[SkillId2["Thieving"] = 17] = "Thieving";
SkillId2[SkillId2["Slayer"] = 18] = "Slayer";
SkillId2[SkillId2["Farming"] = 19] = "Farming";
SkillId2[SkillId2["Runecrafting"] = 20] = "Runecrafting";
SkillId2[SkillId2["Hunter"] = 21] = "Hunter";
SkillId2[SkillId2["Construction"] = 22] = "Construction";
SkillId2[SkillId2["Summoning"] = 23] = "Summoning";
SkillId2[SkillId2["Dungeoneering"] = 24] = "Dungeoneering";
SkillId2[SkillId2["Divination"] = 25] = "Divination";
SkillId2[SkillId2["Invention"] = 26] = "Invention";
SkillId2[SkillId2["Archaeology"] = 27] = "Archaeology";
return SkillId2;
})(SkillId || {});
dayjs.extend(utc);
async function profile({ name, activities, abortSignal }) {
const urlSearchParams = new URLSearchParams();
urlSearchParams.set("user", name);
if (activities !== void 0) {
urlSearchParams.set("activities", String(activities));
}
const url = `https://apps.runescape.com/runemetrics/profile?${urlSearchParams}`;
const response = await makeRequest(url, abortSignal);
if (!response.ok) {
throw new RuneScapeAPIError("Error fetching RuneMetrics profile data.", response.status, url);
}
const body = await response.json();
if ("error" in body) {
let code;
switch (body.error) {
case "NOT_A_MEMBER" /* NotAMember */:
code = ErrorCode.ProfileNotAMember;
break;
case "PROFILE_PRIVATE" /* ProfilePrivate */:
code = ErrorCode.ProfilePrivate;
break;
case "NO_PROFILE" /* NoProfile */:
code = ErrorCode.ProfileNone;
break;
default:
code = ErrorCode.ProfileError;
}
throw new RuneScapeError(code, body.error, url);
}
const {
magic,
questsstarted,
totalskill,
questscomplete,
questsnotstarted,
totalxp,
ranged,
activities: rawActivities,
skillvalues,
name: rawName,
rank,
melee,
combatlevel,
loggedIn
} = body;
return {
magic,
questsStarted: questsstarted,
totalSkill: totalskill,
questsComplete: questscomplete,
questsNotStarted: questsnotstarted,
totalXp: totalxp,
ranged,
activities: rawActivities.map(({ date, details, text }) => ({
timestamp: dayjs.utc(date, "Europe/London").valueOf(),
details,
text
})),
skillValues: skillvalues.map(({ level, xp, rank: rank2, id }) => ({
level,
xp: xp / 10,
rank: rank2,
id
})),
name: rawName,
rank,
melee,
combatLevel: combatlevel,
loggedIn: loggedIn === "true"
};
}
__name(profile, "profile");
var QuestDifficulty = /* @__PURE__ */ ((QuestDifficulty2) => {
QuestDifficulty2[QuestDifficulty2["Novice"] = 0] = "Novice";
QuestDifficulty2[QuestDifficulty2["Intermediate"] = 1] = "Intermediate";
QuestDifficulty2[QuestDifficulty2["Experienced"] = 2] = "Experienced";
QuestDifficulty2[QuestDifficulty2["Master"] = 3] = "Master";
QuestDifficulty2[QuestDifficulty2["Grandmaster"] = 4] = "Grandmaster";
QuestDifficulty2[QuestDifficulty2["Special"] = 250] = "Special";
return QuestDifficulty2;
})(QuestDifficulty || {});
var QuestStatus = /* @__PURE__ */ ((QuestStatus2) => {
QuestStatus2["Completed"] = "COMPLETED";
QuestStatus2["NotStarted"] = "NOT_STARTED";
QuestStatus2["Started"] = "STARTED";
return QuestStatus2;
})(QuestStatus || {});
var QuestTitle = /* @__PURE__ */ ((QuestTitle2) => {
QuestTitle2["AChristmasReunion"] = "A Christmas Reunion";
QuestTitle2["AClockworkSyringe"] = "A Clockwork Syringe";
QuestTitle2["AFairyTaleIGrowingPains"] = "A Fairy Tale I - Growing Pains";
QuestTitle2["AFairyTaleIICureaQueen"] = "A Fairy Tale II - Cure a Queen";
QuestTitle2["AFairyTaleIIIBattleatOrksRift"] = "A Fairy Tale III - Battle at Ork's Rift";
QuestTitle2["AGuildOfOurOwn"] = "A Guild of Our Own (miniquest)";
QuestTitle2["AShadowoverAshdale"] = "A Shadow over Ashdale";
QuestTitle2["ASoulsBane"] = "A Soul's Bane";
QuestTitle2["ATailOfTwoCats"] = "A Tail of Two Cats";
QuestTitle2["AVoidDance"] = "A Void Dance";
QuestTitle2["Aftermath"] = "Aftermath";
QuestTitle2["AllFiredUp"] = "All Fired Up";
QuestTitle2["AlphaVsOmega"] = "Alpha vs Omega";
QuestTitle2["AncientAwakening"] = "Ancient Awakening";
QuestTitle2["AnimalMagnetism"] = "Animal Magnetism";
QuestTitle2["AnotherSliceOfHAM"] = "Another Slice of H.A.M.";
QuestTitle2["AsaFirstResort"] = "As a First Resort";
QuestTitle2["AzzanadrasQuest"] = "Azzanadra's Quest";
QuestTitle2["BackToMyRoots"] = "Back to my Roots";
QuestTitle2["BackToTheFreezer"] = "Back to the Freezer";
QuestTitle2["BarCrawl"] = "Bar Crawl (miniquest)";
QuestTitle2["BattleOfForinthry"] = "Battle of Forinthry";
QuestTitle2["BattleOfTheMonolith"] = "Battle of the Monolith";
QuestTitle2["BeneathCursedTides"] = "Beneath Cursed Tides";
QuestTitle2["BeneathScabarasSands"] = "Beneath Scabaras' Sands";
QuestTitle2["BenedictsWorldTour"] = "Benedict's World Tour (miniquest)";
QuestTitle2["BetweenARock"] = "Between a Rock...";
QuestTitle2["BigChompyBirdHunting"] = "Big Chompy Bird Hunting";
QuestTitle2["Biohazard"] = "Biohazard";
QuestTitle2["BirthrightOfTheDwarves"] = "Birthright of the Dwarves";
QuestTitle2["BloodRunsDeep"] = "Blood Runs Deep";
QuestTitle2["BoricsTaskI"] = "Boric's Task I (miniquest)";
QuestTitle2["BoricsTaskII"] = "Boric's Task II (miniquest)";
QuestTitle2["BoricsTaskIII"] = "Boric's Task III (miniquest)";
QuestTitle2["BringingHomeTheBacon"] = "Bringing Home the Bacon";
QuestTitle2["BrokenHome"] = "Broken Home";
QuestTitle2["BuyersAndCellars"] = "Buyers and Cellars";
QuestTitle2["CabinFever"] = "Cabin Fever";
QuestTitle2["CallOfTheAncestors"] = "Call of the Ancestors";
QuestTitle2["CarnilleanRising"] = "Carnillean Rising";
QuestTitle2["CatapultConstruction"] = "Catapult Construction";
QuestTitle2["ChefsAssistant"] = "Chef's Assistant";
QuestTitle2["ChildrenOfMah"] = "Children of Mah";
QuestTitle2["CityOfSenntisten"] = "City of Senntisten";
QuestTitle2["CivilWarI"] = "Civil War I (miniquest)";
QuestTitle2["CivilWarII"] = "Civil War II (miniquest)";
QuestTitle2["CivilWarIII"] = "Civil War III (miniquest)";
QuestTitle2["ClockTower"] = "Clock Tower";
QuestTitle2["ColdWar"] = "Cold War";
QuestTitle2["Contact"] = "Contact!";
QuestTitle2["CooksAssistant"] = "Cook's Assistant";
QuestTitle2["CreatureOfFenkenstrain"] = "Creature of Fenkenstrain";
QuestTitle2["CrocodileTears"] = "Crocodile Tears";
QuestTitle2["CurseOfTheBlackStone"] = "Curse of the Black Stone";
QuestTitle2["DamageControl"] = "Damage Control (miniquest)";
QuestTitle2["DaughterOfChaos"] = "Daughter of Chaos";
QuestTitle2["DeadAndBuried"] = "Dead and Buried";
QuestTitle2["DeadliestCatch"] = "Deadliest Catch";
QuestTitle2["DealingwithScabaras"] = "Dealing with Scabaras";
QuestTitle2["DeathPlateau"] = "Death Plateau";
QuestTitle2["DeathToTheDorgeshuun"] = "Death to the Dorgeshuun";
QuestTitle2["DefenderOfVarrock"] = "Defender of Varrock";
QuestTitle2["DemonSlayer"] = "Demon Slayer";
QuestTitle2["DesertSlayerDungeon"] = "Desert Slayer Dungeon (miniquest)";
QuestTitle2["DesertTreasure"] = "Desert Treasure";
QuestTitle2["DesperateCreatures"] = "Desperate Creatures";
QuestTitle2["DesperateMeasures"] = "Desperate Measures";
QuestTitle2["DesperateTimes"] = "Desperate Times";
QuestTitle2["DeviousMinds"] = "Devious Minds";
QuestTitle2["DiamondInTheRough"] = "Diamond in the Rough";
QuestTitle2["DimensionOfDisaster"] = "Dimension of Disaster";
QuestTitle2["DimensionOfDisasterCoinOfTheRealm"] = "Dimension of Disaster: Coin of the Realm";
QuestTitle2["DimensionOfDisasterCurseOfArrav"] = "Dimension of Disaster: Curse of Arrav";
QuestTitle2["DimensionOfDisasterDefenderOfVarrock"] = "Dimension of Disaster: Defender of Varrock";
QuestTitle2["DimensionOfDisasterDemonSlayer"] = "Dimension of Disaster: Demon Slayer";
QuestTitle2["DimensionOfDisasterShieldOfArrav"] = "Dimension of Disaster: Shield of Arrav";
QuestTitle2["DishonourAmongThieves"] = "Dishonour among Thieves";
QuestTitle2["DoNoEvil"] = "Do No Evil";
QuestTitle2["DoricsTaskI"] = "Doric's Task I (miniquest)";
QuestTitle2["DoricsTaskII"] = "Doric's Task II (miniquest)";
QuestTitle2["DoricsTaskIII"] = "Doric's Task III (miniquest)";
QuestTitle2["DoricsTaskIV"] = "Doric's Task IV (miniquest)";
QuestTitle2["DoricsTaskV"] = "Doric's Task V (miniquest)";
QuestTitle2["DoricsTaskVI"] = "Doric's Task VI (miniquest)";
QuestTitle2["DoricsTaskVII"] = "Doric's Task VII (miniquest)";
QuestTitle2["DoricsTaskVIII"] = "Doric's Task VIII (miniquest)";
QuestTitle2["DragonSlayer"] = "Dragon Slayer";
QuestTitle2["DreamMentor"] = "Dream Mentor";
QuestTitle2["DruidicRitual"] = "Druidic Ritual";
QuestTitle2["DuckQuest"] = "Duck Quest";
QuestTitle2["DwarfCannon"] = "Dwarf Cannon";
QuestTitle2["EadgarsRuse"] = "Eadgar's Ruse";
QuestTitle2["EaglesPeak"] = "Eagles' Peak";
QuestTitle2["EclipseOfTheHeart"] = "Eclipse of the Heart";
QuestTitle2["ElementalWorkshopI"] = "Elemental Workshop I";
QuestTitle2["ElementalWorkshopII"] = "Elemental Workshop II";
QuestTitle2["ElementalWorkshopIII"] = "Elemental Workshop III";
QuestTitle2["ElementalWorkshopIV"] = "Elemental Workshop IV";
QuestTitle2["EnakhrasLament"] = "Enakhra's Lament";
QuestTitle2["EnlightenedJourney"] = "Enlightened Journey";
QuestTitle2["EnterTheAbyss"] = "Enter the Abyss (miniquest)";
QuestTitle2["ErnestTheChicken"] = "Ernest the Chicken";
QuestTitle2["EvilDavesBigDayOut"] = "Evil Dave's Big Day Out";
QuestTitle2["Extinction"] = "Extinction";
QuestTitle2["EyeForAnEye"] = "Eye for an Eye (miniquest)";
QuestTitle2["EyeOfHetI"] = "Eye of Het I";
QuestTitle2["EyeOfHetII"] = "Eye of Het II";
QuestTitle2["FamilyCrest"] = "Family Crest";
QuestTitle2["FateOfTheGods"] = "Fate of the Gods";
QuestTitle2["FatherAndSon"] = "Father and Son";
QuestTitle2["FieldOfScreams"] = "Field of Screams";
QuestTitle2["FightArena"] = "Fight Arena";
QuestTitle2["FinalDestination"] = "Final Destination (miniquest)";
QuestTitle2["Finale"] = "Finale";
QuestTitle2["FishingContest"] = "Fishing Contest";
QuestTitle2["FlagFall"] = "Flag Fall (miniquest)";
QuestTitle2["Flashback"] = "Flashback";
QuestTitle2["Foreshadowing"] = "Foreshadowing";
QuestTitle2["ForgettableTaleOfADrunkenDwarf"] = "Forgettable Tale of a Drunken Dwarf";
QuestTitle2["ForgivenessOfAChaosDwarf"] = "Forgiveness of a Chaos Dwarf";
QuestTitle2["Fortunes"] = "Fortunes";
QuestTitle2["FromTinyAcorns"] = "From Tiny Acorns (miniquest)";
QuestTitle2["FurNSeek"] = "Fur 'n Seek";
QuestTitle2["GardenOfTranquillity"] = "Garden of Tranquillity";
QuestTitle2["GertrudesCat"] = "Gertrude's Cat";
QuestTitle2["GhostsAhoy"] = "Ghosts Ahoy";
QuestTitle2["GhostsfromThePast"] = "Ghosts from the Past (miniquest)";
QuestTitle2["GloriousMemories"] = "Glorious Memories";
QuestTitle2["GoblinDiplomacy"] = "Goblin Diplomacy";
QuestTitle2["GowerQuest"] = "Gower Quest";
QuestTitle2["GreatEggSpectations"] = "Great Egg-spectations";
QuestTitle2["GrimTales"] = "Grim Tales";
QuestTitle2["GunnarsGround"] = "Gunnar's Ground";
QuestTitle2["GuysAndDolls"] = "Guys and Dolls";
QuestTitle2["Harbinger"] = "Harbinger (miniquest)";
QuestTitle2["HauntedMine"] = "Haunted Mine";
QuestTitle2["HazeelCult"] = "Hazeel Cult";
QuestTitle2["HeadOfTheFamily"] = "Head of the Family (miniquest)";
QuestTitle2["HeartOfStone"] = "Heart of Stone";
QuestTitle2["Heartstealer"] = "Heartstealer";
QuestTitle2["HelpingLaniakea"] = "Helping Laniakea";
QuestTitle2["HeroesQuest"] = "Heroes' Quest";
QuestTitle2["HerosWelcome"] = "Hero's Welcome";
QuestTitle2["HolyGrail"] = "Holy Grail";
QuestTitle2["HopespearsWill"] = "Hopespear's Will (miniquest)";
QuestTitle2["HorrorfromTheDeep"] = "Horror from the Deep";
QuestTitle2["HousingOfParliament"] = "Housing of Parliament";
QuestTitle2["HuntforRedRaktuber"] = "Hunt for Red Raktuber";
QuestTitle2["IcthlarinsLittleHelper"] = "Icthlarin's Little Helper";
QuestTitle2["ImpCatcher"] = "Imp Catcher";
QuestTitle2["ImpressingTheLocals"] = "Impressing the Locals";
QuestTitle2["InAidOfTheMyreque"] = "In Aid of the Myreque";
QuestTitle2["InMemoryOfTheMyreque"] = "In Memory of the Myreque (miniquest)";
QuestTitle2["InPyreNeed"] = "In Pyre Need";
QuestTitle2["InSearchOfTheMyreque"] = "In Search of the Myreque";
QuestTitle2["ItsSnowBother"] = "It's Snow Bother";
QuestTitle2["JedHunter"] = "Jed Hunter (miniquest)";
QuestTitle2["JunglePotion"] = "Jungle Potion";
QuestTitle2["KennithsConcerns"] = "Kennith's Concerns";
QuestTitle2["KiliRow"] = "Kili Row";
QuestTitle2["KindredSpirits"] = "Kindred Spirits";
QuestTitle2["KingOfTheDwarves"] = "King of the Dwarves";
QuestTitle2["KingsRansom"] = "King's Ransom";
QuestTitle2["KoscheisTroubles"] = "Koschei's Troubles (miniquest)";
QuestTitle2["LairOfTarnRazorlor"] = "Lair of Tarn Razorlor (miniquest)";
QuestTitle2["LandOfTheGoblins"] = "Land of the Goblins";
QuestTitle2["LegacyOfSeergaze"] = "Legacy of Seergaze";
QuestTitle2["LegendsQuest"] = "Legends' Quest";
QuestTitle2["LetThemEatPie"] = "Let Them Eat Pie";
QuestTitle2["LostCity"] = "Lost City";
QuestTitle2["LostHerMarbles"] = "Lost Her Marbles (miniquest)";
QuestTitle2["LoveStory"] = "Love Story";
QuestTitle2["LunarDiplomacy"] = "Lunar Diplomacy";
QuestTitle2["MahjarratMemories"] = "Mahjarrat Memories (miniquest)";
QuestTitle2["MakingHistory"] = "Making History";
QuestTitle2["MeetingHistory"] = "Meeting History";
QuestTitle2["MerlinsCrystal"] = "Merlin's Crystal";
QuestTitle2["MissingMyMummy"] = "Missing My Mummy";
QuestTitle2["MissingPresumedDeath"] = "Missing, Presumed Death";
QuestTitle2["MonkeyMadness"] = "Monkey Madness";
QuestTitle2["MonksFriend"] = "Monk's Friend";
QuestTitle2["MountainDaughter"] = "Mountain Daughter";
QuestTitle2["MourningsEndPartI"] = "Mourning's End Part I";
QuestTitle2["MourningsEndPartII"] = "Mourning's End Part II";
QuestTitle2["MurderMystery"] = "Murder Mystery";
QuestTitle2["MurderOnTheBorder"] = "Murder on the Border";
QuestTitle2["MyArmsBigAdventure"] = "My Arm's Big Adventure";
QuestTitle2["MythsOfTheWhiteLands"] = "Myths of the White Lands";
QuestTitle2["Nadir"] = "Nadir (saga)";
QuestTitle2["NatureSpirit"] = "Nature Spirit";
QuestTitle2["Necromancy"] = "Necromancy!";
QuestTitle2["NewFoundations"] = "New Foundations";
QuestTitle2["NomadsElegy"] = "Nomad's Elegy";
QuestTitle2["NomadsRequiem"] = "Nomad's Requiem";
QuestTitle2["ObservatoryQuest"] = "Observatory Quest";
QuestTitle2["OdeofTheDevourer"] = "Ode of the Devourer";
QuestTitle2["OlafsQuest"] = "Olaf's Quest";
QuestTitle2["OnceUponaSlime"] = "Once Upon a Slime";
QuestTitle2["OnceUponaTimeInGielinor"] = "Once Upon a Time in Gielinor";
QuestTitle2["OneFootInTheGrave"] = "One Foot in the Grave (miniquest)";
QuestTitle2["OneOfAKind"] = "One of a Kind";
QuestTitle2["OnePiercingNote"] = "One Piercing Note";
QuestTitle2["OneSmallFavour"] = "One Small Favour";
QuestTitle2["OsseousRex"] = "Osseous Rex";
QuestTitle2["OurManInTheNorth"] = "Our Man in the North";
QuestTitle2["PerilsOfIceMountain"] = "Perils of Ice Mountain";
QuestTitle2["PharaohsFolly"] = "Pharaoh's Folly";
QuestTitle2["PhiteClub"] = "'Phite Club";
QuestTitle2["PiecesOfHate"] = "Pieces of Hate";
QuestTitle2["PiratesTreasure"] = "Pirate's Treasure";
QuestTitle2["PlagueCity"] = "Plague City";
QuestTitle2["PlaguesEnd"] = "Plague's End";
QuestTitle2["PriestInPeril"] = "Priest in Peril";
QuestTitle2["PurpleCat"] = "Purple Cat (miniquest)";
QuestTitle2["QuietBeforeTheSwarm"] = "Quiet Before the Swarm";
QuestTitle2["RagAndBoneMan"] = "Rag and Bone Man";
QuestTitle2["RakshaTheShadowColossus"] = "Raksha, the Shadow Colossus";
QuestTitle2["RatCatchers"] = "Rat Catchers";
QuestTitle2["RebuildingEdgeville"] = "Rebuilding Edgeville (miniquest)";
QuestTitle2["RecipeforDisaster"] = "Recipe for Disaster";
QuestTitle2["RecipeforDisasterAnotherCooksQuest"] = "Recipe for Disaster: Another Cook's Quest";
QuestTitle2["RecipeforDisasterDefeatingTheCulinaromancer"] = "Recipe for Disaster: Defeating the Culinaromancer";
QuestTitle2["RecipeforDisasterFreeingEvilDave"] = "Recipe for Disaster: Freeing Evil Dave";
QuestTitle2["RecipeforDisasterFreeingKingAwowogei"] = "Recipe for Disaster: Freeing King Awowogei";
QuestTitle2["RecipeforDisasterFreeingPiratePete"] = "Recipe for Disaster: Freeing Pirate Pete";
QuestTitle2["RecipeforDisasterFreeingSirAmikVarze"] = "Recipe for Disaster: Freeing Sir Amik Varze";
QuestTitle2["RecipeforDisasterFreeingSkrachUglogwee"] = "Recipe for Disaster: Freeing Skrach Uglogwee";
QuestTitle2["RecipeforDisasterFreeingTheGoblinGenerals"] = "Recipe for Disaster: Freeing the Goblin Generals";
QuestTitle2["RecipeforDisasterFreeingTheLumbridgeSage"] = "Recipe for Disaster: Freeing the Lumbridge Sage";
QuestTitle2["RecipeforDisasterFreeingTheMountainDwarf"] = "Recipe for Disaster: Freeing the Mountain Dwarf";
QuestTitle2["RecruitmentDrive"] = "Recruitment Drive";
QuestTitle2["Regicide"] = "Regicide";
QuestTitle2["RemainsOfTheNecrolord"] = "Remains of the Necrolord";
QuestTitle2["RequiemForADragon"] = "Requiem for a Dragon";
QuestTitle2["RitualOfTheMahjarrat"] = "Ritual of the Mahjarrat";
QuestTitle2["RiverOfBlood"] = "River of Blood";
QuestTitle2["RockingOut"] = "Rocking Out";
QuestTitle2["RovingElves"] = "Roving Elves";
QuestTitle2["RoyalTrouble"] = "Royal Trouble";
QuestTitle2["RumDeal"] = "Rum Deal";
QuestTitle2["RuneMechanics"] = "Rune Mechanics";
QuestTitle2["RuneMemories"] = "Rune Memories";
QuestTitle2["RuneMysteries"] = "Rune Mysteries";
QuestTitle2["RuneMythos"] = "Rune Mythos";
QuestTitle2["SaltInTheWound"] = "Salt in the Wound";
QuestTitle2["ScorpionCatcher"] = "Scorpion Catcher";
QuestTitle2["SeaSlug"] = "Sea Slug";
QuestTitle2["ShadesOfMortton"] = "Shades of Mort'ton";
QuestTitle2["ShadowOfTheStorm"] = "Shadow of the Storm";
QuestTitle2["SheepHerder"] = "Sheep Herder";
QuestTitle2["SheepShearer"] = "Sheep Shearer (miniquest)";
QuestTitle2["ShieldOfArrav"] = "Shield of Arrav";
QuestTitle2["ShiloVillage"] = "Shilo Village";
QuestTitle2["SinsOfTheFather"] = "Sins of the Father (miniquest)";
QuestTitle2["SliskesEndgame"] = "Sliske's Endgame";
QuestTitle2["SmokingKills"] = "Smoking Kills";
QuestTitle2["SomeLikeItCold"] = "Some Like It Cold";
QuestTitle2["SongfromTheDepths"] = "Song from the Depths";
QuestTitle2["SoulSearching"] = "Soul Searching";
QuestTitle2["SpiritOfSummer"] = "Spirit of Summer";
QuestTitle2["SpiritsOfTheElid"] = "Spirits of the Elid";
QuestTitle2["SpiritualEnlightenment"] = "Spiritual Enlightenment (miniquest)";
QuestTitle2["StellarBorn"] = "Stellar Born";
QuestTitle2["StolenHearts"] = "Stolen Hearts";
QuestTitle2["Succession"] = "Succession";
QuestTitle2["SummersEnd"] = "Summer's End";
QuestTitle2["SwanSong"] = "Swan Song";
QuestTitle2["SweptAway"] = "Swept Away";
QuestTitle2["TaiBwoWannaiTrio"] = "Tai Bwo Wannai Trio";
QuestTitle2["TalesOfNomad"] = "Tales of Nomad (miniquest)";
QuestTitle2["TalesOfTheGodWars"] = "Tales of the God Wars (miniquest)";
QuestTitle2["TearsOfGuthix"] = "Tears of Guthix";
QuestTitle2["TempleOfIkov"] = "Temple of Ikov";
QuestTitle2["ThatOldBlackMagic"] = "That Old Black Magic";
QuestTitle2["TheBloodPact"] = "The Blood Pact";
QuestTitle2["TheBranchesOfDarkmeyer"] = "The Branches of Darkmeyer";
QuestTitle2["TheBrinkOfExtinction"] = "The Brink of Extinction";
QuestTitle2["TheChosenCommander"] = "The Chosen Commander";
QuestTitle2["TheCurseOfArrav"] = "The Curse of Arrav";
QuestTitle2["TheCurseOfZaros"] = "The Curse of Zaros (miniquest)";
QuestTitle2["TheDarknessOfHallowvale"] = "The Darkness of Hallowvale";
QuestTitle2["TheDeathOfChivalry"] = "The Death of Chivalry";
QuestTitle2["TheDigSite"] = "The Dig Site";
QuestTitle2["TheElderKiln"] = "The Elder Kiln";
QuestTitle2["TheEyesOfGlouphrie"] = "The Eyes of Glouphrie";
QuestTitle2["TheFeud"] = "The Feud";
QuestTitle2["TheFiremakersCurse"] = "The Firemaker's Curse";
QuestTitle2["TheFremennikIsles"] = "The Fremennik Isles";
QuestTitle2["TheFremennikTrials"] = "The Fremennik Trials";
QuestTitle2["TheGeneralsShadow"] = "The General's Shadow (miniquest)";
QuestTitle2["TheGiantDwarf"] = "The Giant Dwarf";
QuestTitle2["TheGolem"] = "The Golem";
QuestTitle2["TheGrandTree"] = "The Grand Tree";
QuestTitle2["TheGreatBrainRobbery"] = "The Great Brain Robbery";
QuestTitle2["TheHandInTheSand"] = "The Hand in the Sand";
QuestTitle2["TheHuntforSurok"] = "The Hunt for Surok (miniquest)";
QuestTitle2["TheJackOfSpades"] = "The Jack of Spades";
QuestTitle2["TheKnightsSword"] = "The Knight's Sword";
QuestTitle2["TheLightWithin"] = "The Light Within";
QuestTitle2["TheLordOfVampyrium"] = "The Lord of Vampyrium";
QuestTitle2["TheLostToys"] = "The Lost Toys (miniquest)";
QuestTitle2["TheLostTribe"] = "The Lost Tribe";
QuestTitle2["TheMightyFall"] = "The Mighty Fall";
QuestTitle2["TheNeedleSkips"] = "The Needle Skips";
QuestTitle2["ThePathOfGlouphrie"] = "The Path of Glouphrie";
QuestTitle2["ThePrisonerOfGlouphrie"] = "The Prisoner of Glouphrie";
QuestTitle2["TheRestlessGhost"] = "The Restless Ghost";
QuestTitle2["TheSlugMenace"] = "The Slug Menace";
QuestTitle2["TheSpiritOfWar"] = "The Spirit of War";
QuestTitle2["TheTaleOfTheMuspah"] = "The Tale of the Muspah";
QuestTitle2["TheTempleatSenntisten"] = "The Temple at Senntisten";
QuestTitle2["TheTouristTrap"] = "The Tourist Trap";
QuestTitle2["TheVaultOfShadows"] = "The Vault of Shadows";
QuestTitle2["TheVoidStaresBack"] = "The Void Stares Back";
QuestTitle2["TheWorldWakes"] = "The World Wakes";
QuestTitle2["ThokItToEm"] = "Thok It To 'Em (saga)";
QuestTitle2["ThokYourBlockOff"] = "Thok Your Block Off (saga)";
QuestTitle2["ThreesCompany"] = "Three's Company (saga)";
QuestTitle2["ThroneOfMiscellania"] = "Throne of Miscellania";
QuestTitle2["TokTzKetDill"] = "TokTz-Ket-Dill";
QuestTitle2["TomesOfTheWarlock"] = "Tomes of the Warlock";
QuestTitle2["TortleCombat"] = "Tortle Combat (miniquest)";
QuestTitle2["TowerOfLife"] = "Tower of Life";
QuestTitle2["TreeGnomeVillage"] = "Tree Gnome Village";
QuestTitle2["TribalTotem"] = "Tribal Totem";
QuestTitle2["TrollRomance"] = "Troll Romance";
QuestTitle2["TrollStronghold"] = "Troll Stronghold";
QuestTitle2["TuaiLeitsOwn"] = "Tuai Leit's Own (miniquest)";
QuestTitle2["TwilightOfTheGods"] = "Twilight of the Gods";
QuestTitle2["UndergroundPass"] = "Underground Pass";
QuestTitle2["UnstableFoundations"] = "Unstable Foundations";
QuestTitle2["UnwelcomeGuests"] = "Unwelcome Guests";
QuestTitle2["VampyreSlayer"] = "Vampyre Slayer";
QuestTitle2["Vengeance"] = "Vengeance (saga)";
QuestTitle2["VesselOfTheHarbinger"] = "Vessel of the Harbinger";
QuestTitle2["VioletisBlue"] = "Violet is Blue";
QuestTitle2["VioletisBlueToo"] = "Violet is Blue Too";
QuestTitle2["WanderingGaal"] = "Wandering Ga'al (miniquest)";
QuestTitle2["Wanted"] = "Wanted!";
QuestTitle2["Watchtower"] = "Watchtower";
QuestTitle2["WaterfallQuest"] = "Waterfall Quest";
QuestTitle2["WhatLiesBelow"] = "What Lies Below";
QuestTitle2["WhatsMineisYours"] = "What's Mine is Yours";
QuestTitle2["WhileGuthixSleeps"] = "While Guthix Sleeps";
QuestTitle2["WitchsHouse"] = "Witch's House";
QuestTitle2["WitchsPotion"] = "Witch's Potion (miniquest)";
QuestTitle2["WithinTheLight"] = "Within the Light";
QuestTitle2["WolfWhistle"] = "Wolf Whistle";
QuestTitle2["YouAreIt"] = "You Are It";
QuestTitle2["ZogreFleshEaters"] = "Zogre Flesh Eaters";
return QuestTitle2;
})(QuestTitle || {});
async function questDetails({
name,
abortSignal
}) {
const urlSearchParams = new URLSearchParams();
urlSearchParams.set("user", name);
const url = `https://apps.runescape.com/runemetrics/quests?${urlSearchParams}`;
const response = await makeRequest(url, abortSignal);
if (!response.ok) {
throw new RuneScapeAPIError("Error fetching quest data.", response.status, url);
}
const body = await response.json();
const { quests, loggedIn } = body;
return {
quests,
loggedIn: loggedIn === "true"
};
}
__name(questDetails, "questDetails");
// source/travelling-merchant.ts
var Item = /* @__PURE__ */ ((Item2) => {
Item2["AdvancedPulseCore"] = "Advanced pulse core";
Item2["AnimaCrystal"] = "Anima crystal";
Item2["BarrelOfBait"] = "Barrel of bait";
Item2["BrokenFishingRod"] = "Broken fishing rod";
Item2["CrystalTriskelion"] = "Crystal triskelion";
Item2["DDTokenDaily"] = "D&D token (daily)";
Item2["DDTokenMonthly"] = "D&D token (monthly)";
Item2["DDTokenWeekly"] = "D&D token (weekly)";
Item2["DeathtouchedDart"] = "Deathtouched dart";
Item2["DragonkinLamp"] = "Dragonkin Lamp";
Item2["DungeoneeringWildcard"] = "Dungeoneering Wildcard";
Item2["GiftForTheReaper"] = "Gift for the Reaper";
Item2["GoebieBurialCharm"] = "Goebie burial charm";
Item2["HarmonicDust"] = "Harmonic dust";
Item2["HornOfHonour"] = "Horn of honour";
Item2["LargeGoebieBurialCharm"] = "Large goebie burial charm";
Item2["LividPlant"] = "Livid plant";
Item2["MenaphiteGiftOfferingLarge"] = "Menaphite gift offering (large)";
Item2["MenaphiteGiftOfferingMedium"] = "Menaphite gift offering (medium)";
Item2["MenaphiteGiftOfferingSmall"] = "Menaphite gift offering (small)";
Item2["MessageInABottle"] = "Message in a bottle";
Item2["SacredClay"] = "Sacred clay";
Item2["ShatteredAnima"] = "Shattered anima";
Item2["SilverhawkDown"] = "Silverhawk down";
Item2["SlayerVIPCoupon"] = "Slayer VIP coupon";
Item2["SmallGoebieBurialCharm"] = "Small goebie burial charm";
Item2["StarvedAncientEffigy"] = "Starved ancient effigy";
Item2["Taijitu"] = "Taijitu";
Item2["TangledFishbowl"] = "Tangled fishbowl";
Item2["UnfocusedDamageEnhancer"] = "Unfocused damage enhancer";
Item2["UnfocusedRewardEnhancer"] = "Unfocused reward enhancer";
Item2["UnstableAirRune"] = "Unstable air rune";
return Item2;
})(Item || {});
var SLOT_1_AND_2 = [
"Gift for the Reaper" /* GiftForTheReaper */,
"Broken fishing rod" /* BrokenFishingRod */,
"Barrel of bait" /* BarrelOfBait */,
"Anima crystal" /* AnimaCrystal */,
"Small goebie burial charm" /* SmallGoebieBurialCharm */,
"Goebie burial charm" /* GoebieBurialCharm */,
"Menaphite gift offering (small)" /* MenaphiteGiftOfferingSmall */,
"Menaphite gift offering (medium)" /* MenaphiteGiftOfferingMedium */,
"Shattered anima" /* ShatteredAnima */,
"D&D token (daily)" /* DDTokenDaily */,
"Sacred clay" /* SacredClay */,
"Livid plant" /* LividPlant */,
"Slayer VIP coupon" /* SlayerVIPCoupon */,
"Silverhawk down" /* SilverhawkDown */,
"Unstable air rune" /* UnstableAirRune */,
"Advanced pulse core" /* AdvancedPulseCore */,
"Tangled fishbowl" /* TangledFishbowl */,
"Unfocused damage enhancer" /* UnfocusedDamageEnhancer */,
"Horn of honour" /* HornOfHonour */
];
var SLOTS = {
1: SLOT_1_AND_2,
2: SLOT_1_AND_2,
3: [
"Taijitu" /* Taijitu */,
"Large goebie burial charm" /* LargeGoebieBurialCharm */,
"Menaphite gift offering (large)" /* MenaphiteGiftOfferingLarge */,
"D&D token (weekly)" /* DDTokenWeekly */,
"D&D token (monthly)" /* DDTokenMonthly */,
"Dungeoneering Wildcard" /* DungeoneeringWildcard */,
"Message in a bottle" /* MessageInABottle */,
"Crystal triskelion" /* CrystalTriskelion */,
"Starved ancient effigy" /* StarvedAncientEffigy */,
"Deathtouched dart" /* DeathtouchedDart */,
"Dragonkin Lamp" /* DragonkinLamp */,
"Harmonic dust" /* HarmonicDust */,
"Unfocused reward enhancer" /* UnfocusedRewardEnhancer */
]
};
function getSlots(runedate2, n1, n2) {
const seed = runedate2 * 2 ** 32 + runedate2 % n1;
return nextInt(BigInt(Math.trunc(seed)), n2);
}
__name(getSlots, "getSlots");
function slot1(runedate2) {
const index = Number(getSlots(runedate2, 3, 19n));
return SLOTS[1][index];
}
__name(slot1, "slot1");
function slot2(runedate2) {
const index = Number(getSlots(runedate2, 8, 19n));
return SLOTS[2][index];
}
__name(slot2, "slot2");
function slot3(runedate2) {
const index = Number(getSlots(runedate2, 5, 13n));
return SLOTS[3][index];
}
__name(slot3, "slot3");
function stock(timestamp) {
const date = new Date(timestamp);
date.setUTCHours(0, 0, 0, 0);
const currentRunedate = runedate(date.getTime());
return [slot1(currentRunedate), slot2(currentRunedate), slot3(currentRunedate)];
}
__name(stock, "stock");
// source/wilderness-flash-event.ts
var INITIAL_TIMESTAMP2 = Date.UTC(2024, 1, 5, 12);
var WildernessFlashEvent = /* @__PURE__ */ ((WildernessFlashEvent2) => {
WildernessFlashEvent2["KingBlackDragonRampage"] = "King Black Dragon Rampage";
WildernessFlashEvent2["ForgottenSoldiers"] = "Forgotten Soldiers";
WildernessFlashEvent2["SurprisingSeedlings"] = "Surprising Seedlings";
WildernessFlashEvent2["HellhoundPack"] = "Hellhound Pack";
WildernessFlashEvent2["InfernalStar"] = "Infernal Star";
WildernessFlashEvent2["LostSouls"] = "Lost Souls";
WildernessFlashEvent2["RamokeeIncursion"] = "Ramokee Incursion";
WildernessFlashEvent2["DisplacedEnergy"] = "Displaced Energy";
WildernessFlashEvent2["EvilBloodwoodTree"] = "Evil Bloodwood Tree";
WildernessFlashEvent2["SpiderSwarm"] = "Spider Swarm";
WildernessFlashEvent2["UnnaturalOutcrop"] = "Unnatural Outcrop";
WildernessFlashEvent2["StrykeTheWyrm"] = "Stryke the Wyrm";
WildernessFlashEvent2["DemonStragglers"] = "Demon Stragglers";
WildernessFlashEvent2["ButterflySwarm"] = "Butterfly Swarm";
return WildernessFlashEvent2;
})(WildernessFlashEvent || {});
var WILDERNESS_FLASH_EVENTS = Object.values(WildernessFlashEvent);
var WILDERNESS_FLASH_EVENTS_LENGTH = WILDERNESS_FLASH_EVENTS.length;
function wildernessFlashEvent(timestamp) {
const hoursElapsed = Math.floor((timestamp - INITIAL_TIMESTAMP2) / 1e3 / 60 / 60);
return WILDERNESS_FLASH_EVENTS[hoursElapsed % WILDERNESS_FLASH_EVENTS_LENGTH];
}
__name(wildernessFlashEvent, "wildernessFlashEvent");
// source/wilderness-warbands.ts
function wildernessWarbands(timestamp) {
const date = new Date(timestamp);
const start = new Date(date);
start.setUTCDate(date.getUTCDate() - (date.getUTCDay() + 6) % 7);
start.setUTCHours(2, 0, 0, 0)