1567 lines
		
	
	
		
			51 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			1567 lines
		
	
	
		
			51 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /*
 | |
| THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
 | |
| if you want to view the source, please visit the github repository of this plugin
 | |
| */
 | |
| 
 | |
| var __create = Object.create;
 | |
| var __defProp = Object.defineProperty;
 | |
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
 | |
| var __getOwnPropNames = Object.getOwnPropertyNames;
 | |
| var __getProtoOf = Object.getPrototypeOf;
 | |
| var __hasOwnProp = Object.prototype.hasOwnProperty;
 | |
| var __commonJS = (cb, mod) => function __require() {
 | |
|   return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
 | |
| };
 | |
| var __export = (target, all) => {
 | |
|   for (var name in all)
 | |
|     __defProp(target, name, { get: all[name], enumerable: true });
 | |
| };
 | |
| var __copyProps = (to, from, except, desc) => {
 | |
|   if (from && typeof from === "object" || typeof from === "function") {
 | |
|     for (let key of __getOwnPropNames(from))
 | |
|       if (!__hasOwnProp.call(to, key) && key !== except)
 | |
|         __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
 | |
|   }
 | |
|   return to;
 | |
| };
 | |
| var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
 | |
|   // If the importer is in node compatibility mode or this is not an ESM
 | |
|   // file that has been converted to a CommonJS file using a Babel-
 | |
|   // compatible transform (i.e. "__esModule" has not been set), then set
 | |
|   // "default" to the CommonJS "module.exports" for node compatibility.
 | |
|   isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
 | |
|   mod
 | |
| ));
 | |
| var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
 | |
| 
 | |
| // (disabled):register-scheme
 | |
| var require_register_scheme = __commonJS({
 | |
|   "(disabled):register-scheme"() {
 | |
|   }
 | |
| });
 | |
| 
 | |
| // node_modules/discord-rpc/src/util.js
 | |
| var require_util = __commonJS({
 | |
|   "node_modules/discord-rpc/src/util.js"(exports, module2) {
 | |
|     "use strict";
 | |
|     var register;
 | |
|     try {
 | |
|       const { app } = require("electron");
 | |
|       register = app.setAsDefaultProtocolClient.bind(app);
 | |
|     } catch (err) {
 | |
|       try {
 | |
|         register = require_register_scheme();
 | |
|       } catch (e) {
 | |
|       }
 | |
|     }
 | |
|     if (typeof register !== "function") {
 | |
|       register = () => false;
 | |
|     }
 | |
|     function pid() {
 | |
|       if (typeof process !== "undefined") {
 | |
|         return process.pid;
 | |
|       }
 | |
|       return null;
 | |
|     }
 | |
|     var uuid4122 = () => {
 | |
|       let uuid = "";
 | |
|       for (let i = 0; i < 32; i += 1) {
 | |
|         if (i === 8 || i === 12 || i === 16 || i === 20) {
 | |
|           uuid += "-";
 | |
|         }
 | |
|         let n;
 | |
|         if (i === 12) {
 | |
|           n = 4;
 | |
|         } else {
 | |
|           const random = Math.random() * 16 | 0;
 | |
|           if (i === 16) {
 | |
|             n = random & 3 | 0;
 | |
|           } else {
 | |
|             n = random;
 | |
|           }
 | |
|         }
 | |
|         uuid += n.toString(16);
 | |
|       }
 | |
|       return uuid;
 | |
|     };
 | |
|     module2.exports = {
 | |
|       pid,
 | |
|       register,
 | |
|       uuid: uuid4122
 | |
|     };
 | |
|   }
 | |
| });
 | |
| 
 | |
| // node_modules/node-fetch/browser.js
 | |
| var require_browser = __commonJS({
 | |
|   "node_modules/node-fetch/browser.js"(exports, module2) {
 | |
|     "use strict";
 | |
|     var getGlobal = function() {
 | |
|       if (typeof self !== "undefined") {
 | |
|         return self;
 | |
|       }
 | |
|       if (typeof window !== "undefined") {
 | |
|         return window;
 | |
|       }
 | |
|       if (typeof global !== "undefined") {
 | |
|         return global;
 | |
|       }
 | |
|       throw new Error("unable to locate global object");
 | |
|     };
 | |
|     var globalObject = getGlobal();
 | |
|     module2.exports = exports = globalObject.fetch;
 | |
|     if (globalObject.fetch) {
 | |
|       exports.default = globalObject.fetch.bind(globalObject);
 | |
|     }
 | |
|     exports.Headers = globalObject.Headers;
 | |
|     exports.Request = globalObject.Request;
 | |
|     exports.Response = globalObject.Response;
 | |
|   }
 | |
| });
 | |
| 
 | |
| // node_modules/discord-rpc/src/transports/ipc.js
 | |
| var require_ipc = __commonJS({
 | |
|   "node_modules/discord-rpc/src/transports/ipc.js"(exports, module2) {
 | |
|     "use strict";
 | |
|     var net = require("net");
 | |
|     var EventEmitter = require("events");
 | |
|     var fetch = require_browser();
 | |
|     var { uuid } = require_util();
 | |
|     var OPCodes = {
 | |
|       HANDSHAKE: 0,
 | |
|       FRAME: 1,
 | |
|       CLOSE: 2,
 | |
|       PING: 3,
 | |
|       PONG: 4
 | |
|     };
 | |
|     function getIPCPath(id) {
 | |
|       if (process.platform === "win32") {
 | |
|         return `\\\\?\\pipe\\discord-ipc-${id}`;
 | |
|       }
 | |
|       const { env: { XDG_RUNTIME_DIR, TMPDIR, TMP, TEMP } } = process;
 | |
|       const prefix = XDG_RUNTIME_DIR || TMPDIR || TMP || TEMP || "/tmp";
 | |
|       return `${prefix.replace(/\/$/, "")}/discord-ipc-${id}`;
 | |
|     }
 | |
|     function getIPC(id = 0) {
 | |
|       return new Promise((resolve, reject) => {
 | |
|         const path = getIPCPath(id);
 | |
|         const onerror = () => {
 | |
|           if (id < 10) {
 | |
|             resolve(getIPC(id + 1));
 | |
|           } else {
 | |
|             reject(new Error("Could not connect"));
 | |
|           }
 | |
|         };
 | |
|         const sock = net.createConnection(path, () => {
 | |
|           sock.removeListener("error", onerror);
 | |
|           resolve(sock);
 | |
|         });
 | |
|         sock.once("error", onerror);
 | |
|       });
 | |
|     }
 | |
|     async function findEndpoint(tries = 0) {
 | |
|       if (tries > 30) {
 | |
|         throw new Error("Could not find endpoint");
 | |
|       }
 | |
|       const endpoint = `http://127.0.0.1:${6463 + tries % 10}`;
 | |
|       try {
 | |
|         const r = await fetch(endpoint);
 | |
|         if (r.status === 404) {
 | |
|           return endpoint;
 | |
|         }
 | |
|         return findEndpoint(tries + 1);
 | |
|       } catch (e) {
 | |
|         return findEndpoint(tries + 1);
 | |
|       }
 | |
|     }
 | |
|     function encode(op, data) {
 | |
|       data = JSON.stringify(data);
 | |
|       const len = Buffer.byteLength(data);
 | |
|       const packet = Buffer.alloc(8 + len);
 | |
|       packet.writeInt32LE(op, 0);
 | |
|       packet.writeInt32LE(len, 4);
 | |
|       packet.write(data, 8, len);
 | |
|       return packet;
 | |
|     }
 | |
|     var working = {
 | |
|       full: "",
 | |
|       op: void 0
 | |
|     };
 | |
|     function decode(socket, callback) {
 | |
|       const packet = socket.read();
 | |
|       if (!packet) {
 | |
|         return;
 | |
|       }
 | |
|       let { op } = working;
 | |
|       let raw;
 | |
|       if (working.full === "") {
 | |
|         op = working.op = packet.readInt32LE(0);
 | |
|         const len = packet.readInt32LE(4);
 | |
|         raw = packet.slice(8, len + 8);
 | |
|       } else {
 | |
|         raw = packet.toString();
 | |
|       }
 | |
|       try {
 | |
|         const data = JSON.parse(working.full + raw);
 | |
|         callback({ op, data });
 | |
|         working.full = "";
 | |
|         working.op = void 0;
 | |
|       } catch (err) {
 | |
|         working.full += raw;
 | |
|       }
 | |
|       decode(socket, callback);
 | |
|     }
 | |
|     var IPCTransport = class extends EventEmitter {
 | |
|       constructor(client) {
 | |
|         super();
 | |
|         this.client = client;
 | |
|         this.socket = null;
 | |
|       }
 | |
|       async connect() {
 | |
|         const socket = this.socket = await getIPC();
 | |
|         socket.on("close", this.onClose.bind(this));
 | |
|         socket.on("error", this.onClose.bind(this));
 | |
|         this.emit("open");
 | |
|         socket.write(encode(OPCodes.HANDSHAKE, {
 | |
|           v: 1,
 | |
|           client_id: this.client.clientId
 | |
|         }));
 | |
|         socket.pause();
 | |
|         socket.on("readable", () => {
 | |
|           decode(socket, ({ op, data }) => {
 | |
|             switch (op) {
 | |
|               case OPCodes.PING:
 | |
|                 this.send(data, OPCodes.PONG);
 | |
|                 break;
 | |
|               case OPCodes.FRAME:
 | |
|                 if (!data) {
 | |
|                   return;
 | |
|                 }
 | |
|                 if (data.cmd === "AUTHORIZE" && data.evt !== "ERROR") {
 | |
|                   findEndpoint().then((endpoint) => {
 | |
|                     this.client.request.endpoint = endpoint;
 | |
|                   }).catch((e) => {
 | |
|                     this.client.emit("error", e);
 | |
|                   });
 | |
|                 }
 | |
|                 this.emit("message", data);
 | |
|                 break;
 | |
|               case OPCodes.CLOSE:
 | |
|                 this.emit("close", data);
 | |
|                 break;
 | |
|               default:
 | |
|                 break;
 | |
|             }
 | |
|           });
 | |
|         });
 | |
|       }
 | |
|       onClose(e) {
 | |
|         this.emit("close", e);
 | |
|       }
 | |
|       send(data, op = OPCodes.FRAME) {
 | |
|         this.socket.write(encode(op, data));
 | |
|       }
 | |
|       async close() {
 | |
|         return new Promise((r) => {
 | |
|           this.once("close", r);
 | |
|           this.send({}, OPCodes.CLOSE);
 | |
|           this.socket.end();
 | |
|         });
 | |
|       }
 | |
|       ping() {
 | |
|         this.send(uuid(), OPCodes.PING);
 | |
|       }
 | |
|     };
 | |
|     module2.exports = IPCTransport;
 | |
|     module2.exports.encode = encode;
 | |
|     module2.exports.decode = decode;
 | |
|   }
 | |
| });
 | |
| 
 | |
| // node_modules/discord-rpc/src/constants.js
 | |
| var require_constants = __commonJS({
 | |
|   "node_modules/discord-rpc/src/constants.js"(exports) {
 | |
|     "use strict";
 | |
|     function keyMirror(arr) {
 | |
|       const tmp = {};
 | |
|       for (const value of arr) {
 | |
|         tmp[value] = value;
 | |
|       }
 | |
|       return tmp;
 | |
|     }
 | |
|     exports.browser = typeof window !== "undefined";
 | |
|     exports.RPCCommands = keyMirror([
 | |
|       "DISPATCH",
 | |
|       "AUTHORIZE",
 | |
|       "AUTHENTICATE",
 | |
|       "GET_GUILD",
 | |
|       "GET_GUILDS",
 | |
|       "GET_CHANNEL",
 | |
|       "GET_CHANNELS",
 | |
|       "CREATE_CHANNEL_INVITE",
 | |
|       "GET_RELATIONSHIPS",
 | |
|       "GET_USER",
 | |
|       "SUBSCRIBE",
 | |
|       "UNSUBSCRIBE",
 | |
|       "SET_USER_VOICE_SETTINGS",
 | |
|       "SET_USER_VOICE_SETTINGS_2",
 | |
|       "SELECT_VOICE_CHANNEL",
 | |
|       "GET_SELECTED_VOICE_CHANNEL",
 | |
|       "SELECT_TEXT_CHANNEL",
 | |
|       "GET_VOICE_SETTINGS",
 | |
|       "SET_VOICE_SETTINGS_2",
 | |
|       "SET_VOICE_SETTINGS",
 | |
|       "CAPTURE_SHORTCUT",
 | |
|       "SET_ACTIVITY",
 | |
|       "SEND_ACTIVITY_JOIN_INVITE",
 | |
|       "CLOSE_ACTIVITY_JOIN_REQUEST",
 | |
|       "ACTIVITY_INVITE_USER",
 | |
|       "ACCEPT_ACTIVITY_INVITE",
 | |
|       "INVITE_BROWSER",
 | |
|       "DEEP_LINK",
 | |
|       "CONNECTIONS_CALLBACK",
 | |
|       "BRAINTREE_POPUP_BRIDGE_CALLBACK",
 | |
|       "GIFT_CODE_BROWSER",
 | |
|       "GUILD_TEMPLATE_BROWSER",
 | |
|       "OVERLAY",
 | |
|       "BROWSER_HANDOFF",
 | |
|       "SET_CERTIFIED_DEVICES",
 | |
|       "GET_IMAGE",
 | |
|       "CREATE_LOBBY",
 | |
|       "UPDATE_LOBBY",
 | |
|       "DELETE_LOBBY",
 | |
|       "UPDATE_LOBBY_MEMBER",
 | |
|       "CONNECT_TO_LOBBY",
 | |
|       "DISCONNECT_FROM_LOBBY",
 | |
|       "SEND_TO_LOBBY",
 | |
|       "SEARCH_LOBBIES",
 | |
|       "CONNECT_TO_LOBBY_VOICE",
 | |
|       "DISCONNECT_FROM_LOBBY_VOICE",
 | |
|       "SET_OVERLAY_LOCKED",
 | |
|       "OPEN_OVERLAY_ACTIVITY_INVITE",
 | |
|       "OPEN_OVERLAY_GUILD_INVITE",
 | |
|       "OPEN_OVERLAY_VOICE_SETTINGS",
 | |
|       "VALIDATE_APPLICATION",
 | |
|       "GET_ENTITLEMENT_TICKET",
 | |
|       "GET_APPLICATION_TICKET",
 | |
|       "START_PURCHASE",
 | |
|       "GET_SKUS",
 | |
|       "GET_ENTITLEMENTS",
 | |
|       "GET_NETWORKING_CONFIG",
 | |
|       "NETWORKING_SYSTEM_METRICS",
 | |
|       "NETWORKING_PEER_METRICS",
 | |
|       "NETWORKING_CREATE_TOKEN",
 | |
|       "SET_USER_ACHIEVEMENT",
 | |
|       "GET_USER_ACHIEVEMENTS"
 | |
|     ]);
 | |
|     exports.RPCEvents = keyMirror([
 | |
|       "CURRENT_USER_UPDATE",
 | |
|       "GUILD_STATUS",
 | |
|       "GUILD_CREATE",
 | |
|       "CHANNEL_CREATE",
 | |
|       "RELATIONSHIP_UPDATE",
 | |
|       "VOICE_CHANNEL_SELECT",
 | |
|       "VOICE_STATE_CREATE",
 | |
|       "VOICE_STATE_DELETE",
 | |
|       "VOICE_STATE_UPDATE",
 | |
|       "VOICE_SETTINGS_UPDATE",
 | |
|       "VOICE_SETTINGS_UPDATE_2",
 | |
|       "VOICE_CONNECTION_STATUS",
 | |
|       "SPEAKING_START",
 | |
|       "SPEAKING_STOP",
 | |
|       "GAME_JOIN",
 | |
|       "GAME_SPECTATE",
 | |
|       "ACTIVITY_JOIN",
 | |
|       "ACTIVITY_JOIN_REQUEST",
 | |
|       "ACTIVITY_SPECTATE",
 | |
|       "ACTIVITY_INVITE",
 | |
|       "NOTIFICATION_CREATE",
 | |
|       "MESSAGE_CREATE",
 | |
|       "MESSAGE_UPDATE",
 | |
|       "MESSAGE_DELETE",
 | |
|       "LOBBY_DELETE",
 | |
|       "LOBBY_UPDATE",
 | |
|       "LOBBY_MEMBER_CONNECT",
 | |
|       "LOBBY_MEMBER_DISCONNECT",
 | |
|       "LOBBY_MEMBER_UPDATE",
 | |
|       "LOBBY_MESSAGE",
 | |
|       "CAPTURE_SHORTCUT_CHANGE",
 | |
|       "OVERLAY",
 | |
|       "OVERLAY_UPDATE",
 | |
|       "ENTITLEMENT_CREATE",
 | |
|       "ENTITLEMENT_DELETE",
 | |
|       "USER_ACHIEVEMENT_UPDATE",
 | |
|       "READY",
 | |
|       "ERROR"
 | |
|     ]);
 | |
|     exports.RPCErrors = {
 | |
|       CAPTURE_SHORTCUT_ALREADY_LISTENING: 5004,
 | |
|       GET_GUILD_TIMED_OUT: 5002,
 | |
|       INVALID_ACTIVITY_JOIN_REQUEST: 4012,
 | |
|       INVALID_ACTIVITY_SECRET: 5005,
 | |
|       INVALID_CHANNEL: 4005,
 | |
|       INVALID_CLIENTID: 4007,
 | |
|       INVALID_COMMAND: 4002,
 | |
|       INVALID_ENTITLEMENT: 4015,
 | |
|       INVALID_EVENT: 4004,
 | |
|       INVALID_GIFT_CODE: 4016,
 | |
|       INVALID_GUILD: 4003,
 | |
|       INVALID_INVITE: 4011,
 | |
|       INVALID_LOBBY: 4013,
 | |
|       INVALID_LOBBY_SECRET: 4014,
 | |
|       INVALID_ORIGIN: 4008,
 | |
|       INVALID_PAYLOAD: 4e3,
 | |
|       INVALID_PERMISSIONS: 4006,
 | |
|       INVALID_TOKEN: 4009,
 | |
|       INVALID_USER: 4010,
 | |
|       LOBBY_FULL: 5007,
 | |
|       NO_ELIGIBLE_ACTIVITY: 5006,
 | |
|       OAUTH2_ERROR: 5e3,
 | |
|       PURCHASE_CANCELED: 5008,
 | |
|       PURCHASE_ERROR: 5009,
 | |
|       RATE_LIMITED: 5011,
 | |
|       SELECT_CHANNEL_TIMED_OUT: 5001,
 | |
|       SELECT_VOICE_FORCE_REQUIRED: 5003,
 | |
|       SERVICE_UNAVAILABLE: 1001,
 | |
|       TRANSACTION_ABORTED: 1002,
 | |
|       UNAUTHORIZED_FOR_ACHIEVEMENT: 5010,
 | |
|       UNKNOWN_ERROR: 1e3
 | |
|     };
 | |
|     exports.RPCCloseCodes = {
 | |
|       CLOSE_NORMAL: 1e3,
 | |
|       CLOSE_UNSUPPORTED: 1003,
 | |
|       CLOSE_ABNORMAL: 1006,
 | |
|       INVALID_CLIENTID: 4e3,
 | |
|       INVALID_ORIGIN: 4001,
 | |
|       RATELIMITED: 4002,
 | |
|       TOKEN_REVOKED: 4003,
 | |
|       INVALID_VERSION: 4004,
 | |
|       INVALID_ENCODING: 4005
 | |
|     };
 | |
|     exports.LobbyTypes = {
 | |
|       PRIVATE: 1,
 | |
|       PUBLIC: 2
 | |
|     };
 | |
|     exports.RelationshipTypes = {
 | |
|       NONE: 0,
 | |
|       FRIEND: 1,
 | |
|       BLOCKED: 2,
 | |
|       PENDING_INCOMING: 3,
 | |
|       PENDING_OUTGOING: 4,
 | |
|       IMPLICIT: 5
 | |
|     };
 | |
|   }
 | |
| });
 | |
| 
 | |
| // (disabled):node_modules/ws/browser.js
 | |
| var require_browser2 = __commonJS({
 | |
|   "(disabled):node_modules/ws/browser.js"() {
 | |
|   }
 | |
| });
 | |
| 
 | |
| // node_modules/discord-rpc/src/transports/websocket.js
 | |
| var require_websocket = __commonJS({
 | |
|   "node_modules/discord-rpc/src/transports/websocket.js"(exports, module2) {
 | |
|     "use strict";
 | |
|     var EventEmitter = require("events");
 | |
|     var { browser } = require_constants();
 | |
|     var WebSocket = browser ? window.WebSocket : require_browser2();
 | |
|     var pack = (d) => JSON.stringify(d);
 | |
|     var unpack = (s) => JSON.parse(s);
 | |
|     var WebSocketTransport = class extends EventEmitter {
 | |
|       constructor(client) {
 | |
|         super();
 | |
|         this.client = client;
 | |
|         this.ws = null;
 | |
|         this.tries = 0;
 | |
|       }
 | |
|       async connect() {
 | |
|         const port = 6463 + this.tries % 10;
 | |
|         this.tries += 1;
 | |
|         this.ws = new WebSocket(
 | |
|           `ws://127.0.0.1:${port}/?v=1&client_id=${this.client.clientId}`,
 | |
|           browser ? void 0 : { origin: this.client.options.origin }
 | |
|         );
 | |
|         this.ws.onopen = this.onOpen.bind(this);
 | |
|         this.ws.onclose = this.onClose.bind(this);
 | |
|         this.ws.onerror = this.onError.bind(this);
 | |
|         this.ws.onmessage = this.onMessage.bind(this);
 | |
|       }
 | |
|       onOpen() {
 | |
|         this.emit("open");
 | |
|       }
 | |
|       onClose(event) {
 | |
|         if (!event.wasClean) {
 | |
|           return;
 | |
|         }
 | |
|         this.emit("close", event);
 | |
|       }
 | |
|       onError(event) {
 | |
|         try {
 | |
|           this.ws.close();
 | |
|         } catch (e) {
 | |
|         }
 | |
|         if (this.tries > 20) {
 | |
|           this.emit("error", event.error);
 | |
|         } else {
 | |
|           setTimeout(() => {
 | |
|             this.connect();
 | |
|           }, 250);
 | |
|         }
 | |
|       }
 | |
|       onMessage(event) {
 | |
|         this.emit("message", unpack(event.data));
 | |
|       }
 | |
|       send(data) {
 | |
|         this.ws.send(pack(data));
 | |
|       }
 | |
|       ping() {
 | |
|       }
 | |
|       // eslint-disable-line no-empty-function
 | |
|       close() {
 | |
|         return new Promise((r) => {
 | |
|           this.once("close", r);
 | |
|           this.ws.close();
 | |
|         });
 | |
|       }
 | |
|     };
 | |
|     module2.exports = WebSocketTransport;
 | |
|   }
 | |
| });
 | |
| 
 | |
| // node_modules/discord-rpc/src/transports/index.js
 | |
| var require_transports = __commonJS({
 | |
|   "node_modules/discord-rpc/src/transports/index.js"(exports, module2) {
 | |
|     "use strict";
 | |
|     module2.exports = {
 | |
|       ipc: require_ipc(),
 | |
|       websocket: require_websocket()
 | |
|     };
 | |
|   }
 | |
| });
 | |
| 
 | |
| // node_modules/discord-rpc/src/client.js
 | |
| var require_client = __commonJS({
 | |
|   "node_modules/discord-rpc/src/client.js"(exports, module2) {
 | |
|     "use strict";
 | |
|     var EventEmitter = require("events");
 | |
|     var { setTimeout: setTimeout2, clearTimeout } = require("timers");
 | |
|     var fetch = require_browser();
 | |
|     var transports = require_transports();
 | |
|     var { RPCCommands, RPCEvents, RelationshipTypes } = require_constants();
 | |
|     var { pid: getPid, uuid } = require_util();
 | |
|     function subKey(event, args) {
 | |
|       return `${event}${JSON.stringify(args)}`;
 | |
|     }
 | |
|     var RPCClient = class extends EventEmitter {
 | |
|       /**
 | |
|        * @param {RPCClientOptions} [options] Options for the client.
 | |
|        * You must provide a transport
 | |
|        */
 | |
|       constructor(options = {}) {
 | |
|         super();
 | |
|         this.options = options;
 | |
|         this.accessToken = null;
 | |
|         this.clientId = null;
 | |
|         this.application = null;
 | |
|         this.user = null;
 | |
|         const Transport = transports[options.transport];
 | |
|         if (!Transport) {
 | |
|           throw new TypeError("RPC_INVALID_TRANSPORT", options.transport);
 | |
|         }
 | |
|         this.fetch = (method, path, { data, query } = {}) => fetch(`${this.fetch.endpoint}${path}${query ? new URLSearchParams(query) : ""}`, {
 | |
|           method,
 | |
|           body: data,
 | |
|           headers: {
 | |
|             Authorization: `Bearer ${this.accessToken}`
 | |
|           }
 | |
|         }).then(async (r) => {
 | |
|           const body = await r.json();
 | |
|           if (!r.ok) {
 | |
|             const e = new Error(r.status);
 | |
|             e.body = body;
 | |
|             throw e;
 | |
|           }
 | |
|           return body;
 | |
|         });
 | |
|         this.fetch.endpoint = "https://discord.com/api";
 | |
|         this.transport = new Transport(this);
 | |
|         this.transport.on("message", this._onRpcMessage.bind(this));
 | |
|         this._expecting = /* @__PURE__ */ new Map();
 | |
|         this._connectPromise = void 0;
 | |
|       }
 | |
|       /**
 | |
|        * Search and connect to RPC
 | |
|        */
 | |
|       connect(clientId) {
 | |
|         if (this._connectPromise) {
 | |
|           return this._connectPromise;
 | |
|         }
 | |
|         this._connectPromise = new Promise((resolve, reject) => {
 | |
|           this.clientId = clientId;
 | |
|           const timeout = setTimeout2(() => reject(new Error("RPC_CONNECTION_TIMEOUT")), 1e4);
 | |
|           timeout.unref();
 | |
|           this.once("connected", () => {
 | |
|             clearTimeout(timeout);
 | |
|             resolve(this);
 | |
|           });
 | |
|           this.transport.once("close", () => {
 | |
|             this._expecting.forEach((e) => {
 | |
|               e.reject(new Error("connection closed"));
 | |
|             });
 | |
|             this.emit("disconnected");
 | |
|             reject(new Error("connection closed"));
 | |
|           });
 | |
|           this.transport.connect().catch(reject);
 | |
|         });
 | |
|         return this._connectPromise;
 | |
|       }
 | |
|       /**
 | |
|        * @typedef {RPCLoginOptions}
 | |
|        * @param {string} clientId Client ID
 | |
|        * @param {string} [clientSecret] Client secret
 | |
|        * @param {string} [accessToken] Access token
 | |
|        * @param {string} [rpcToken] RPC token
 | |
|        * @param {string} [tokenEndpoint] Token endpoint
 | |
|        * @param {string[]} [scopes] Scopes to authorize with
 | |
|        */
 | |
|       /**
 | |
|        * Performs authentication flow. Automatically calls Client#connect if needed.
 | |
|        * @param {RPCLoginOptions} options Options for authentication.
 | |
|        * At least one property must be provided to perform login.
 | |
|        * @example client.login({ clientId: '1234567', clientSecret: 'abcdef123' });
 | |
|        * @returns {Promise<RPCClient>}
 | |
|        */
 | |
|       async login(options = {}) {
 | |
|         let { clientId, accessToken } = options;
 | |
|         await this.connect(clientId);
 | |
|         if (!options.scopes) {
 | |
|           this.emit("ready");
 | |
|           return this;
 | |
|         }
 | |
|         if (!accessToken) {
 | |
|           accessToken = await this.authorize(options);
 | |
|         }
 | |
|         return this.authenticate(accessToken);
 | |
|       }
 | |
|       /**
 | |
|        * Request
 | |
|        * @param {string} cmd Command
 | |
|        * @param {Object} [args={}] Arguments
 | |
|        * @param {string} [evt] Event
 | |
|        * @returns {Promise}
 | |
|        * @private
 | |
|        */
 | |
|       request(cmd, args, evt) {
 | |
|         return new Promise((resolve, reject) => {
 | |
|           const nonce = uuid();
 | |
|           this.transport.send({ cmd, args, evt, nonce });
 | |
|           this._expecting.set(nonce, { resolve, reject });
 | |
|         });
 | |
|       }
 | |
|       /**
 | |
|        * Message handler
 | |
|        * @param {Object} message message
 | |
|        * @private
 | |
|        */
 | |
|       _onRpcMessage(message) {
 | |
|         if (message.cmd === RPCCommands.DISPATCH && message.evt === RPCEvents.READY) {
 | |
|           if (message.data.user) {
 | |
|             this.user = message.data.user;
 | |
|           }
 | |
|           this.emit("connected");
 | |
|         } else if (this._expecting.has(message.nonce)) {
 | |
|           const { resolve, reject } = this._expecting.get(message.nonce);
 | |
|           if (message.evt === "ERROR") {
 | |
|             const e = new Error(message.data.message);
 | |
|             e.code = message.data.code;
 | |
|             e.data = message.data;
 | |
|             reject(e);
 | |
|           } else {
 | |
|             resolve(message.data);
 | |
|           }
 | |
|           this._expecting.delete(message.nonce);
 | |
|         } else {
 | |
|           this.emit(message.evt, message.data);
 | |
|         }
 | |
|       }
 | |
|       /**
 | |
|        * Authorize
 | |
|        * @param {Object} options options
 | |
|        * @returns {Promise}
 | |
|        * @private
 | |
|        */
 | |
|       async authorize({ scopes, clientSecret, rpcToken, redirectUri, prompt } = {}) {
 | |
|         if (clientSecret && rpcToken === true) {
 | |
|           const body = await this.fetch("POST", "/oauth2/token/rpc", {
 | |
|             data: new URLSearchParams({
 | |
|               client_id: this.clientId,
 | |
|               client_secret: clientSecret
 | |
|             })
 | |
|           });
 | |
|           rpcToken = body.rpc_token;
 | |
|         }
 | |
|         const { code } = await this.request("AUTHORIZE", {
 | |
|           scopes,
 | |
|           client_id: this.clientId,
 | |
|           prompt,
 | |
|           rpc_token: rpcToken
 | |
|         });
 | |
|         const response = await this.fetch("POST", "/oauth2/token", {
 | |
|           data: new URLSearchParams({
 | |
|             client_id: this.clientId,
 | |
|             client_secret: clientSecret,
 | |
|             code,
 | |
|             grant_type: "authorization_code",
 | |
|             redirect_uri: redirectUri
 | |
|           })
 | |
|         });
 | |
|         return response.access_token;
 | |
|       }
 | |
|       /**
 | |
|        * Authenticate
 | |
|        * @param {string} accessToken access token
 | |
|        * @returns {Promise}
 | |
|        * @private
 | |
|        */
 | |
|       authenticate(accessToken) {
 | |
|         return this.request("AUTHENTICATE", { access_token: accessToken }).then(({ application, user }) => {
 | |
|           this.accessToken = accessToken;
 | |
|           this.application = application;
 | |
|           this.user = user;
 | |
|           this.emit("ready");
 | |
|           return this;
 | |
|         });
 | |
|       }
 | |
|       /**
 | |
|        * Fetch a guild
 | |
|        * @param {Snowflake} id Guild ID
 | |
|        * @param {number} [timeout] Timeout request
 | |
|        * @returns {Promise<Guild>}
 | |
|        */
 | |
|       getGuild(id, timeout) {
 | |
|         return this.request(RPCCommands.GET_GUILD, { guild_id: id, timeout });
 | |
|       }
 | |
|       /**
 | |
|        * Fetch all guilds
 | |
|        * @param {number} [timeout] Timeout request
 | |
|        * @returns {Promise<Collection<Snowflake, Guild>>}
 | |
|        */
 | |
|       getGuilds(timeout) {
 | |
|         return this.request(RPCCommands.GET_GUILDS, { timeout });
 | |
|       }
 | |
|       /**
 | |
|        * Get a channel
 | |
|        * @param {Snowflake} id Channel ID
 | |
|        * @param {number} [timeout] Timeout request
 | |
|        * @returns {Promise<Channel>}
 | |
|        */
 | |
|       getChannel(id, timeout) {
 | |
|         return this.request(RPCCommands.GET_CHANNEL, { channel_id: id, timeout });
 | |
|       }
 | |
|       /**
 | |
|        * Get all channels
 | |
|        * @param {Snowflake} [id] Guild ID
 | |
|        * @param {number} [timeout] Timeout request
 | |
|        * @returns {Promise<Collection<Snowflake, Channel>>}
 | |
|        */
 | |
|       async getChannels(id, timeout) {
 | |
|         const { channels } = await this.request(RPCCommands.GET_CHANNELS, {
 | |
|           timeout,
 | |
|           guild_id: id
 | |
|         });
 | |
|         return channels;
 | |
|       }
 | |
|       /**
 | |
|        * @typedef {CertifiedDevice}
 | |
|        * @prop {string} type One of `AUDIO_INPUT`, `AUDIO_OUTPUT`, `VIDEO_INPUT`
 | |
|        * @prop {string} uuid This device's Windows UUID
 | |
|        * @prop {object} vendor Vendor information
 | |
|        * @prop {string} vendor.name Vendor's name
 | |
|        * @prop {string} vendor.url Vendor's url
 | |
|        * @prop {object} model Model information
 | |
|        * @prop {string} model.name Model's name
 | |
|        * @prop {string} model.url Model's url
 | |
|        * @prop {string[]} related Array of related product's Windows UUIDs
 | |
|        * @prop {boolean} echoCancellation If the device has echo cancellation
 | |
|        * @prop {boolean} noiseSuppression If the device has noise suppression
 | |
|        * @prop {boolean} automaticGainControl If the device has automatic gain control
 | |
|        * @prop {boolean} hardwareMute If the device has a hardware mute
 | |
|        */
 | |
|       /**
 | |
|        * Tell discord which devices are certified
 | |
|        * @param {CertifiedDevice[]} devices Certified devices to send to discord
 | |
|        * @returns {Promise}
 | |
|        */
 | |
|       setCertifiedDevices(devices) {
 | |
|         return this.request(RPCCommands.SET_CERTIFIED_DEVICES, {
 | |
|           devices: devices.map((d) => ({
 | |
|             type: d.type,
 | |
|             id: d.uuid,
 | |
|             vendor: d.vendor,
 | |
|             model: d.model,
 | |
|             related: d.related,
 | |
|             echo_cancellation: d.echoCancellation,
 | |
|             noise_suppression: d.noiseSuppression,
 | |
|             automatic_gain_control: d.automaticGainControl,
 | |
|             hardware_mute: d.hardwareMute
 | |
|           }))
 | |
|         });
 | |
|       }
 | |
|       /**
 | |
|        * @typedef {UserVoiceSettings}
 | |
|        * @prop {Snowflake} id ID of the user these settings apply to
 | |
|        * @prop {?Object} [pan] Pan settings, an object with `left` and `right` set between
 | |
|        * 0.0 and 1.0, inclusive
 | |
|        * @prop {?number} [volume=100] The volume
 | |
|        * @prop {bool} [mute] If the user is muted
 | |
|        */
 | |
|       /**
 | |
|        * Set the voice settings for a user, by id
 | |
|        * @param {Snowflake} id ID of the user to set
 | |
|        * @param {UserVoiceSettings} settings Settings
 | |
|        * @returns {Promise}
 | |
|        */
 | |
|       setUserVoiceSettings(id, settings) {
 | |
|         return this.request(RPCCommands.SET_USER_VOICE_SETTINGS, {
 | |
|           user_id: id,
 | |
|           pan: settings.pan,
 | |
|           mute: settings.mute,
 | |
|           volume: settings.volume
 | |
|         });
 | |
|       }
 | |
|       /**
 | |
|        * Move the user to a voice channel
 | |
|        * @param {Snowflake} id ID of the voice channel
 | |
|        * @param {Object} [options] Options
 | |
|        * @param {number} [options.timeout] Timeout for the command
 | |
|        * @param {boolean} [options.force] Force this move. This should only be done if you
 | |
|        * have explicit permission from the user.
 | |
|        * @returns {Promise}
 | |
|        */
 | |
|       selectVoiceChannel(id, { timeout, force = false } = {}) {
 | |
|         return this.request(RPCCommands.SELECT_VOICE_CHANNEL, { channel_id: id, timeout, force });
 | |
|       }
 | |
|       /**
 | |
|        * Move the user to a text channel
 | |
|        * @param {Snowflake} id ID of the voice channel
 | |
|        * @param {Object} [options] Options
 | |
|        * @param {number} [options.timeout] Timeout for the command
 | |
|        * have explicit permission from the user.
 | |
|        * @returns {Promise}
 | |
|        */
 | |
|       selectTextChannel(id, { timeout } = {}) {
 | |
|         return this.request(RPCCommands.SELECT_TEXT_CHANNEL, { channel_id: id, timeout });
 | |
|       }
 | |
|       /**
 | |
|        * Get current voice settings
 | |
|        * @returns {Promise}
 | |
|        */
 | |
|       getVoiceSettings() {
 | |
|         return this.request(RPCCommands.GET_VOICE_SETTINGS).then((s) => ({
 | |
|           automaticGainControl: s.automatic_gain_control,
 | |
|           echoCancellation: s.echo_cancellation,
 | |
|           noiseSuppression: s.noise_suppression,
 | |
|           qos: s.qos,
 | |
|           silenceWarning: s.silence_warning,
 | |
|           deaf: s.deaf,
 | |
|           mute: s.mute,
 | |
|           input: {
 | |
|             availableDevices: s.input.available_devices,
 | |
|             device: s.input.device_id,
 | |
|             volume: s.input.volume
 | |
|           },
 | |
|           output: {
 | |
|             availableDevices: s.output.available_devices,
 | |
|             device: s.output.device_id,
 | |
|             volume: s.output.volume
 | |
|           },
 | |
|           mode: {
 | |
|             type: s.mode.type,
 | |
|             autoThreshold: s.mode.auto_threshold,
 | |
|             threshold: s.mode.threshold,
 | |
|             shortcut: s.mode.shortcut,
 | |
|             delay: s.mode.delay
 | |
|           }
 | |
|         }));
 | |
|       }
 | |
|       /**
 | |
|        * Set current voice settings, overriding the current settings until this session disconnects.
 | |
|        * This also locks the settings for any other rpc sessions which may be connected.
 | |
|        * @param {Object} args Settings
 | |
|        * @returns {Promise}
 | |
|        */
 | |
|       setVoiceSettings(args) {
 | |
|         return this.request(RPCCommands.SET_VOICE_SETTINGS, {
 | |
|           automatic_gain_control: args.automaticGainControl,
 | |
|           echo_cancellation: args.echoCancellation,
 | |
|           noise_suppression: args.noiseSuppression,
 | |
|           qos: args.qos,
 | |
|           silence_warning: args.silenceWarning,
 | |
|           deaf: args.deaf,
 | |
|           mute: args.mute,
 | |
|           input: args.input ? {
 | |
|             device_id: args.input.device,
 | |
|             volume: args.input.volume
 | |
|           } : void 0,
 | |
|           output: args.output ? {
 | |
|             device_id: args.output.device,
 | |
|             volume: args.output.volume
 | |
|           } : void 0,
 | |
|           mode: args.mode ? {
 | |
|             type: args.mode.type,
 | |
|             auto_threshold: args.mode.autoThreshold,
 | |
|             threshold: args.mode.threshold,
 | |
|             shortcut: args.mode.shortcut,
 | |
|             delay: args.mode.delay
 | |
|           } : void 0
 | |
|         });
 | |
|       }
 | |
|       /**
 | |
|        * Capture a shortcut using the client
 | |
|        * The callback takes (key, stop) where `stop` is a function that will stop capturing.
 | |
|        * This `stop` function must be called before disconnecting or else the user will have
 | |
|        * to restart their client.
 | |
|        * @param {Function} callback Callback handling keys
 | |
|        * @returns {Promise<Function>}
 | |
|        */
 | |
|       captureShortcut(callback) {
 | |
|         const subid = subKey(RPCEvents.CAPTURE_SHORTCUT_CHANGE);
 | |
|         const stop = () => {
 | |
|           this._subscriptions.delete(subid);
 | |
|           return this.request(RPCCommands.CAPTURE_SHORTCUT, { action: "STOP" });
 | |
|         };
 | |
|         this._subscriptions.set(subid, ({ shortcut }) => {
 | |
|           callback(shortcut, stop);
 | |
|         });
 | |
|         return this.request(RPCCommands.CAPTURE_SHORTCUT, { action: "START" }).then(() => stop);
 | |
|       }
 | |
|       /**
 | |
|        * Sets the presence for the logged in user.
 | |
|        * @param {object} args The rich presence to pass.
 | |
|        * @param {number} [pid] The application's process ID. Defaults to the executing process' PID.
 | |
|        * @returns {Promise}
 | |
|        */
 | |
|       setActivity(args = {}, pid = getPid()) {
 | |
|         let timestamps;
 | |
|         let assets;
 | |
|         let party;
 | |
|         let secrets;
 | |
|         if (args.startTimestamp || args.endTimestamp) {
 | |
|           timestamps = {
 | |
|             start: args.startTimestamp,
 | |
|             end: args.endTimestamp
 | |
|           };
 | |
|           if (timestamps.start instanceof Date) {
 | |
|             timestamps.start = Math.round(timestamps.start.getTime());
 | |
|           }
 | |
|           if (timestamps.end instanceof Date) {
 | |
|             timestamps.end = Math.round(timestamps.end.getTime());
 | |
|           }
 | |
|           if (timestamps.start > 2147483647e3) {
 | |
|             throw new RangeError("timestamps.start must fit into a unix timestamp");
 | |
|           }
 | |
|           if (timestamps.end > 2147483647e3) {
 | |
|             throw new RangeError("timestamps.end must fit into a unix timestamp");
 | |
|           }
 | |
|         }
 | |
|         if (args.largeImageKey || args.largeImageText || args.smallImageKey || args.smallImageText) {
 | |
|           assets = {
 | |
|             large_image: args.largeImageKey,
 | |
|             large_text: args.largeImageText,
 | |
|             small_image: args.smallImageKey,
 | |
|             small_text: args.smallImageText
 | |
|           };
 | |
|         }
 | |
|         if (args.partySize || args.partyId || args.partyMax) {
 | |
|           party = { id: args.partyId };
 | |
|           if (args.partySize || args.partyMax) {
 | |
|             party.size = [args.partySize, args.partyMax];
 | |
|           }
 | |
|         }
 | |
|         if (args.matchSecret || args.joinSecret || args.spectateSecret) {
 | |
|           secrets = {
 | |
|             match: args.matchSecret,
 | |
|             join: args.joinSecret,
 | |
|             spectate: args.spectateSecret
 | |
|           };
 | |
|         }
 | |
|         return this.request(RPCCommands.SET_ACTIVITY, {
 | |
|           pid,
 | |
|           activity: {
 | |
|             state: args.state,
 | |
|             details: args.details,
 | |
|             timestamps,
 | |
|             assets,
 | |
|             party,
 | |
|             secrets,
 | |
|             buttons: args.buttons,
 | |
|             instance: !!args.instance
 | |
|           }
 | |
|         });
 | |
|       }
 | |
|       /**
 | |
|        * Clears the currently set presence, if any. This will hide the "Playing X" message
 | |
|        * displayed below the user's name.
 | |
|        * @param {number} [pid] The application's process ID. Defaults to the executing process' PID.
 | |
|        * @returns {Promise}
 | |
|        */
 | |
|       clearActivity(pid = getPid()) {
 | |
|         return this.request(RPCCommands.SET_ACTIVITY, {
 | |
|           pid
 | |
|         });
 | |
|       }
 | |
|       /**
 | |
|        * Invite a user to join the game the RPC user is currently playing
 | |
|        * @param {User} user The user to invite
 | |
|        * @returns {Promise}
 | |
|        */
 | |
|       sendJoinInvite(user) {
 | |
|         return this.request(RPCCommands.SEND_ACTIVITY_JOIN_INVITE, {
 | |
|           user_id: user.id || user
 | |
|         });
 | |
|       }
 | |
|       /**
 | |
|        * Request to join the game the user is playing
 | |
|        * @param {User} user The user whose game you want to request to join
 | |
|        * @returns {Promise}
 | |
|        */
 | |
|       sendJoinRequest(user) {
 | |
|         return this.request(RPCCommands.SEND_ACTIVITY_JOIN_REQUEST, {
 | |
|           user_id: user.id || user
 | |
|         });
 | |
|       }
 | |
|       /**
 | |
|        * Reject a join request from a user
 | |
|        * @param {User} user The user whose request you wish to reject
 | |
|        * @returns {Promise}
 | |
|        */
 | |
|       closeJoinRequest(user) {
 | |
|         return this.request(RPCCommands.CLOSE_ACTIVITY_JOIN_REQUEST, {
 | |
|           user_id: user.id || user
 | |
|         });
 | |
|       }
 | |
|       createLobby(type, capacity, metadata) {
 | |
|         return this.request(RPCCommands.CREATE_LOBBY, {
 | |
|           type,
 | |
|           capacity,
 | |
|           metadata
 | |
|         });
 | |
|       }
 | |
|       updateLobby(lobby, { type, owner, capacity, metadata } = {}) {
 | |
|         return this.request(RPCCommands.UPDATE_LOBBY, {
 | |
|           id: lobby.id || lobby,
 | |
|           type,
 | |
|           owner_id: owner && owner.id || owner,
 | |
|           capacity,
 | |
|           metadata
 | |
|         });
 | |
|       }
 | |
|       deleteLobby(lobby) {
 | |
|         return this.request(RPCCommands.DELETE_LOBBY, {
 | |
|           id: lobby.id || lobby
 | |
|         });
 | |
|       }
 | |
|       connectToLobby(id, secret) {
 | |
|         return this.request(RPCCommands.CONNECT_TO_LOBBY, {
 | |
|           id,
 | |
|           secret
 | |
|         });
 | |
|       }
 | |
|       sendToLobby(lobby, data) {
 | |
|         return this.request(RPCCommands.SEND_TO_LOBBY, {
 | |
|           id: lobby.id || lobby,
 | |
|           data
 | |
|         });
 | |
|       }
 | |
|       disconnectFromLobby(lobby) {
 | |
|         return this.request(RPCCommands.DISCONNECT_FROM_LOBBY, {
 | |
|           id: lobby.id || lobby
 | |
|         });
 | |
|       }
 | |
|       updateLobbyMember(lobby, user, metadata) {
 | |
|         return this.request(RPCCommands.UPDATE_LOBBY_MEMBER, {
 | |
|           lobby_id: lobby.id || lobby,
 | |
|           user_id: user.id || user,
 | |
|           metadata
 | |
|         });
 | |
|       }
 | |
|       getRelationships() {
 | |
|         const types = Object.keys(RelationshipTypes);
 | |
|         return this.request(RPCCommands.GET_RELATIONSHIPS).then((o) => o.relationships.map((r) => ({
 | |
|           ...r,
 | |
|           type: types[r.type]
 | |
|         })));
 | |
|       }
 | |
|       /**
 | |
|        * Subscribe to an event
 | |
|        * @param {string} event Name of event e.g. `MESSAGE_CREATE`
 | |
|        * @param {Object} [args] Args for event e.g. `{ channel_id: '1234' }`
 | |
|        * @returns {Promise<Object>}
 | |
|        */
 | |
|       async subscribe(event, args) {
 | |
|         await this.request(RPCCommands.SUBSCRIBE, args, event);
 | |
|         return {
 | |
|           unsubscribe: () => this.request(RPCCommands.UNSUBSCRIBE, args, event)
 | |
|         };
 | |
|       }
 | |
|       /**
 | |
|        * Destroy the client
 | |
|        */
 | |
|       async destroy() {
 | |
|         await this.transport.close();
 | |
|       }
 | |
|     };
 | |
|     module2.exports = RPCClient;
 | |
|   }
 | |
| });
 | |
| 
 | |
| // node_modules/discord-rpc/src/index.js
 | |
| var require_src = __commonJS({
 | |
|   "node_modules/discord-rpc/src/index.js"(exports, module2) {
 | |
|     "use strict";
 | |
|     var util = require_util();
 | |
|     module2.exports = {
 | |
|       Client: require_client(),
 | |
|       register(id) {
 | |
|         return util.register(`discord-${id}`);
 | |
|       }
 | |
|     };
 | |
|   }
 | |
| });
 | |
| 
 | |
| // src/main.ts
 | |
| var main_exports = {};
 | |
| __export(main_exports, {
 | |
|   default: () => ObsidianDiscordRPC
 | |
| });
 | |
| module.exports = __toCommonJS(main_exports);
 | |
| var import_discord_rpc = __toESM(require_src());
 | |
| var import_obsidian4 = require("obsidian");
 | |
| 
 | |
| // src/logger.ts
 | |
| var import_obsidian = require("obsidian");
 | |
| var Logger = class {
 | |
|   constructor(plugin) {
 | |
|     this.plugin = plugin;
 | |
|   }
 | |
|   log(message, showPopups) {
 | |
|     if (showPopups) {
 | |
|       new import_obsidian.Notice(message);
 | |
|     }
 | |
|     console.log(`discordrpc: ${message}`);
 | |
|   }
 | |
|   logIgnoreNoNotice(message) {
 | |
|     new import_obsidian.Notice(message);
 | |
|     console.log(`discordrpc: ${message}`);
 | |
|   }
 | |
| };
 | |
| 
 | |
| // src/settings/settings.ts
 | |
| var DiscordRPCSettings = class {
 | |
|   constructor() {
 | |
|     this.showVaultName = true;
 | |
|     this.showCurrentFileName = true;
 | |
|     this.showConnectionTimer = false;
 | |
|     this.showPopups = true;
 | |
|     this.customVaultName = "";
 | |
|     this.showFileExtension = false;
 | |
|     this.useLoadedTime = false;
 | |
|     this.connectOnStart = true;
 | |
|     this.autoHideStatusBar = true;
 | |
|     this.privacyMode = false;
 | |
|     this.themeStyle = "default-new-dark" /* Default_new_dark */;
 | |
|   }
 | |
| };
 | |
| 
 | |
| // src/settings/settings-tab.ts
 | |
| var import_obsidian2 = require("obsidian");
 | |
| var DiscordRPCSettingsTab = class extends import_obsidian2.PluginSettingTab {
 | |
|   constructor(app, plugin) {
 | |
|     super(app, plugin);
 | |
|     this.plugin = plugin;
 | |
|     this.logger = new Logger(plugin);
 | |
|   }
 | |
|   display() {
 | |
|     let { containerEl } = this;
 | |
|     const plugin = this.plugin;
 | |
|     containerEl.empty();
 | |
|     new import_obsidian2.Setting(containerEl).setName("Vault name").setHeading();
 | |
|     new import_obsidian2.Setting(containerEl).setName("Privacy mode").setDesc("Enable this to hide the name of the vault and Hide file names").addToggle(
 | |
|       (boolean) => boolean.setValue(plugin.settings.privacyMode).onChange((value) => {
 | |
|         plugin.settings.privacyMode = value;
 | |
|         plugin.saveData(plugin.settings);
 | |
|         plugin.setActivity("", "", "");
 | |
|       })
 | |
|     );
 | |
|     new import_obsidian2.Setting(containerEl).setName("Show vault name").setDesc(
 | |
|       "Enable this to show the name of the vault you are working with."
 | |
|     ).addToggle(
 | |
|       (boolean) => boolean.setValue(plugin.settings.showVaultName).onChange((value) => {
 | |
|         plugin.settings.showVaultName = value;
 | |
|         plugin.saveData(plugin.settings);
 | |
|         plugin.setActivity(
 | |
|           this.app.vault.getName(),
 | |
|           plugin.currentFile.basename,
 | |
|           plugin.currentFile.extension
 | |
|         );
 | |
|       })
 | |
|     );
 | |
|     new import_obsidian2.Setting(containerEl).setName("Set custom vault name").setDesc(
 | |
|       "Change the vault name shown publicly. Leave blank to use your actual vault name."
 | |
|     ).addText(
 | |
|       (text) => text.setValue(plugin.settings.customVaultName).onChange((value) => {
 | |
|         plugin.settings.customVaultName = value;
 | |
|         plugin.saveData(plugin.settings);
 | |
|         plugin.setActivity(
 | |
|           this.app.vault.getName(),
 | |
|           plugin.currentFile.basename,
 | |
|           plugin.currentFile.extension
 | |
|         );
 | |
|       })
 | |
|     );
 | |
|     new import_obsidian2.Setting(containerEl).setName("File name").setHeading();
 | |
|     new import_obsidian2.Setting(containerEl).setName("Show current file name").setDesc("Enable this to show the name of the file you are working on.").addToggle(
 | |
|       (boolean) => boolean.setValue(plugin.settings.showCurrentFileName).onChange((value) => {
 | |
|         plugin.settings.showCurrentFileName = value;
 | |
|         plugin.saveData(plugin.settings);
 | |
|         plugin.setActivity(
 | |
|           this.app.vault.getName(),
 | |
|           plugin.currentFile.basename,
 | |
|           plugin.currentFile.extension
 | |
|         );
 | |
|       })
 | |
|     );
 | |
|     new import_obsidian2.Setting(containerEl).setName("Show file extension").setDesc("Enable this to show file extension.").addToggle(
 | |
|       (boolean) => boolean.setValue(plugin.settings.showFileExtension).onChange((value) => {
 | |
|         plugin.settings.showFileExtension = value;
 | |
|         plugin.saveData(plugin.settings);
 | |
|         plugin.setActivity(
 | |
|           this.app.vault.getName(),
 | |
|           plugin.currentFile.basename,
 | |
|           plugin.currentFile.extension
 | |
|         );
 | |
|       })
 | |
|     );
 | |
|     new import_obsidian2.Setting(containerEl).setName("Time tracking").setHeading();
 | |
|     new import_obsidian2.Setting(containerEl).setName("Use obsidian total time").setDesc(
 | |
|       "Enable to use the total time you have been using Obsidian, instead of the time spent editing a single file."
 | |
|     ).addToggle((boolean) => {
 | |
|       boolean.setValue(plugin.settings.useLoadedTime).onChange((value) => {
 | |
|         plugin.settings.useLoadedTime = value;
 | |
|         plugin.saveData(plugin.settings);
 | |
|         plugin.setActivity(
 | |
|           this.app.vault.getName(),
 | |
|           plugin.currentFile.basename,
 | |
|           plugin.currentFile.extension
 | |
|         );
 | |
|       });
 | |
|     });
 | |
|     new import_obsidian2.Setting(containerEl).setName("Status bar").setHeading();
 | |
|     new import_obsidian2.Setting(containerEl).setName("Automatically hide status bar").setDesc(
 | |
|       "Automatically hide status bar after successfully connecting to Discord."
 | |
|     ).addToggle((boolean) => {
 | |
|       boolean.setValue(plugin.settings.autoHideStatusBar).onChange((value) => {
 | |
|         plugin.settings.autoHideStatusBar = value;
 | |
|         plugin.saveData(plugin.settings);
 | |
|         plugin.setActivity(
 | |
|           this.app.vault.getName(),
 | |
|           plugin.currentFile.basename,
 | |
|           plugin.currentFile.extension
 | |
|         );
 | |
|       });
 | |
|     });
 | |
|     new import_obsidian2.Setting(containerEl).setName("Show connected time").setDesc(
 | |
|       "Show time spent editing file or time connected to Discord in the status bar."
 | |
|     ).addToggle((boolean) => {
 | |
|       boolean.setValue(plugin.settings.showConnectionTimer).onChange((value) => {
 | |
|         plugin.settings.showConnectionTimer = value;
 | |
|         plugin.saveData(plugin.settings);
 | |
|         plugin.setActivity(
 | |
|           this.app.vault.getName(),
 | |
|           plugin.currentFile.basename,
 | |
|           plugin.currentFile.extension
 | |
|         );
 | |
|         plugin.statusBar.displayState(plugin.getState(), plugin.settings.autoHideStatusBar);
 | |
|       });
 | |
|     });
 | |
|     new import_obsidian2.Setting(containerEl).setName("Startup behavior").setHeading();
 | |
|     new import_obsidian2.Setting(containerEl).setName("Automatically connect to Discord").setDesc(
 | |
|       "Automatically connect to Discord on startup. You can always click the status bar to manually connect."
 | |
|     ).addToggle((boolean) => {
 | |
|       boolean.setValue(plugin.settings.connectOnStart).onChange((value) => {
 | |
|         plugin.settings.connectOnStart = value;
 | |
|         plugin.saveData(plugin.settings);
 | |
|         plugin.setActivity(
 | |
|           this.app.vault.getName(),
 | |
|           plugin.currentFile.basename,
 | |
|           plugin.currentFile.extension
 | |
|         );
 | |
|       });
 | |
|     });
 | |
|     new import_obsidian2.Setting(containerEl).setName("Notices").setHeading();
 | |
|     new import_obsidian2.Setting(containerEl).setName("Show notices").setDesc("Enable this to show connection Notices.").addToggle(
 | |
|       (boolean) => boolean.setValue(plugin.settings.showPopups).onChange((value) => {
 | |
|         plugin.settings.showPopups = value;
 | |
|         plugin.saveData(plugin.settings);
 | |
|         plugin.setActivity(
 | |
|           this.app.vault.getName(),
 | |
|           plugin.currentFile.basename,
 | |
|           plugin.currentFile.extension
 | |
|         );
 | |
|       })
 | |
|     );
 | |
|     new import_obsidian2.Setting(containerEl).setName("Theme style").setHeading();
 | |
|     new import_obsidian2.Setting(containerEl).setName("Theme style").setDesc("Choose the theme style for Discord Rich Presence").addDropdown((dropdown) => dropdown.addOption("default-old-dark" /* Default_dark */, "Default Dark (Old)").addOption("default-old-light" /* Default_light */, "Default Light (Old)").addOption("default-new-dark" /* Default_new_dark */, "Default Dark (New)").addOption("default-new-light" /* Default_new_light */, "Default Light (New)").addOption("latte" /* Catppuccin_Latte */, "Catppuccin Latte").addOption("frappe" /* Catppuccin_Frappe */, "Catppuccin Frappe").addOption("macchiato" /* Catppuccin_Macchiato */, "Catppuccin Macchiato").addOption("mocha" /* Catppuccin_Mocha */, "Catppuccin Mocha").addOption("cyberglow-dark" /* Cyberglow_Dark */, "Cyberglow Dark").addOption("cyberglow-light" /* Cyberglow_Light */, "Cyberglow Light").addOption("tokyo-night-dark" /* Tokyo_night_Dark */, "Tokyo Night Dark").addOption("tokyo-night-light" /* Tokyo_night_Light */, "Tokyo Night Light").setValue(plugin.settings.themeStyle).onChange(async (value) => {
 | |
|       var _a, _b, _c, _d;
 | |
|       plugin.settings.themeStyle = value;
 | |
|       await plugin.saveData(plugin.settings);
 | |
|       if (plugin.getState() === 0 /* connected */) {
 | |
|         await plugin.setActivity(
 | |
|           plugin.app.vault.getName(),
 | |
|           (_b = (_a = plugin.currentFile) == null ? void 0 : _a.basename) != null ? _b : "...",
 | |
|           (_d = (_c = plugin.currentFile) == null ? void 0 : _c.extension) != null ? _d : ""
 | |
|         );
 | |
|       }
 | |
|     }));
 | |
|   }
 | |
| };
 | |
| 
 | |
| // src/status-bar.ts
 | |
| var import_obsidian3 = require("obsidian");
 | |
| var StatusBar = class _StatusBar {
 | |
|   constructor(statusBarEl) {
 | |
|     this.statusBarEl = statusBarEl;
 | |
|   }
 | |
|   displayState(state, autoHide) {
 | |
|     switch (state) {
 | |
|       case 0 /* connected */:
 | |
|         this.displayConnected(autoHide ? 1e4 : 0);
 | |
|         break;
 | |
|       case 1 /* connecting */:
 | |
|         this.statusBarEl.setText(`Connecting to Discord...`);
 | |
|         break;
 | |
|       case 2 /* disconnected */:
 | |
|         this.statusBarEl.setText(`\u{1F5D8} Reconnect to Discord`);
 | |
|         break;
 | |
|     }
 | |
|   }
 | |
|   displayTimer(loadedTime) {
 | |
|     this.statusBarEl.setText(`\u{1F30D} ${_StatusBar.millisecsToString((/* @__PURE__ */ new Date()).getTime() - loadedTime.getTime())}`);
 | |
|   }
 | |
|   displayConnected(timeout) {
 | |
|     this.statusBarEl.setText(`\u2713 Connected to Discord`);
 | |
|     if (timeout && timeout > 0) {
 | |
|       window.setTimeout(() => {
 | |
|         this.statusBarEl.setText("");
 | |
|       }, timeout);
 | |
|     } else {
 | |
|       window.setTimeout(() => {
 | |
|         this.statusBarEl.setText(`Discord RPC`);
 | |
|       }, 5e3);
 | |
|     }
 | |
|   }
 | |
|   /* Returns [HH:]mm:ss on the stopwatch
 | |
|   https://github.com/grassbl8d/flexible-pomo-obsidian/blob/ae037e3710866863c5397f42af06c5540a807b10/src/timer.ts#L475
 | |
|   */
 | |
|   static millisecsToString(millisecs) {
 | |
|     let formattedCountDown;
 | |
|     if (millisecs >= 60 * 60 * 1e3) {
 | |
|       formattedCountDown = import_obsidian3.moment.utc(millisecs).format("HH:mm:ss");
 | |
|     } else {
 | |
|       formattedCountDown = import_obsidian3.moment.utc(millisecs).format("mm:ss");
 | |
|     }
 | |
|     return formattedCountDown.toString();
 | |
|   }
 | |
| };
 | |
| 
 | |
| // src/main.ts
 | |
| var ObsidianDiscordRPC = class extends import_obsidian4.Plugin {
 | |
|   constructor() {
 | |
|     super(...arguments);
 | |
|     this.logger = new Logger();
 | |
|   }
 | |
|   setState(state) {
 | |
|     this.state = state;
 | |
|   }
 | |
|   getState() {
 | |
|     return this.state;
 | |
|   }
 | |
|   getApp() {
 | |
|     return this.app;
 | |
|   }
 | |
|   getPluginManifest() {
 | |
|     return this.manifest;
 | |
|   }
 | |
|   async onload() {
 | |
|     let statusBarEl = this.addStatusBarItem();
 | |
|     this.statusBar = new StatusBar(statusBarEl);
 | |
|     this.settings = await this.loadData() || new DiscordRPCSettings();
 | |
|     this.registerEvent(
 | |
|       this.app.workspace.on("file-open", this.onFileOpen, this)
 | |
|     );
 | |
|     this.registerInterval(window.setInterval(async () => {
 | |
|       if (this.settings.showConnectionTimer && this.getState() == 0 /* connected */) {
 | |
|         this.statusBar.displayTimer(this.settings.useLoadedTime ? this.loadedTime : this.lastSetTime);
 | |
|       }
 | |
|     }, 500));
 | |
|     this.registerDomEvent(statusBarEl, "click", async () => {
 | |
|       if (this.getState() == 2 /* disconnected */) {
 | |
|         await this.connectDiscord();
 | |
|       } else if (this.getState() == 0 /* connected */) {
 | |
|         await this.disconnectDiscord();
 | |
|       }
 | |
|     });
 | |
|     this.addSettingTab(new DiscordRPCSettingsTab(this.app, this));
 | |
|     this.addCommand({
 | |
|       id: "reconnect-discord",
 | |
|       name: "Reconnect to Discord",
 | |
|       callback: async () => await this.connectDiscord()
 | |
|     });
 | |
|     this.addCommand({
 | |
|       id: "disconnect-discord",
 | |
|       name: "Disconnect from Discord",
 | |
|       callback: async () => await this.disconnectDiscord()
 | |
|     });
 | |
|     if (this.settings.connectOnStart) {
 | |
|       await this.connectDiscord();
 | |
|       const activeLeaf = this.app.workspace.activeLeaf;
 | |
|       const files = this.app.vault.getMarkdownFiles();
 | |
|       if (activeLeaf) {
 | |
|         const displayText = activeLeaf.getDisplayText();
 | |
|         files.forEach((file) => {
 | |
|           if (file.basename === displayText) {
 | |
|             this.onFileOpen(file);
 | |
|           }
 | |
|         });
 | |
|       }
 | |
|     } else {
 | |
|       this.setState(2 /* disconnected */);
 | |
|       this.statusBar.displayState(
 | |
|         this.getState(),
 | |
|         this.settings.autoHideStatusBar
 | |
|       );
 | |
|     }
 | |
|   }
 | |
|   async onFileOpen(file) {
 | |
|     this.currentFile = file;
 | |
|     if (this.getState() === 0 /* connected */) {
 | |
|       await this.setActivity(
 | |
|         this.app.vault.getName(),
 | |
|         file.basename,
 | |
|         file.extension
 | |
|       );
 | |
|     }
 | |
|   }
 | |
|   async onunload() {
 | |
|     await this.saveData(this.settings);
 | |
|     this.rpc.clearActivity();
 | |
|     this.rpc.destroy();
 | |
|   }
 | |
|   async connectDiscord() {
 | |
|     this.loadedTime = /* @__PURE__ */ new Date();
 | |
|     this.lastSetTime = /* @__PURE__ */ new Date();
 | |
|     this.rpc = new import_discord_rpc.Client({
 | |
|       transport: "ipc"
 | |
|     });
 | |
|     this.setState(1 /* connecting */);
 | |
|     this.statusBar.displayState(
 | |
|       this.getState(),
 | |
|       this.settings.autoHideStatusBar
 | |
|     );
 | |
|     this.rpc.once("ready", () => {
 | |
|       this.setState(0 /* connected */);
 | |
|       this.statusBar.displayState(
 | |
|         this.getState(),
 | |
|         this.settings.autoHideStatusBar
 | |
|       );
 | |
|       this.logger.log("Connected to Discord", this.settings.showPopups);
 | |
|     });
 | |
|     try {
 | |
|       await this.rpc.login({
 | |
|         clientId: "1352970439684657152"
 | |
|       });
 | |
|       await this.setActivity(this.app.vault.getName(), "...", "");
 | |
|     } catch (error) {
 | |
|       this.setState(2 /* disconnected */);
 | |
|       this.statusBar.displayState(
 | |
|         this.getState(),
 | |
|         this.settings.autoHideStatusBar
 | |
|       );
 | |
|       this.logger.log("Failed to connect to Discord", this.settings.showPopups);
 | |
|     }
 | |
|   }
 | |
|   async disconnectDiscord() {
 | |
|     this.rpc.clearActivity();
 | |
|     this.rpc.destroy();
 | |
|     this.setState(2 /* disconnected */);
 | |
|     this.statusBar.displayState(
 | |
|       this.getState(),
 | |
|       this.settings.autoHideStatusBar
 | |
|     );
 | |
|     this.logger.log("Disconnected from Discord", this.settings.showPopups);
 | |
|   }
 | |
|   async setActivity(vaultName, fileName, fileExtension) {
 | |
|     if (this.getState() === 0 /* connected */) {
 | |
|       let vault;
 | |
|       if (this.settings.customVaultName === "") {
 | |
|         vault = vaultName;
 | |
|       } else {
 | |
|         vault = this.settings.customVaultName;
 | |
|       }
 | |
|       let file;
 | |
|       if (this.settings.showFileExtension) {
 | |
|         file = fileName + "." + fileExtension;
 | |
|       } else {
 | |
|         file = fileName;
 | |
|       }
 | |
|       let date;
 | |
|       if (this.settings.useLoadedTime) {
 | |
|         date = this.loadedTime;
 | |
|       } else {
 | |
|         date = /* @__PURE__ */ new Date();
 | |
|       }
 | |
|       this.lastSetTime = date;
 | |
|       if (this.settings.privacyMode) {
 | |
|         await this.rpc.setActivity({
 | |
|           details: `Editing Notes`,
 | |
|           state: `Working in a Vault`,
 | |
|           startTimestamp: date,
 | |
|           largeImageKey: this.settings.themeStyle,
 | |
|           largeImageText: "no info just privacy mode"
 | |
|         });
 | |
|       } else if (this.settings.showVaultName && this.settings.showCurrentFileName) {
 | |
|         await this.rpc.setActivity({
 | |
|           details: `Editing ${file}`,
 | |
|           state: `Vault: ${vault}`,
 | |
|           startTimestamp: date,
 | |
|           largeImageKey: this.settings.themeStyle,
 | |
|           largeImageText: "I'm thinking!"
 | |
|         });
 | |
|       } else if (this.settings.showVaultName) {
 | |
|         await this.rpc.setActivity({
 | |
|           state: `Vault: ${vault}`,
 | |
|           startTimestamp: date,
 | |
|           largeImageKey: this.settings.themeStyle,
 | |
|           largeImageText: "Obsidian"
 | |
|         });
 | |
|       } else if (this.settings.showCurrentFileName) {
 | |
|         await this.rpc.setActivity({
 | |
|           details: `Editing ${file}`,
 | |
|           startTimestamp: date,
 | |
|           largeImageKey: this.settings.themeStyle,
 | |
|           largeImageText: "I'm thinking!"
 | |
|         });
 | |
|       } else {
 | |
|         await this.rpc.setActivity({
 | |
|           startTimestamp: date,
 | |
|           largeImageKey: this.settings.themeStyle,
 | |
|           largeImageText: "Obsidian"
 | |
|         });
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| };
 | |
| 
 | |
| 
 | |
| /* nosourcemap */ |