dotfiles/vesktop/vencordDist/vencordDesktopRenderer.js.map
2024-03-06 20:18:13 -06:00

8 lines
2.1 MiB

{
"version": 3,
"sources": ["../scripts/build/inject/react.mjs", "../src/utils/Logger.ts", "../src/utils/margins.ts", "../src/utils/lazy.ts", "../src/utils/lazyReact.tsx", "../src/utils/patches.ts", "../src/debug/Tracer.ts", "../src/webpack/webpack.ts", "../src/webpack/common/classes.ts", "../src/webpack/common/internal.tsx", "../src/webpack/common/components.ts", "../src/webpack/common/menu.ts", "../src/webpack/common/react.ts", "../src/webpack/common/settingsStores.ts", "../src/webpack/common/stores.ts", "../src/webpack/common/types/components.d.ts", "../src/webpack/common/types/menu.d.ts", "../src/webpack/common/types/utils.d.ts", "../src/webpack/common/utils.ts", "../src/webpack/common/index.ts", "git-hash:~git-hash", "git-remote:~git-remote", "../src/utils/constants.ts", "../src/utils/misc.tsx", "../src/utils/react.tsx", "../src/components/ErrorCard.tsx", "../src/components/ErrorBoundary.tsx", "../src/components/Heart.tsx", "../src/components/DonateButton.tsx", "../src/components/Flex.tsx", "../src/utils/modal.tsx", "../src/utils/types.ts", "../src/plugins/_api/badges.tsx", "../src/plugins/_api/commands.ts", "../src/plugins/_api/contextMenu.ts", "../src/plugins/_api/memberListDecorators.ts", "../src/plugins/_api/messageAccessories.ts", "../src/plugins/_api/messageDecorations.ts", "../src/plugins/_api/messageEvents.ts", "../src/plugins/_api/messagePopover.ts", "../src/plugins/_api/notices.ts", "../src/plugins/_api/serverList.ts", "../src/plugins/_core/noTrack.ts", "../src/api/ContextMenu.ts", "../src/utils/debounce.ts", "../src/utils/localStorage.ts", "../src/utils/Queue.ts", "../src/api/Notifications/NotificationComponent.tsx", "../src/api/DataStore/index.ts", "../src/api/Styles.ts", "../node_modules/.pnpm/nanoid@4.0.2/node_modules/nanoid/index.browser.js", "../src/api/Notifications/notificationLog.tsx", "../src/api/Notifications/Notifications.tsx", "../src/api/Notifications/index.ts", "../node_modules/.pnpm/fflate@0.7.4/node_modules/fflate/esm/browser.js", "../src/utils/cloud.tsx", "../src/utils/native.ts", "../src/utils/web.ts", "../src/utils/settingsSync.ts", "../src/api/Settings.ts", "../src/utils/updater.ts", "../src/components/handleComponentFailed.ts", "../src/utils/onlyOnce.ts", "../src/components/VencordSettings/shared.tsx", "../src/components/VencordSettings/VencordTab.tsx", "../src/api/Notices.ts", "../src/components/Icons.tsx", "../src/utils/text.ts", "../src/api/Commands/commandHelpers.ts", "../src/api/Commands/types.ts", "../src/api/Commands/index.ts", "../src/components/Badge.tsx", "../src/components/PluginSettings/components/SettingBooleanComponent.tsx", "../src/components/PluginSettings/components/SettingCustomComponent.tsx", "../src/components/PluginSettings/components/SettingNumericComponent.tsx", "../src/components/PluginSettings/components/SettingSelectComponent.tsx", "../src/components/PluginSettings/components/SettingSliderComponent.tsx", "../src/components/PluginSettings/components/SettingTextComponent.tsx", "../src/components/PluginSettings/components/index.ts", "../src/utils/discord.tsx", "../src/components/PluginSettings/ContributorModal.tsx", "../src/components/PluginSettings/PluginModal.tsx", "../src/components/Switch.tsx", "../src/components/VencordSettings/AddonCard.tsx", "../src/utils/ChangeList.ts", "../src/plugins/index.ts", "../src/components/PluginSettings/index.tsx", "../src/components/VencordSettings/PluginsTab.tsx", "../src/components/Link.tsx", "../src/components/VencordSettings/ThemesTab.tsx", "../src/components/VencordSettings/UpdaterTab.tsx", "../src/components/CheckedTextInput.tsx", "../src/components/VencordSettings/CloudTab.tsx", "../src/components/VencordSettings/BackupAndRestoreTab.tsx", "../src/plugins/_core/settings.tsx", "../src/plugins/_core/supportHelper.tsx", "../src/plugins/alwaysAnimate/index.ts", "../src/plugins/alwaysTrust/index.ts", "../src/plugins/anonymiseFileNames/index.ts", "../src/plugins/arRPC.web/index.tsx", "../src/plugins/banger/index.ts", "../src/plugins/betterFolders/FolderSideBar.tsx", "../src/plugins/betterFolders/index.tsx", "../src/plugins/betterGifAltText/index.ts", "../src/plugins/betterNotes/index.tsx", "../src/plugins/betterRoleDot/index.ts", "../src/plugins/betterUploadButton/index.ts", "../src/plugins/biggerStreamPreview/webpack/stores.ts", "../src/plugins/biggerStreamPreview/index.tsx", "../src/plugins/blurNsfw/index.ts", "../src/plugins/callTimer/index.tsx", "../src/api/MessageEvents.ts", "../src/plugins/clearURLs/defaultRules.ts", "../src/plugins/clearURLs/index.ts", "../src/plugins/clientTheme/index.tsx", "../src/plugins/colorSighted/index.ts", "../src/plugins/consoleShortcuts/index.ts", "../src/plugins/copyUserURLs/index.tsx", "../src/plugins/crashHandler/index.ts", "../src/utils/guards.ts", "../src/plugins/customRPC/index.tsx", "../src/plugins/dearrow/index.tsx", "../src/plugins/decor/lib/constants.ts", "../src/plugins/decor/lib/stores/AuthorizationStore.tsx", "../src/plugins/decor/lib/api.ts", "../src/plugins/decor/lib/utils/decoration.ts", "../src/plugins/decor/lib/stores/UsersDecorationsStore.ts", "../src/plugins/decor/lib/stores/CurrentUserDecorationsStore.ts", "../src/plugins/decor/ui/index.ts", "../src/plugins/decor/ui/components/index.ts", "../src/plugins/decor/ui/components/DecorationGridCreate.tsx", "../src/plugins/decor/ui/components/DecorationGridNone.tsx", "../src/plugins/decor/ui/components/DecorationContextMenu.tsx", "../src/plugins/decor/ui/components/DecorDecorationGridDecoration.tsx", "../src/plugins/decor/ui/components/Grid.tsx", "../src/plugins/decor/ui/components/SectionedGridList.tsx", "../src/plugins/decor/ui/modals/CreateDecorationModal.tsx", "../src/plugins/decor/ui/modals/GuidelinesModal.tsx", "../src/plugins/decor/ui/modals/ChangeDecorationModal.tsx", "../src/plugins/decor/ui/components/DecorSection.tsx", "../src/plugins/decor/settings.tsx", "../src/plugins/decor/index.tsx", "../src/plugins/disableDMCallIdle/index.ts", "../src/plugins/emoteCloner/index.tsx", "../src/plugins/experiments/index.tsx", "../src/plugins/f8break/index.ts", "../src/utils/web-metadata.ts", "../src/utils/apng-canvas.js", "../src/utils/dependencies.ts", "../node_modules/.pnpm/github.com+mattdesl+gifenc@64842fca317b112a8590f8fef2bf3825da8f6fe3/node_modules/gifenc/src/index.js", "../node_modules/.pnpm/github.com+mattdesl+gifenc@64842fca317b112a8590f8fef2bf3825da8f6fe3/node_modules/gifenc/src/constants.js", "../node_modules/.pnpm/github.com+mattdesl+gifenc@64842fca317b112a8590f8fef2bf3825da8f6fe3/node_modules/gifenc/src/stream.js", "../node_modules/.pnpm/github.com+mattdesl+gifenc@64842fca317b112a8590f8fef2bf3825da8f6fe3/node_modules/gifenc/src/lzwEncode.js", "../node_modules/.pnpm/github.com+mattdesl+gifenc@64842fca317b112a8590f8fef2bf3825da8f6fe3/node_modules/gifenc/src/rgb-packing.js", "../node_modules/.pnpm/github.com+mattdesl+gifenc@64842fca317b112a8590f8fef2bf3825da8f6fe3/node_modules/gifenc/src/pnnquant2.js", "../node_modules/.pnpm/github.com+mattdesl+gifenc@64842fca317b112a8590f8fef2bf3825da8f6fe3/node_modules/gifenc/src/color.js", "../node_modules/.pnpm/github.com+mattdesl+gifenc@64842fca317b112a8590f8fef2bf3825da8f6fe3/node_modules/gifenc/src/palettize.js", "../src/plugins/fakeNitro/index.ts", "../node_modules/.pnpm/virtual-merge@1.0.1/node_modules/virtual-merge/dist/index.mjs", "../src/plugins/fakeProfileThemes/index.tsx", "../src/plugins/favEmojiFirst/index.ts", "../src/plugins/favGifSearch/index.tsx", "../src/plugins/fixSpotifyEmbeds.desktop/index.ts", "../src/plugins/forceOwnerCrown/index.ts", "../src/plugins/friendInvites/index.ts", "managed-style:src/plugins/gameActivityToggle/style.css", "../src/plugins/gameActivityToggle/index.tsx", "../src/plugins/gifPaste/index.ts", "../src/plugins/greetStickerPicker/index.tsx", "../src/api/MessagePopover.ts", "../src/plugins/hideAttachments/index.tsx", "../src/plugins/iLoveSpam/index.ts", "../src/plugins/ignoreActivities/index.tsx", "../src/plugins/imageZoom/constants.ts", "../src/plugins/imageZoom/utils/waitFor.ts", "../src/plugins/imageZoom/components/Magnifier.tsx", "managed-style:src/plugins/imageZoom/styles.css", "../src/plugins/imageZoom/index.tsx", "../src/plugins/invisibleChat.desktop/components/DecryptionModal.tsx", "../src/plugins/invisibleChat.desktop/components/EncryptionModal.tsx", "../src/plugins/invisibleChat.desktop/index.tsx", "../src/plugins/keepCurrentChannel/index.ts", "../src/plugins/lastfm/index.tsx", "../src/plugins/loadingQuotes/index.ts", "../src/plugins/memberCount/index.tsx", "../src/plugins/messageClickActions/index.ts", "../src/api/MessageAccessories.ts", "../src/plugins/messageLinkEmbeds/index.tsx", "managed-style:src/plugins/messageLogger/deleteStyleOverlay.css", "managed-style:src/plugins/messageLogger/deleteStyleText.css", "../src/plugins/messageLogger/index.tsx", "../src/plugins/messageTags/index.ts", "../src/plugins/moreCommands/index.ts", "../src/plugins/moreKaomoji/index.ts", "../src/plugins/moreUserTags/index.tsx", "../src/plugins/moyai/index.ts", "../src/plugins/muteNewGuild/index.tsx", "../src/plugins/mutualGroupDMs/index.tsx", "../src/plugins/noBlockedMessages/index.ts", "../src/plugins/noDevtoolsWarning/index.ts", "../src/plugins/noF1/index.ts", "managed-style:src/plugins/noMosaic/styles.css", "../src/plugins/noMosaic/index.ts", "../src/plugins/noPendingCount/index.ts", "../src/plugins/noProfileThemes/index.ts", "../src/plugins/noReplyMention/index.tsx", "../src/plugins/noScreensharePreview/index.ts", "../src/plugins/noTypingAnimation/index.ts", "../src/plugins/noUnblockToJump/index.ts", "../src/plugins/normalizeMessageLinks/index.ts", "../src/plugins/notificationVolume/index.ts", "../src/plugins/nsfwGateBypass/index.ts", "../src/plugins/onePingPerDM/index.ts", "../src/plugins/oneko/index.ts", "../src/plugins/openInApp/index.ts", "../src/plugins/partyMode/index.ts", "../src/plugins/permissionFreeWill/index.ts", "../src/plugins/permissionsViewer/utils.ts", "../src/plugins/permissionsViewer/components/icons.tsx", "../src/plugins/permissionsViewer/components/RolesAndUsersPermissions.tsx", "../src/components/ExpandableHeader.tsx", "../src/plugins/permissionsViewer/components/UserPermissions.tsx", "../src/plugins/permissionsViewer/index.tsx", "../src/plugins/petpet/index.ts", "../src/plugins/pictureInPicture/index.tsx", "../src/plugins/pinDms/settings.ts", "../src/plugins/pinDms/contextMenus.tsx", "../src/plugins/pinDms/index.tsx", "../src/plugins/plainFolderIcon/index.ts", "../src/api/MemberListDecorators.ts", "../src/api/MessageDecorations.ts", "../src/plugins/platformIndicators/index.tsx", "../src/plugins/previewMessage/index.tsx", "../src/plugins/pronoundb/components/PronounsAboutComponent.tsx", "../src/plugins/pronoundb/settings.ts", "../src/plugins/pronoundb/types.ts", "../src/plugins/pronoundb/pronoundbUtils.ts", "../src/plugins/pronoundb/components/PronounsChatComponent.tsx", "../src/plugins/pronoundb/index.ts", "../src/plugins/quickMention/index.tsx", "../src/plugins/quickReply/index.ts", "../src/plugins/reactErrorDecoder/index.ts", "../src/api/ServerList.ts", "../src/plugins/readAllNotificationsButton/index.tsx", "../src/plugins/relationshipNotifier/settings.ts", "../src/plugins/relationshipNotifier/types.ts", "../src/plugins/relationshipNotifier/utils.ts", "../src/plugins/relationshipNotifier/functions.ts", "../src/plugins/relationshipNotifier/index.ts", "../src/plugins/revealAllSpoilers/index.ts", "../src/plugins/reverseImageSearch/index.tsx", "../src/plugins/roleColorEverywhere/index.tsx", "../src/plugins/searchReply/index.tsx", "../src/plugins/secretRingTone/index.ts", "../src/plugins/sendTimestamps/index.tsx", "../src/plugins/serverListIndicators/index.tsx", "../src/plugins/serverProfile/GuildProfileModal.tsx", "../src/plugins/serverProfile/index.tsx", "include-file:~fileContent/previewExample.tsx", "../node_modules/.pnpm/eventemitter3@4.0.7/node_modules/eventemitter3/index.js", "../node_modules/.pnpm/@vap+core@0.0.12/node_modules/@vap/core/ipc/channel.js", "../node_modules/.pnpm/@vap+core@0.0.12/node_modules/@vap/core/ipc/rpc.js", "../node_modules/.pnpm/@vap+core@0.0.12/node_modules/@vap/core/ipc/worker.js", "../node_modules/.pnpm/@vap+core@0.0.12/node_modules/@vap/core/ipc/index.js", "../src/plugins/shikiCodeblocks.desktop/hooks/useTheme.ts", "../src/plugins/shikiCodeblocks.desktop/api/languages.ts", "../src/plugins/shikiCodeblocks.desktop/api/themes.ts", "../src/plugins/shikiCodeblocks.desktop/api/shiki.ts", "managed-style:src/plugins/shikiCodeblocks.desktop/devicon.css", "../src/plugins/shikiCodeblocks.desktop/types.ts", "../src/plugins/shikiCodeblocks.desktop/settings.ts", "../src/plugins/shikiCodeblocks.desktop/hooks/useShikiSettings.ts", "../src/plugins/shikiCodeblocks.desktop/utils/color.ts", "../src/plugins/shikiCodeblocks.desktop/utils/misc.ts", "../src/plugins/shikiCodeblocks.desktop/hooks/useCopyCooldown.ts", "../src/plugins/shikiCodeblocks.desktop/components/CopyButton.tsx", "../src/plugins/shikiCodeblocks.desktop/components/ButtonRow.tsx", "../src/plugins/shikiCodeblocks.desktop/components/Code.tsx", "../src/plugins/shikiCodeblocks.desktop/components/Header.tsx", "../src/plugins/shikiCodeblocks.desktop/components/Highlighter.tsx", "../src/plugins/shikiCodeblocks.desktop/utils/createStyle.ts", "../src/plugins/shikiCodeblocks.desktop/index.ts", "../src/plugins/showAllMessageButtons/index.ts", "../src/plugins/showConnections/VerifiedIcon.tsx", "../src/plugins/showConnections/index.tsx", "../src/plugins/showHiddenChannels/components/HiddenChannelLockScreen.tsx", "../src/plugins/showHiddenChannels/index.tsx", "../src/plugins/showMeYourName/index.tsx", "../src/plugins/showTimeouts/index.ts", "../src/plugins/silentMessageToggle/index.tsx", "../src/plugins/silentTyping/index.tsx", "../src/plugins/sortFriendRequests/index.tsx", "managed-style:src/plugins/spotifyControls/hoverOnly.css", "../src/plugins/spotifyControls/SpotifyStore.ts", "../src/plugins/spotifyControls/PlayerComponent.tsx", "../src/plugins/spotifyControls/index.tsx", "../src/plugins/spotifyCrack/index.ts", "../src/plugins/spotifyShareCommands/index.ts", "../src/plugins/startupTimings/StartupTimingPage.tsx", "../src/plugins/startupTimings/index.tsx", "../src/plugins/superReactionTweaks/index.ts", "../src/plugins/textReplace/index.tsx", "../src/plugins/themeAttributes/index.ts", "../src/plugins/timeBarAllActivities/index.ts", "../src/plugins/translate/settings.ts", "../src/plugins/translate/languages.ts", "../src/plugins/translate/utils.ts", "../src/plugins/translate/TranslateModal.tsx", "../src/plugins/translate/TranslateIcon.tsx", "../src/plugins/translate/TranslationAccessory.tsx", "../src/plugins/translate/index.tsx", "../src/plugins/typingTweaks/index.tsx", "../src/plugins/typingIndicator/index.tsx", "../src/plugins/unindent/index.ts", "../src/plugins/unsuppressEmbeds/index.tsx", "../src/plugins/urbanDictionary/index.ts", "../src/plugins/userVoiceShow/components/VoiceChannelSection.tsx", "../src/plugins/userVoiceShow/index.tsx", "managed-style:src/plugins/usrbg/index.css", "../src/plugins/usrbg/index.tsx", "../src/plugins/validUser/index.tsx", "../src/plugins/vcDoubleClick/index.ts", "../src/plugins/vcNarrator/index.tsx", "../src/plugins/vencordToolbox/index.tsx", "../src/plugins/viewIcons/index.tsx", "../src/components/CodeBlock.tsx", "../src/plugins/viewRaw/index.tsx", "../src/plugins/voiceMessages/settings.ts", "../src/plugins/voiceMessages/DesktopRecorder.tsx", "../src/plugins/voiceMessages/utils.ts", "../src/plugins/voiceMessages/VoicePreview.tsx", "../src/plugins/voiceMessages/WebRecorder.tsx", "../src/plugins/voiceMessages/index.tsx", "../src/plugins/webContextMenus.web/index.ts", "../src/plugins/webKeybinds.web/index.ts", "../src/plugins/whoReacted/index.tsx", "../src/plugins/wikisearch/index.ts", "../src/plugins/xsOverlay.desktop/index.ts", "import-plugins:~plugins", "../src/api/Badges.ts", "../src/api/index.ts", "../src/Vencord.ts", "../src/utils/index.ts", "../src/utils/onceDefined.ts", "../src/utils/quickCss.ts", "../src/webpack/index.ts", "../src/webpack/patchWebpack.ts"],
"sourcesContent": ["/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nexport const VencordFragment = /* #__PURE__*/ Symbol.for(\"react.fragment\");\nexport let VencordCreateElement =\n (...args) => (VencordCreateElement = Vencord.Webpack.Common.React.createElement)(...args);\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nexport class Logger {\n /**\n * Returns the console format args for a title with the specified background colour and black text\n * @param color Background colour\n * @param title Text\n * @returns Array. Destructure this into {@link Logger}.errorCustomFmt or console.log\n *\n * @example logger.errorCustomFmt(...Logger.makeTitleElements(\"white\", \"Hello\"), \"World\");\n */\n static makeTitle(color: string, title: string): [string, ...string[]] {\n return [\"%c %c %s \", \"\", `background: ${color}; color: black; font-weight: bold; border-radius: 5px;`, title];\n }\n\n constructor(public name: string, public color: string = \"white\") { }\n\n private _log(level: \"log\" | \"error\" | \"warn\" | \"info\" | \"debug\", levelColor: string, args: any[], customFmt = \"\") {\n console[level](\n `%c Vencord %c %c ${this.name} ${customFmt}`,\n `background: ${levelColor}; color: black; font-weight: bold; border-radius: 5px;`,\n \"\",\n `background: ${this.color}; color: black; font-weight: bold; border-radius: 5px;`\n , ...args\n );\n }\n\n public log(...args: any[]) {\n this._log(\"log\", \"#a6d189\", args);\n }\n\n public info(...args: any[]) {\n this._log(\"info\", \"#a6d189\", args);\n }\n\n public error(...args: any[]) {\n this._log(\"error\", \"#e78284\", args);\n }\n\n public errorCustomFmt(fmt: string, ...args: any[]) {\n this._log(\"error\", \"#e78284\", args, fmt);\n }\n\n public warn(...args: any[]) {\n this._log(\"warn\", \"#e5c890\", args);\n }\n\n public debug(...args: any[]) {\n this._log(\"debug\", \"#eebebe\", args);\n }\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nlet styleStr = \"\";\n\nexport const Margins: Record<`${\"top\" | \"bottom\" | \"left\" | \"right\"}${8 | 16 | 20}`, string> = {} as any;\n\nfor (const dir of [\"top\", \"bottom\", \"left\", \"right\"] as const) {\n for (const size of [8, 16, 20] as const) {\n const cl = `vc-m-${dir}-${size}`;\n Margins[`${dir}${size}`] = cl;\n styleStr += `.${cl}{margin-${dir}:${size}px;}`;\n }\n}\n\ndocument.addEventListener(\"DOMContentLoaded\", () =>\n document.head.append(Object.assign(document.createElement(\"style\"), {\n textContent: styleStr,\n id: \"vencord-margins\"\n })), { once: true });\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nexport function makeLazy<T>(factory: () => T, attempts = 5): () => T {\n let tries = 0;\n let cache: T;\n return () => {\n if (!cache && attempts > tries++) {\n cache = factory();\n if (!cache && attempts === tries)\n console.error(\"Lazy factory failed:\", factory);\n }\n return cache;\n };\n}\n\n// Proxies demand that these properties be unmodified, so proxyLazy\n// will always return the function default for them.\nconst unconfigurable = [\"arguments\", \"caller\", \"prototype\"];\n\nconst handler: ProxyHandler<any> = {};\n\nconst kGET = Symbol.for(\"vencord.lazy.get\");\nconst kCACHE = Symbol.for(\"vencord.lazy.cached\");\n\nfor (const method of [\n \"apply\",\n \"construct\",\n \"defineProperty\",\n \"deleteProperty\",\n \"getOwnPropertyDescriptor\",\n \"getPrototypeOf\",\n \"has\",\n \"isExtensible\",\n \"ownKeys\",\n \"preventExtensions\",\n \"set\",\n \"setPrototypeOf\"\n]) {\n handler[method] =\n (target: any, ...args: any[]) => Reflect[method](target[kGET](), ...args);\n}\n\nhandler.ownKeys = target => {\n const v = target[kGET]();\n const keys = Reflect.ownKeys(v);\n for (const key of unconfigurable) {\n if (!keys.includes(key)) keys.push(key);\n }\n return keys;\n};\n\nhandler.getOwnPropertyDescriptor = (target, p) => {\n if (typeof p === \"string\" && unconfigurable.includes(p))\n return Reflect.getOwnPropertyDescriptor(target, p);\n\n const descriptor = Reflect.getOwnPropertyDescriptor(target[kGET](), p);\n\n if (descriptor) Object.defineProperty(target, p, descriptor);\n return descriptor;\n};\n\n/**\n * Wraps the result of {@link makeLazy} in a Proxy you can consume as if it wasn't lazy.\n * On first property access, the lazy is evaluated\n * @param factory lazy factory\n * @param attempts how many times to try to evaluate the lazy before giving up\n * @returns Proxy\n *\n * Note that the example below exists already as an api, see {@link findByPropsLazy}\n * @example const mod = proxyLazy(() => findByProps(\"blah\")); console.log(mod.blah);\n */\nexport function proxyLazy<T>(factory: () => T, attempts = 5, isChild = false): T {\n let isSameTick = true;\n if (!isChild)\n setTimeout(() => isSameTick = false, 0);\n\n let tries = 0;\n const proxyDummy = Object.assign(function () { }, {\n [kCACHE]: void 0 as T | undefined,\n [kGET]() {\n if (!proxyDummy[kCACHE] && attempts > tries++) {\n proxyDummy[kCACHE] = factory();\n if (!proxyDummy[kCACHE] && attempts === tries)\n console.error(\"Lazy factory failed:\", factory);\n }\n return proxyDummy[kCACHE];\n }\n });\n\n return new Proxy(proxyDummy, {\n ...handler,\n get(target, p, receiver) {\n // if we're still in the same tick, it means the lazy was immediately used.\n // thus, we lazy proxy the get access to make things like destructuring work as expected\n // meow here will also be a lazy\n // `const { meow } = findByPropsLazy(\"meow\");`\n if (!isChild && isSameTick)\n return proxyLazy(\n () => Reflect.get(target[kGET](), p, receiver),\n attempts,\n true\n );\n\n return Reflect.get(target[kGET](), p, receiver);\n }\n }) as any;\n}\n", "/*\n * Vencord, a Discord client mod\n * Copyright (c) 2023 Vendicated and contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport { ComponentType } from \"react\";\n\nimport { makeLazy } from \"./lazy\";\n\nconst NoopComponent = () => null;\n\n/**\n * A lazy component. The factory method is called on first render.\n * @param factory Function returning a Component\n * @param attempts How many times to try to get the component before giving up\n * @returns Result of factory function\n */\nexport function LazyComponent<T extends object = any>(factory: () => React.ComponentType<T>, attempts = 5) {\n const get = makeLazy(factory, attempts);\n const LazyComponent = (props: T) => {\n const Component = get() ?? NoopComponent;\n return <Component {...props} />;\n };\n\n LazyComponent.$$vencordInternal = get;\n\n return LazyComponent as ComponentType<T>;\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { PatchReplacement, ReplaceFn } from \"./types\";\n\nexport function canonicalizeMatch(match: RegExp | string) {\n if (typeof match === \"string\") return match;\n const canonSource = match.source\n .replaceAll(\"\\\\i\", \"[A-Za-z_$][\\\\w$]*\");\n return new RegExp(canonSource, match.flags);\n}\n\nexport function canonicalizeReplace(replace: string | ReplaceFn, pluginName: string): string | ReplaceFn {\n const self = `Vencord.Plugins.plugins[${JSON.stringify(pluginName)}]`;\n\n if (typeof replace !== \"function\")\n return replace.replaceAll(\"$self\", self);\n\n return (...args) => replace(...args).replaceAll(\"$self\", self);\n}\n\nexport function canonicalizeDescriptor<T>(descriptor: TypedPropertyDescriptor<T>, canonicalize: (value: T) => T) {\n if (descriptor.get) {\n const original = descriptor.get;\n descriptor.get = function () {\n return canonicalize(original.call(this));\n };\n } else if (descriptor.value) {\n descriptor.value = canonicalize(descriptor.value);\n }\n return descriptor;\n}\n\nexport function canonicalizeReplacement(replacement: Pick<PatchReplacement, \"match\" | \"replace\">, plugin: string) {\n const descriptors = Object.getOwnPropertyDescriptors(replacement);\n descriptors.match = canonicalizeDescriptor(descriptors.match, canonicalizeMatch);\n descriptors.replace = canonicalizeDescriptor(\n descriptors.replace,\n replace => canonicalizeReplace(replace, plugin),\n );\n Object.defineProperties(replacement, descriptors);\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Logger } from \"@utils/Logger\";\n\nif (IS_DEV) {\n var traces = {} as Record<string, [number, any[]]>;\n var logger = new Logger(\"Tracer\", \"#FFD166\");\n}\n\nconst noop = function () { };\n\nexport const beginTrace = !IS_DEV ? noop :\n function beginTrace(name: string, ...args: any[]) {\n if (name in traces)\n throw new Error(`Trace ${name} already exists!`);\n\n traces[name] = [performance.now(), args];\n };\n\nexport const finishTrace = !IS_DEV ? noop : function finishTrace(name: string) {\n const end = performance.now();\n\n const [start, args] = traces[name];\n delete traces[name];\n\n logger.debug(`${name} took ${end - start}ms`, args);\n};\n\ntype Func = (...args: any[]) => any;\ntype TraceNameMapper<F extends Func> = (...args: Parameters<F>) => string;\n\nconst noopTracer =\n <F extends Func>(name: string, f: F, mapper?: TraceNameMapper<F>) => f;\n\nexport const traceFunction = !IS_DEV\n ? noopTracer\n : function traceFunction<F extends Func>(name: string, f: F, mapper?: TraceNameMapper<F>): F {\n return function (this: any, ...args: Parameters<F>) {\n const traceName = mapper?.(...args) ?? name;\n\n beginTrace(traceName, ...arguments);\n try {\n return f.apply(this, args);\n } finally {\n finishTrace(traceName);\n }\n } as F;\n };\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { proxyLazy } from \"@utils/lazy\";\nimport { LazyComponent } from \"@utils/lazyReact\";\nimport { Logger } from \"@utils/Logger\";\nimport { canonicalizeMatch } from \"@utils/patches\";\nimport type { WebpackInstance } from \"discord-types/other\";\n\nimport { traceFunction } from \"../debug/Tracer\";\n\nconst logger = new Logger(\"Webpack\");\n\nexport let _resolveReady: () => void;\n/**\n * Fired once a gateway connection to Discord has been established.\n * This indicates that the core webpack modules have been initialised\n */\nexport const onceReady = new Promise<void>(r => _resolveReady = r);\n\nexport let wreq: WebpackInstance;\nexport let cache: WebpackInstance[\"c\"];\n\nexport type FilterFn = (mod: any) => boolean;\n\nexport const filters = {\n byProps: (...props: string[]): FilterFn =>\n props.length === 1\n ? m => m[props[0]] !== void 0\n : m => props.every(p => m[p] !== void 0),\n\n byCode: (...code: string[]): FilterFn => m => {\n if (typeof m !== \"function\") return false;\n const s = Function.prototype.toString.call(m);\n for (const c of code) {\n if (!s.includes(c)) return false;\n }\n return true;\n },\n byStoreName: (name: string): FilterFn => m =>\n m.constructor?.displayName === name,\n\n componentByCode: (...code: string[]): FilterFn => {\n const filter = filters.byCode(...code);\n return m => {\n if (filter(m)) return true;\n if (!m.$$typeof) return false;\n if (m.type) return filter(m.type); // memos\n if (m.render) return filter(m.render); // forwardRefs\n return false;\n };\n }\n};\n\nexport const subscriptions = new Map<FilterFn, CallbackFn>();\nexport const listeners = new Set<CallbackFn>();\n\nexport type CallbackFn = (mod: any, id: string) => void;\n\nexport function _initWebpack(instance: typeof window.webpackChunkdiscord_app) {\n if (cache !== void 0) throw \"no.\";\n\n instance.push([[Symbol(\"Vencord\")], {}, r => wreq = r]);\n instance.pop();\n if (!wreq) return false;\n\n cache = wreq.c;\n return true;\n}\n\nif (IS_DEV && IS_DISCORD_DESKTOP) {\n var devToolsOpen = false;\n // At this point in time, DiscordNative has not been exposed yet, so setImmediate is needed\n setTimeout(() => {\n DiscordNative/* just to make sure */?.window.setDevtoolsCallbacks(() => devToolsOpen = true, () => devToolsOpen = false);\n }, 0);\n}\n\nfunction handleModuleNotFound(method: string, ...filter: unknown[]) {\n const err = new Error(`webpack.${method} found no module`);\n logger.error(err, \"Filter:\", filter);\n\n // Strict behaviour in DevBuilds to fail early and make sure the issue is found\n if (IS_DEV && !devToolsOpen)\n throw err;\n}\n\n/**\n * Find the first module that matches the filter\n */\nexport const find = traceFunction(\"find\", function find(filter: FilterFn, { isIndirect = false, isWaitFor = false }: { isIndirect?: boolean; isWaitFor?: boolean; } = {}) {\n if (typeof filter !== \"function\")\n throw new Error(\"Invalid filter. Expected a function got \" + typeof filter);\n\n for (const key in cache) {\n const mod = cache[key];\n if (!mod?.exports) continue;\n\n if (filter(mod.exports)) {\n return isWaitFor ? [mod.exports, key] : mod.exports;\n }\n\n if (mod.exports.default && filter(mod.exports.default)) {\n const found = mod.exports.default;\n return isWaitFor ? [found, key] : found;\n }\n }\n\n if (!isIndirect) {\n handleModuleNotFound(\"find\", filter);\n }\n\n return isWaitFor ? [null, null] : null;\n});\n\nexport function findAll(filter: FilterFn) {\n if (typeof filter !== \"function\")\n throw new Error(\"Invalid filter. Expected a function got \" + typeof filter);\n\n const ret = [] as any[];\n for (const key in cache) {\n const mod = cache[key];\n if (!mod?.exports) continue;\n\n if (filter(mod.exports))\n ret.push(mod.exports);\n\n if (mod.exports.default && filter(mod.exports.default))\n ret.push(mod.exports.default);\n }\n\n return ret;\n}\n\n/**\n * Same as {@link find} but in bulk\n * @param filterFns Array of filters. Please note that this array will be modified in place, so if you still\n * need it afterwards, pass a copy.\n * @returns Array of results in the same order as the passed filters\n */\nexport const findBulk = traceFunction(\"findBulk\", function findBulk(...filterFns: FilterFn[]) {\n if (!Array.isArray(filterFns))\n throw new Error(\"Invalid filters. Expected function[] got \" + typeof filterFns);\n\n const { length } = filterFns;\n\n if (length === 0)\n throw new Error(\"Expected at least two filters.\");\n\n if (length === 1) {\n if (IS_DEV) {\n throw new Error(\"bulk called with only one filter. Use find\");\n }\n return find(filterFns[0]);\n }\n\n const filters = filterFns as Array<FilterFn | undefined>;\n\n let found = 0;\n const results = Array(length);\n\n outer:\n for (const key in cache) {\n const mod = cache[key];\n if (!mod?.exports) continue;\n\n for (let j = 0; j < length; j++) {\n const filter = filters[j];\n // Already done\n if (filter === undefined) continue;\n\n if (filter(mod.exports)) {\n results[j] = mod.exports;\n filters[j] = undefined;\n if (++found === length) break outer;\n break;\n }\n\n if (mod.exports.default && filter(mod.exports.default)) {\n results[j] = mod.exports.default;\n filters[j] = undefined;\n if (++found === length) break outer;\n break;\n }\n }\n }\n\n if (found !== length) {\n const err = new Error(`Got ${length} filters, but only found ${found} modules!`);\n if (IS_DEV) {\n if (!devToolsOpen)\n // Strict behaviour in DevBuilds to fail early and make sure the issue is found\n throw err;\n } else {\n logger.warn(err);\n }\n }\n\n return results;\n});\n\n/**\n * Find the id of the first module factory that includes all the given code\n * @returns string or null\n */\nexport const findModuleId = traceFunction(\"findModuleId\", function findModuleId(...code: string[]) {\n outer:\n for (const id in wreq.m) {\n const str = wreq.m[id].toString();\n\n for (const c of code) {\n if (!str.includes(c)) continue outer;\n }\n return id;\n }\n\n const err = new Error(\"Didn't find module with code(s):\\n\" + code.join(\"\\n\"));\n if (IS_DEV) {\n if (!devToolsOpen)\n // Strict behaviour in DevBuilds to fail early and make sure the issue is found\n throw err;\n } else {\n logger.warn(err);\n }\n\n return null;\n});\n\n/**\n * Find the first module factory that includes all the given code\n * @returns The module factory or null\n */\nexport function findModuleFactory(...code: string[]) {\n const id = findModuleId(...code);\n if (!id) return null;\n\n return wreq.m[id];\n}\n\nexport const lazyWebpackSearchHistory = [] as Array<[\"find\" | \"findByProps\" | \"findByCode\" | \"findStore\" | \"findComponent\" | \"findComponentByCode\" | \"findExportedComponent\" | \"waitFor\" | \"waitForComponent\" | \"waitForStore\" | \"proxyLazyWebpack\" | \"LazyComponentWebpack\" | \"extractAndLoadChunks\", any[]]>;\n\n/**\n * This is just a wrapper around {@link proxyLazy} to make our reporter test for your webpack finds.\n *\n * Wraps the result of {@link makeLazy} in a Proxy you can consume as if it wasn't lazy.\n * On first property access, the lazy is evaluated\n * @param factory lazy factory\n * @param attempts how many times to try to evaluate the lazy before giving up\n * @returns Proxy\n *\n * Note that the example below exists already as an api, see {@link findByPropsLazy}\n * @example const mod = proxyLazy(() => findByProps(\"blah\")); console.log(mod.blah);\n */\nexport function proxyLazyWebpack<T = any>(factory: () => any, attempts?: number) {\n if (IS_DEV) lazyWebpackSearchHistory.push([\"proxyLazyWebpack\", [factory]]);\n\n return proxyLazy<T>(factory, attempts);\n}\n\n/**\n * This is just a wrapper around {@link LazyComponent} to make our reporter test for your webpack finds.\n *\n * A lazy component. The factory method is called on first render.\n * @param factory Function returning a Component\n * @param attempts How many times to try to get the component before giving up\n * @returns Result of factory function\n */\nexport function LazyComponentWebpack<T extends object = any>(factory: () => any, attempts?: number) {\n if (IS_DEV) lazyWebpackSearchHistory.push([\"LazyComponentWebpack\", [factory]]);\n\n return LazyComponent<T>(factory, attempts);\n}\n\n/**\n * Find the first module that matches the filter, lazily\n */\nexport function findLazy(filter: FilterFn) {\n if (IS_DEV) lazyWebpackSearchHistory.push([\"find\", [filter]]);\n\n return proxyLazy(() => find(filter));\n}\n\n/**\n * Find the first module that has the specified properties\n */\nexport function findByProps(...props: string[]) {\n const res = find(filters.byProps(...props), { isIndirect: true });\n if (!res)\n handleModuleNotFound(\"findByProps\", ...props);\n return res;\n}\n\n/**\n * Find the first module that has the specified properties, lazily\n */\nexport function findByPropsLazy(...props: string[]) {\n if (IS_DEV) lazyWebpackSearchHistory.push([\"findByProps\", props]);\n\n return proxyLazy(() => findByProps(...props));\n}\n\n/**\n * Find the first function that includes all the given code\n */\nexport function findByCode(...code: string[]) {\n const res = find(filters.byCode(...code), { isIndirect: true });\n if (!res)\n handleModuleNotFound(\"findByCode\", ...code);\n return res;\n}\n\n/**\n * Find the first function that includes all the given code, lazily\n */\nexport function findByCodeLazy(...code: string[]) {\n if (IS_DEV) lazyWebpackSearchHistory.push([\"findByCode\", code]);\n\n return proxyLazy(() => findByCode(...code));\n}\n\n/**\n * Find a store by its displayName\n */\nexport function findStore(name: string) {\n const res = find(filters.byStoreName(name), { isIndirect: true });\n if (!res)\n handleModuleNotFound(\"findStore\", name);\n return res;\n}\n\n/**\n * Find a store by its displayName, lazily\n */\nexport function findStoreLazy(name: string) {\n if (IS_DEV) lazyWebpackSearchHistory.push([\"findStore\", [name]]);\n\n return proxyLazy(() => findStore(name));\n}\n\n/**\n * Finds the component which includes all the given code. Checks for plain components, memos and forwardRefs\n */\nexport function findComponentByCode(...code: string[]) {\n const res = find(filters.componentByCode(...code), { isIndirect: true });\n if (!res)\n handleModuleNotFound(\"findComponentByCode\", ...code);\n return res;\n}\n\n/**\n * Finds the first component that matches the filter, lazily.\n */\nexport function findComponentLazy<T extends object = any>(filter: FilterFn) {\n if (IS_DEV) lazyWebpackSearchHistory.push([\"findComponent\", [filter]]);\n\n\n return LazyComponent<T>(() => {\n const res = find(filter, { isIndirect: true });\n if (!res)\n handleModuleNotFound(\"findComponent\", filter);\n return res;\n });\n}\n\n/**\n * Finds the first component that includes all the given code, lazily\n */\nexport function findComponentByCodeLazy<T extends object = any>(...code: string[]) {\n if (IS_DEV) lazyWebpackSearchHistory.push([\"findComponentByCode\", code]);\n\n return LazyComponent<T>(() => {\n const res = find(filters.componentByCode(...code), { isIndirect: true });\n if (!res)\n handleModuleNotFound(\"findComponentByCode\", ...code);\n return res;\n });\n}\n\n/**\n * Finds the first component that is exported by the first prop name, lazily\n */\nexport function findExportedComponentLazy<T extends object = any>(...props: string[]) {\n if (IS_DEV) lazyWebpackSearchHistory.push([\"findExportedComponent\", props]);\n\n return LazyComponent<T>(() => {\n const res = find(filters.byProps(...props), { isIndirect: true });\n if (!res)\n handleModuleNotFound(\"findExportedComponent\", ...props);\n return res[props[0]];\n });\n}\n\n/**\n * Extract and load chunks using their entry point\n * @param code An array of all the code the module factory containing the entry point (as of using it to load chunks) must include\n * @param matcher A RegExp that returns the entry point id as the first capture group. Defaults to a matcher that captures the first entry point found in the module factory\n */\nexport async function extractAndLoadChunks(code: string[], matcher: RegExp = /\\.el\\(\"(.+?)\"\\)(?<=(\\i)\\.el.+?)\\.then\\(\\2\\.bind\\(\\2,\"\\1\"\\)\\)/) {\n const module = findModuleFactory(...code);\n if (!module) {\n const err = new Error(\"extractAndLoadChunks: Couldn't find module factory\");\n logger.warn(err, \"Code:\", code, \"Matcher:\", matcher);\n\n return;\n }\n\n const match = module.toString().match(canonicalizeMatch(matcher));\n if (!match) {\n const err = new Error(\"extractAndLoadChunks: Couldn't find entry point id in module factory code\");\n logger.warn(err, \"Code:\", code, \"Matcher:\", matcher);\n\n // Strict behaviour in DevBuilds to fail early and make sure the issue is found\n if (IS_DEV && !devToolsOpen)\n throw err;\n\n return;\n }\n\n const [, id] = match;\n if (!id || !Number(id)) {\n const err = new Error(\"extractAndLoadChunks: Matcher didn't return a capturing group with the entry point, or the entry point returned wasn't a number\");\n logger.warn(err, \"Code:\", code, \"Matcher:\", matcher);\n\n // Strict behaviour in DevBuilds to fail early and make sure the issue is found\n if (IS_DEV && !devToolsOpen)\n throw err;\n\n return;\n }\n\n await (wreq as any).el(id);\n return wreq(id as any);\n}\n\n/**\n * This is just a wrapper around {@link extractAndLoadChunks} to make our reporter test for your webpack finds.\n *\n * Extract and load chunks using their entry point\n * @param code An array of all the code the module factory containing the entry point (as of using it to load chunks) must include\n * @param matcher A RegExp that returns the entry point id as the first capture group. Defaults to a matcher that captures the first entry point found in the module factory\n * @returns A function that loads the chunks on first call\n */\nexport function extractAndLoadChunksLazy(code: string[], matcher: RegExp = /\\.el\\(\"(.+?)\"\\)(?<=(\\i)\\.el.+?)\\.then\\(\\2\\.bind\\(\\2,\"\\1\"\\)\\)/) {\n if (IS_DEV) lazyWebpackSearchHistory.push([\"extractAndLoadChunks\", [code, matcher]]);\n\n return () => extractAndLoadChunks(code, matcher);\n}\n\n/**\n * Wait for a module that matches the provided filter to be registered,\n * then call the callback with the module as the first argument\n */\nexport function waitFor(filter: string | string[] | FilterFn, callback: CallbackFn, { isIndirect = false }: { isIndirect?: boolean; } = {}) {\n if (IS_DEV && !isIndirect) lazyWebpackSearchHistory.push([\"waitFor\", Array.isArray(filter) ? filter : [filter]]);\n\n if (typeof filter === \"string\")\n filter = filters.byProps(filter);\n else if (Array.isArray(filter))\n filter = filters.byProps(...filter);\n else if (typeof filter !== \"function\")\n throw new Error(\"filter must be a string, string[] or function, got \" + typeof filter);\n\n const [existing, id] = find(filter!, { isIndirect: true, isWaitFor: true });\n if (existing) return void callback(existing, id);\n\n subscriptions.set(filter, callback);\n}\n\nexport function addListener(callback: CallbackFn) {\n listeners.add(callback);\n}\n\nexport function removeListener(callback: CallbackFn) {\n listeners.delete(callback);\n}\n\n/**\n * Search modules by keyword. This searches the factory methods,\n * meaning you can search all sorts of things, displayName, methodName, strings somewhere in the code, etc\n * @param filters One or more strings or regexes\n * @returns Mapping of found modules\n */\nexport function search(...filters: Array<string | RegExp>) {\n const results = {} as Record<number, Function>;\n const factories = wreq.m;\n outer:\n for (const id in factories) {\n const factory = factories[id].original ?? factories[id];\n const str: string = factory.toString();\n for (const filter of filters) {\n if (typeof filter === \"string\" && !str.includes(filter)) continue outer;\n if (filter instanceof RegExp && !filter.test(str)) continue outer;\n }\n results[id] = factory;\n }\n\n return results;\n}\n\n/**\n * Extract a specific module by id into its own Source File. This has no effect on\n * the code, it is only useful to be able to look at a specific module without having\n * to view a massive file. extract then returns the extracted module so you can jump to it.\n * As mentioned above, note that this extracted module is not actually used,\n * so putting breakpoints or similar will have no effect.\n * @param id The id of the module to extract\n */\nexport function extract(id: string | number) {\n const mod = wreq.m[id] as Function;\n if (!mod) return null;\n\n const code = `\n// [EXTRACTED] WebpackModule${id}\n// WARNING: This module was extracted to be more easily readable.\n// This module is NOT ACTUALLY USED! This means putting breakpoints will have NO EFFECT!!\n\n0,${mod.toString()}\n//# sourceURL=ExtractedWebpackModule${id}\n`;\n const extracted = (0, eval)(code);\n return extracted as Function;\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { findByPropsLazy, findLazy } from \"@webpack\";\n\nimport * as t from \"./types/classes\";\n\nexport const ModalImageClasses: t.ImageModalClasses = findLazy(m => m.image && m.modal && !m.applicationIcon);\nexport const ButtonWrapperClasses: t.ButtonWrapperClasses = findByPropsLazy(\"buttonWrapper\", \"buttonContent\");\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { LazyComponent } from \"@utils/react\";\n\n// eslint-disable-next-line path-alias/no-relative\nimport { FilterFn, filters, lazyWebpackSearchHistory, waitFor } from \"../webpack\";\n\nexport function waitForComponent<T extends React.ComponentType<any> = React.ComponentType<any> & Record<string, any>>(name: string, filter: FilterFn | string | string[]): T {\n if (IS_DEV) lazyWebpackSearchHistory.push([\"waitForComponent\", Array.isArray(filter) ? filter : [filter]]);\n\n let myValue: T = function () {\n throw new Error(`Vencord could not find the ${name} Component`);\n } as any;\n\n const lazyComponent = LazyComponent(() => myValue) as T;\n waitFor(filter, (v: any) => {\n myValue = v;\n Object.assign(lazyComponent, v);\n }, { isIndirect: true });\n\n return lazyComponent;\n}\n\nexport function waitForStore(name: string, cb: (v: any) => void) {\n if (IS_DEV) lazyWebpackSearchHistory.push([\"waitForStore\", [name]]);\n\n waitFor(filters.byStoreName(name), cb, { isIndirect: true });\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\n// eslint-disable-next-line path-alias/no-relative\nimport { filters, findByPropsLazy, waitFor } from \"@webpack\";\n\nimport { waitForComponent } from \"./internal\";\nimport * as t from \"./types/components\";\n\nexport let Forms = {} as {\n FormTitle: t.FormTitle,\n FormSection: t.FormSection,\n FormDivider: t.FormDivider,\n FormText: t.FormText,\n};\n\nexport let Card: t.Card;\nexport let Button: t.Button;\nexport let Switch: t.Switch;\nexport let Tooltip: t.Tooltip;\nexport let TextInput: t.TextInput;\nexport let TextArea: t.TextArea;\nexport let Text: t.Text;\nexport let Select: t.Select;\nexport let SearchableSelect: t.SearchableSelect;\nexport let Slider: t.Slider;\nexport let ButtonLooks: t.ButtonLooks;\nexport let Popout: t.Popout;\nexport let Dialog: t.Dialog;\nexport let TabBar: any;\nexport let Paginator: t.Paginator;\nexport let ScrollerThin: t.ScrollerThin;\nexport let Clickable: t.Clickable;\nexport let Avatar: t.Avatar;\n// token lagger real\n/** css colour resolver stuff, no clue what exactly this does, just copied usage from Discord */\nexport let useToken: t.useToken;\n\nexport const MaskedLink = waitForComponent<t.MaskedLink>(\"MaskedLink\", m => m?.type?.toString().includes(\"MASKED_LINK)\"));\nexport const Timestamp = waitForComponent<t.Timestamp>(\"Timestamp\", filters.byCode(\".Messages.MESSAGE_EDITED_TIMESTAMP_A11Y_LABEL.format\"));\nexport const Flex = waitForComponent<t.Flex>(\"Flex\", [\"Justify\", \"Align\", \"Wrap\"]);\n\nexport const { OAuth2AuthorizeModal } = findByPropsLazy(\"OAuth2AuthorizeModal\");\n\nwaitFor([\"FormItem\", \"Button\"], m => {\n ({ useToken, Card, Button, FormSwitch: Switch, Tooltip, TextInput, TextArea, Text, Select, SearchableSelect, Slider, ButtonLooks, TabBar, Popout, Dialog, Paginator, ScrollerThin, Clickable, Avatar } = m);\n Forms = m;\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\n// eslint-disable-next-line path-alias/no-relative\nimport { findByPropsLazy, waitFor } from \"../webpack\";\nimport type * as t from \"./types/menu\";\n\nexport let Menu = {} as t.Menu;\n\nwaitFor([\"MenuItem\", \"MenuSliderControl\"], m => Menu = m);\n\nexport const ContextMenuApi: t.ContextMenuApi = findByPropsLazy(\"closeContextMenu\", \"openContextMenu\");\n\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\n// eslint-disable-next-line path-alias/no-relative\nimport { findByPropsLazy, waitFor } from \"../webpack\";\n\nexport let React: typeof import(\"react\");\nexport let useState: typeof React.useState;\nexport let useEffect: typeof React.useEffect;\nexport let useMemo: typeof React.useMemo;\nexport let useRef: typeof React.useRef;\nexport let useReducer: typeof React.useReducer;\nexport let useCallback: typeof React.useCallback;\n\nexport const ReactDOM: typeof import(\"react-dom\") & typeof import(\"react-dom/client\") = findByPropsLazy(\"createPortal\", \"render\");\n\nwaitFor(\"useState\", m => {\n React = m;\n ({ useEffect, useState, useMemo, useRef, useReducer, useCallback } = React);\n});\n", "/*\n * Vencord, a Discord client mod\n * Copyright (c) 2023 Vendicated and contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport { findByPropsLazy } from \"@webpack\";\n\nexport const TextAndImagesSettingsStores = findByPropsLazy(\"MessageDisplayCompact\");\nexport const StatusSettingsStores = findByPropsLazy(\"ShowCurrentGame\");\n\nexport const UserSettingsActionCreators = findByPropsLazy(\"PreloadedUserSettingsActionCreators\");\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport type * as Stores from \"discord-types/stores\";\n\n// eslint-disable-next-line path-alias/no-relative\nimport { findByPropsLazy } from \"../webpack\";\nimport { waitForStore } from \"./internal\";\nimport * as t from \"./types/stores\";\n\nexport const Flux: t.Flux = findByPropsLazy(\"connectStores\");\n\nexport type GenericStore = t.FluxStore & Record<string, any>;\n\nexport enum DraftType {\n ChannelMessage = 0,\n ThreadSettings = 1,\n FirstThreadMessage = 2,\n ApplicationLauncherCommand = 3\n}\n\nexport let MessageStore: Omit<Stores.MessageStore, \"getMessages\"> & {\n getMessages(chanId: string): any;\n};\n\n// this is not actually a FluxStore\nexport const PrivateChannelsStore = findByPropsLazy(\"openPrivateChannel\");\nexport let PermissionStore: GenericStore;\nexport let GuildChannelStore: GenericStore;\nexport let ReadStateStore: GenericStore;\nexport let PresenceStore: GenericStore;\nexport let PoggerModeSettingsStore: GenericStore;\n\nexport let GuildStore: Stores.GuildStore & t.FluxStore;\nexport let UserStore: Stores.UserStore & t.FluxStore;\nexport let UserProfileStore: GenericStore;\nexport let SelectedChannelStore: Stores.SelectedChannelStore & t.FluxStore;\nexport let SelectedGuildStore: t.FluxStore & Record<string, any>;\nexport let ChannelStore: Stores.ChannelStore & t.FluxStore;\nexport let GuildMemberStore: Stores.GuildMemberStore & t.FluxStore;\nexport let RelationshipStore: Stores.RelationshipStore & t.FluxStore & {\n /** Get the date (as a string) that the relationship was created */\n getSince(userId: string): string;\n};\n\nexport let EmojiStore: t.EmojiStore;\nexport let WindowStore: t.WindowStore;\nexport let DraftStore: t.DraftStore;\n\n/**\n * React hook that returns stateful data for one or more stores\n * You might need a custom comparator (4th argument) if your store data is an object\n *\n * @param stores The stores to listen to\n * @param mapper A function that returns the data you need\n * @param idk some thing, idk just pass null\n * @param isEqual A custom comparator for the data returned by mapper\n *\n * @example const user = useStateFromStores([UserStore], () => UserStore.getCurrentUser(), null, (old, current) => old.id === current.id);\n */\nexport const { useStateFromStores }: {\n useStateFromStores: <T>(\n stores: t.FluxStore[],\n mapper: () => T,\n idk?: any,\n isEqual?: (old: T, newer: T) => boolean\n ) => T;\n}\n = findByPropsLazy(\"useStateFromStores\");\n\nwaitForStore(\"DraftStore\", s => DraftStore = s);\nwaitForStore(\"UserStore\", s => UserStore = s);\nwaitForStore(\"UserProfileStore\", m => UserProfileStore = m);\nwaitForStore(\"ChannelStore\", m => ChannelStore = m);\nwaitForStore(\"SelectedChannelStore\", m => SelectedChannelStore = m);\nwaitForStore(\"SelectedGuildStore\", m => SelectedGuildStore = m);\nwaitForStore(\"GuildStore\", m => GuildStore = m);\nwaitForStore(\"GuildMemberStore\", m => GuildMemberStore = m);\nwaitForStore(\"RelationshipStore\", m => RelationshipStore = m);\nwaitForStore(\"PermissionStore\", m => PermissionStore = m);\nwaitForStore(\"PresenceStore\", m => PresenceStore = m);\nwaitForStore(\"ReadStateStore\", m => ReadStateStore = m);\nwaitForStore(\"GuildChannelStore\", m => GuildChannelStore = m);\nwaitForStore(\"MessageStore\", m => MessageStore = m);\nwaitForStore(\"WindowStore\", m => WindowStore = m);\nwaitForStore(\"EmojiStore\", m => EmojiStore = m);\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport type { Moment } from \"moment\";\nimport type { ComponentType, CSSProperties, FunctionComponent, HtmlHTMLAttributes, HTMLProps, KeyboardEvent, MouseEvent, PropsWithChildren, PropsWithRef, ReactNode, Ref } from \"react\";\n\nexport type TextVariant = \"heading-sm/normal\" | \"heading-sm/medium\" | \"heading-sm/semibold\" | \"heading-sm/bold\" | \"heading-md/normal\" | \"heading-md/medium\" | \"heading-md/semibold\" | \"heading-md/bold\" | \"heading-lg/normal\" | \"heading-lg/medium\" | \"heading-lg/semibold\" | \"heading-lg/bold\" | \"heading-xl/normal\" | \"heading-xl/medium\" | \"heading-xl/bold\" | \"heading-xxl/normal\" | \"heading-xxl/medium\" | \"heading-xxl/bold\" | \"eyebrow\" | \"heading-deprecated-14/normal\" | \"heading-deprecated-14/medium\" | \"heading-deprecated-14/bold\" | \"text-xxs/normal\" | \"text-xxs/medium\" | \"text-xxs/semibold\" | \"text-xxs/bold\" | \"text-xs/normal\" | \"text-xs/medium\" | \"text-xs/semibold\" | \"text-xs/bold\" | \"text-sm/normal\" | \"text-sm/medium\" | \"text-sm/semibold\" | \"text-sm/bold\" | \"text-md/normal\" | \"text-md/medium\" | \"text-md/semibold\" | \"text-md/bold\" | \"text-lg/normal\" | \"text-lg/medium\" | \"text-lg/semibold\" | \"text-lg/bold\" | \"display-sm\" | \"display-md\" | \"display-lg\" | \"code\";\nexport type FormTextTypes = Record<\"DEFAULT\" | \"INPUT_PLACEHOLDER\" | \"DESCRIPTION\" | \"LABEL_BOLD\" | \"LABEL_SELECTED\" | \"LABEL_DESCRIPTOR\" | \"ERROR\" | \"SUCCESS\", string>;\nexport type Heading = `h${1 | 2 | 3 | 4 | 5 | 6}`;\n\nexport type Margins = Record<\"marginTop16\" | \"marginTop8\" | \"marginBottom8\" | \"marginTop20\" | \"marginBottom20\", string>;\nexport type ButtonLooks = Record<\"FILLED\" | \"INVERTED\" | \"OUTLINED\" | \"LINK\" | \"BLANK\", string>;\n\nexport type TextProps = PropsWithChildren<HtmlHTMLAttributes<HTMLDivElement> & {\n variant?: TextVariant;\n tag?: \"div\" | \"span\" | \"p\" | \"strong\" | Heading;\n selectable?: boolean;\n lineClamp?: number;\n}>;\n\nexport type Text = ComponentType<TextProps>;\n\nexport type FormTitle = ComponentType<HTMLProps<HTMLTitleElement> & PropsWithChildren<{\n /** default is h5 */\n tag?: Heading;\n faded?: boolean;\n disabled?: boolean;\n required?: boolean;\n error?: ReactNode;\n}>>;\n\nexport type FormSection = ComponentType<PropsWithChildren<{\n /** default is h5 */\n tag?: Heading;\n className?: string;\n titleClassName?: string;\n titleId?: string;\n title?: ReactNode;\n disabled?: boolean;\n htmlFor?: unknown;\n}>>;\n\nexport type FormDivider = ComponentType<{\n className?: string;\n style?: CSSProperties;\n}>;\n\n\nexport type FormText = ComponentType<PropsWithChildren<{\n disabled?: boolean;\n selectable?: boolean;\n /** defaults to FormText.Types.DEFAULT */\n type?: string;\n}> & TextProps> & { Types: FormTextTypes; };\n\nexport type Tooltip = ComponentType<{\n text: ReactNode;\n children: FunctionComponent<{\n onClick(): void;\n onMouseEnter(): void;\n onMouseLeave(): void;\n onContextMenu(): void;\n onFocus(): void;\n onBlur(): void;\n \"aria-label\"?: string;\n }>;\n \"aria-label\"?: string;\n\n allowOverflow?: boolean;\n forceOpen?: boolean;\n hide?: boolean;\n hideOnClick?: boolean;\n shouldShow?: boolean;\n spacing?: number;\n\n /** Tooltip.Colors.BLACK */\n color?: string;\n /** TooltipPositions.TOP */\n position?: string;\n\n tooltipClassName?: string;\n tooltipContentClassName?: string;\n}> & {\n Colors: Record<\"BLACK\" | \"BRAND\" | \"CUSTOM\" | \"GREEN\" | \"GREY\" | \"PRIMARY\" | \"RED\" | \"YELLOW\", string>;\n};\n\nexport type TooltipPositions = Record<\"BOTTOM\" | \"CENTER\" | \"LEFT\" | \"RIGHT\" | \"TOP\" | \"WINDOW_CENTER\", string>;\n\nexport type Card = ComponentType<PropsWithChildren<HTMLProps<HTMLDivElement> & {\n editable?: boolean;\n outline?: boolean;\n /** Card.Types.PRIMARY */\n type?: string;\n}>> & {\n Types: Record<\"BRAND\" | \"CUSTOM\" | \"DANGER\" | \"PRIMARY\" | \"SUCCESS\" | \"WARNING\", string>;\n};\n\nexport type Button = ComponentType<PropsWithChildren<Omit<HTMLProps<HTMLButtonElement>, \"size\"> & {\n /** Button.Looks.FILLED */\n look?: string;\n /** Button.Colors.BRAND */\n color?: string;\n /** Button.Sizes.MEDIUM */\n size?: string;\n /** Button.BorderColors.BLACK */\n borderColor?: string;\n\n wrapperClassName?: string;\n className?: string;\n innerClassName?: string;\n\n buttonRef?: Ref<HTMLButtonElement>;\n focusProps?: any;\n submitting?: boolean;\n\n submittingStartedLabel?: string;\n submittingFinishedLabel?: string;\n}>> & {\n BorderColors: Record<\"BLACK\" | \"BRAND\" | \"BRAND_NEW\" | \"GREEN\" | \"LINK\" | \"PRIMARY\" | \"RED\" | \"TRANSPARENT\" | \"WHITE\" | \"YELLOW\", string>;\n Colors: Record<\"BRAND\" | \"RED\" | \"GREEN\" | \"YELLOW\" | \"PRIMARY\" | \"LINK\" | \"WHITE\" | \"BLACK\" | \"TRANSPARENT\" | \"BRAND_NEW\" | \"CUSTOM\", string>;\n Hovers: Record<\"DEFAULT\" | \"BRAND\" | \"RED\" | \"GREEN\" | \"YELLOW\" | \"PRIMARY\" | \"LINK\" | \"WHITE\" | \"BLACK\" | \"TRANSPARENT\", string>;\n Looks: Record<\"FILLED\" | \"INVERTED\" | \"OUTLINED\" | \"LINK\" | \"BLANK\", string>;\n Sizes: Record<\"NONE\" | \"TINY\" | \"SMALL\" | \"MEDIUM\" | \"LARGE\" | \"XLARGE\" | \"MIN\" | \"MAX\" | \"ICON\", string>;\n\n Link: any;\n};\n\nexport type Switch = ComponentType<PropsWithChildren<{\n value: boolean;\n onChange(value: boolean): void;\n\n disabled?: boolean;\n hideBorder?: boolean;\n className?: string;\n style?: CSSProperties;\n\n note?: ReactNode;\n tooltipNote?: ReactNode;\n}>>;\n\nexport type Timestamp = ComponentType<PropsWithChildren<{\n timestamp: Moment;\n isEdited?: boolean;\n\n className?: string;\n id?: string;\n\n cozyAlt?: boolean;\n compact?: boolean;\n isInline?: boolean;\n isVisibleOnlyOnHover?: boolean;\n}>>;\n\nexport type TextInput = ComponentType<PropsWithChildren<{\n name?: string;\n onChange?(value: string, name?: string): void;\n placeholder?: string;\n editable?: boolean;\n maxLength?: number;\n error?: string;\n\n inputClassName?: string;\n inputPrefix?: string;\n inputRef?: Ref<HTMLInputElement>;\n prefixElement?: ReactNode;\n\n focusProps?: any;\n\n /** TextInput.Sizes.DEFAULT */\n size?: string;\n} & Omit<HTMLProps<HTMLInputElement>, \"onChange\">>> & {\n Sizes: Record<\"DEFAULT\" | \"MINI\", string>;\n};\n\nexport type TextArea = ComponentType<PropsWithRef<Omit<HTMLProps<HTMLTextAreaElement>, \"onChange\"> & {\n onChange(v: string): void;\n}>>;\n\ninterface SelectOption {\n disabled?: boolean;\n value: any;\n label: string;\n key?: React.Key;\n default?: boolean;\n}\n\nexport type Select = ComponentType<PropsWithChildren<{\n placeholder?: string;\n options: ReadonlyArray<SelectOption>; // TODO\n\n /**\n * - 0 ~ Filled\n * - 1 ~ Custom\n */\n look?: 0 | 1;\n className?: string;\n popoutClassName?: string;\n popoutPosition?: \"top\" | \"left\" | \"right\" | \"bottom\" | \"center\" | \"window_center\";\n optionClassName?: string;\n\n autoFocus?: boolean;\n isDisabled?: boolean;\n clearable?: boolean;\n closeOnSelect?: boolean;\n hideIcon?: boolean;\n\n select(value: any): void;\n isSelected(value: any): boolean;\n serialize(value: any): string;\n clear?(): void;\n\n maxVisibleItems?: number;\n popoutWidth?: number;\n\n onClose?(): void;\n onOpen?(): void;\n\n renderOptionLabel?(option: SelectOption): ReactNode;\n /** discord stupid this gets all options instead of one yeah */\n renderOptionValue?(option: SelectOption[]): ReactNode;\n\n \"aria-label\"?: boolean;\n \"aria-labelledby\"?: boolean;\n}>>;\n\nexport type SearchableSelect = ComponentType<PropsWithChildren<{\n placeholder?: string;\n options: ReadonlyArray<SelectOption>; // TODO\n value?: SelectOption;\n\n /**\n * - 0 ~ Filled\n * - 1 ~ Custom\n */\n look?: 0 | 1;\n className?: string;\n popoutClassName?: string;\n wrapperClassName?: string;\n popoutPosition?: \"top\" | \"left\" | \"right\" | \"bottom\" | \"center\" | \"window_center\";\n optionClassName?: string;\n\n autoFocus?: boolean;\n isDisabled?: boolean;\n clearable?: boolean;\n closeOnSelect?: boolean;\n clearOnSelect?: boolean;\n multi?: boolean;\n\n onChange(value: any): void;\n onSearchChange?(value: string): void;\n\n onClose?(): void;\n onOpen?(): void;\n onBlur?(): void;\n\n renderOptionPrefix?(option: SelectOption): ReactNode;\n renderOptionSuffix?(option: SelectOption): ReactNode;\n\n filter?(option: SelectOption[], query: string): SelectOption[];\n\n centerCaret?: boolean;\n debounceTime?: number;\n maxVisibleItems?: number;\n popoutWidth?: number;\n\n \"aria-labelledby\"?: boolean;\n}>>;\n\nexport type Slider = ComponentType<PropsWithChildren<{\n initialValue: number;\n defaultValue?: number;\n keyboardStep?: number;\n maxValue?: number;\n minValue?: number;\n markers?: number[];\n stickToMarkers?: boolean;\n\n /** 0 above, 1 below */\n markerPosition?: 0 | 1;\n orientation?: \"horizontal\" | \"vertical\";\n\n getAriaValueText?(currentValue: number): string;\n renderMarker?(marker: number): ReactNode;\n onMarkerRender?(marker: number): ReactNode;\n onValueRender?(value: number): ReactNode;\n onValueChange?(value: number): void;\n asValueChanges?(value: number): void;\n\n className?: string;\n disabled?: boolean;\n handleSize?: number;\n mini?: boolean;\n hideBubble?: boolean;\n\n fillStyles?: CSSProperties;\n barStyles?: CSSProperties;\n grabberStyles?: CSSProperties;\n grabberClassName?: string;\n barClassName?: string;\n\n \"aria-hidden\"?: boolean;\n \"aria-label\"?: string;\n \"aria-labelledby\"?: string;\n \"aria-describedby\"?: string;\n}>>;\n\n// TODO - type maybe idk probably not that useful other than the constants\nexport type Flex = ComponentType<PropsWithChildren<any>> & {\n Align: Record<\"START\" | \"END\" | \"CENTER\" | \"STRETCH\" | \"BASELINE\", string>;\n Direction: Record<\"VERTICAL\" | \"HORIZONTAL\" | \"HORIZONTAL_REVERSE\", string>;\n Justify: Record<\"START\" | \"END\" | \"CENTER\" | \"BETWEEN\" | \"AROUND\", string>;\n Wrap: Record<\"NO_WRAP\" | \"WRAP\" | \"WRAP_REVERSE\", string>;\n};\n\ndeclare enum PopoutAnimation {\n NONE = \"1\",\n TRANSLATE = \"2\",\n SCALE = \"3\",\n FADE = \"4\"\n}\n\nexport type Popout = ComponentType<{\n children(\n thing: {\n \"aria-controls\": string;\n \"aria-expanded\": boolean;\n onClick(event: MouseEvent<HTMLElement>): void;\n onKeyDown(event: KeyboardEvent<HTMLElement>): void;\n onMouseDown(event: MouseEvent<HTMLElement>): void;\n },\n data: {\n isShown: boolean;\n position: string;\n }\n ): ReactNode;\n shouldShow?: boolean;\n renderPopout(args: {\n closePopout(): void;\n isPositioned: boolean;\n nudge: number;\n position: string;\n setPopoutRef(ref: any): void;\n updatePosition(): void;\n }): ReactNode;\n\n onRequestOpen?(): void;\n onRequestClose?(): void;\n\n /** \"center\" and others */\n align?: string;\n /** Popout.Animation */\n animation?: PopoutAnimation;\n autoInvert?: boolean;\n nudgeAlignIntoViewport?: boolean;\n /** \"bottom\" and others */\n position?: string;\n positionKey?: string;\n spacing?: number;\n}> & {\n Animation: typeof PopoutAnimation;\n};\n\nexport type Dialog = ComponentType<PropsWithChildren<any>>;\n\ntype Resolve = (data: { theme: \"light\" | \"dark\", saturation: number; }) => {\n hex(): string;\n hsl(): string;\n int(): number;\n spring(): string;\n};\n\nexport type useToken = (color: {\n css: string;\n resolve: Resolve;\n}) => ReturnType<Resolve>;\n\nexport type Paginator = ComponentType<{\n currentPage: number;\n maxVisiblePages: number;\n pageSize: number;\n totalCount: number;\n\n onPageChange?(page: number): void;\n hideMaxPage?: boolean;\n}>;\n\nexport type MaskedLink = ComponentType<PropsWithChildren<{\n href: string;\n rel?: string;\n target?: string;\n title?: string,\n className?: string;\n tabIndex?: number;\n onClick?(): void;\n trusted?: boolean;\n messageId?: string;\n channelId?: string;\n}>>;\n\nexport type ScrollerThin = ComponentType<PropsWithChildren<{\n className?: string;\n style?: CSSProperties;\n\n dir?: \"ltr\";\n orientation?: \"horizontal\" | \"vertical\";\n paddingFix?: boolean;\n fade?: boolean;\n\n onClose?(): void;\n onScroll?(): void;\n}>>;\n\nexport type Clickable = ComponentType<PropsWithChildren<{\n className?: string;\n\n href?: string;\n ignoreKeyPress?: boolean;\n\n onClick?(): void;\n onKeyPress?(): void;\n}>>;\n\nexport type Avatar = ComponentType<PropsWithChildren<{\n className?: string;\n\n src?: string;\n size?: \"SIZE_16\" | \"SIZE_20\" | \"SIZE_24\" | \"SIZE_32\" | \"SIZE_40\" | \"SIZE_48\" | \"SIZE_56\" | \"SIZE_80\" | \"SIZE_120\";\n\n statusColor?: string;\n statusTooltip?: string;\n statusBackdropColor?: string;\n\n isMobile?: boolean;\n isTyping?: boolean;\n isSpeaking?: boolean;\n\n typingIndicatorRef?: unknown;\n\n \"aria-hidden\"?: boolean;\n \"aria-label\"?: string;\n}>>;\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport type { ComponentType, CSSProperties, MouseEvent, PropsWithChildren, ReactNode, UIEvent } from \"react\";\n\ntype RC<C> = ComponentType<PropsWithChildren<C & Record<string, any>>>;\n\nexport interface Menu {\n Menu: RC<{\n navId: string;\n onClose(): void;\n className?: string;\n style?: CSSProperties;\n hideScroller?: boolean;\n onSelect?(): void;\n }>;\n MenuSeparator: ComponentType;\n MenuGroup: RC<{\n label?: string;\n }>;\n MenuItem: RC<{\n id: string;\n label: ReactNode;\n action?(e: MouseEvent): void;\n icon?: ComponentType<any>;\n\n color?: string;\n render?: ComponentType<any>;\n onChildrenScroll?: Function;\n childRowHeight?: number;\n listClassName?: string;\n disabled?: boolean;\n }>;\n MenuCheckboxItem: RC<{\n id: string;\n label: string;\n checked: boolean;\n action?(e: MouseEvent): void;\n disabled?: boolean;\n }>;\n MenuRadioItem: RC<{\n id: string;\n group: string;\n label: string;\n checked: boolean;\n action?(e: MouseEvent): void;\n disabled?: boolean;\n }>;\n MenuControlItem: RC<{\n id: string;\n interactive?: boolean;\n }>;\n MenuSliderControl: RC<{\n minValue: number,\n maxValue: number,\n value: number,\n onChange(value: number): void,\n renderValue?(value: number): string,\n }>;\n}\n\nexport interface ContextMenuApi {\n closeContextMenu(): void;\n openContextMenu(\n event: UIEvent,\n render?: Menu[\"Menu\"],\n options?: { enableSpellCheck?: boolean; },\n renderLazy?: () => Promise<Menu[\"Menu\"]>\n ): void;\n openContextMenuLazy(\n event: UIEvent,\n renderLazy?: () => Promise<Menu[\"Menu\"]>,\n options?: { enableSpellCheck?: boolean; }\n ): void;\n}\n\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport type { ReactNode } from \"react\";\n\nimport type { FluxEvents } from \"./fluxEvents\";\nimport { i18nMessages } from \"./i18nMessages\";\n\nexport { FluxEvents };\n\nexport interface FluxDispatcher {\n _actionHandlers: any;\n _subscriptions: any;\n dispatch(event: { [key: string]: unknown; type: FluxEvents; }): Promise<void>;\n isDispatching(): boolean;\n subscribe(event: FluxEvents, callback: (data: any) => void): void;\n unsubscribe(event: FluxEvents, callback: (data: any) => void): void;\n wait(callback: () => void): void;\n}\n\nexport type Parser = Record<\n | \"parse\"\n | \"parseTopic\"\n | \"parseEmbedTitle\"\n | \"parseInlineReply\"\n | \"parseGuildVerificationFormRule\"\n | \"parseGuildEventDescription\"\n | \"parseAutoModerationSystemMessage\"\n | \"parseForumPostGuidelines\"\n | \"parseForumPostMostRecentMessage\",\n (content: string, inline?: boolean, state?: Record<string, any>) => ReactNode[]\n> & Record<\"defaultRules\" | \"guildEventRules\", Record<string, Record<\"react\" | \"html\" | \"parse\" | \"match\" | \"order\", any>>>;\n\nexport interface Alerts {\n show(alert: {\n title: any;\n body: React.ReactNode;\n className?: string;\n confirmColor?: string;\n cancelText?: string;\n confirmText?: string;\n secondaryConfirmText?: string;\n onCancel?(): void;\n onConfirm?(): void;\n onConfirmSecondary?(): void;\n }): void;\n /** This is a noop, it does nothing. */\n close(): void;\n}\n\nexport interface SnowflakeUtils {\n fromTimestamp(timestamp: number): string;\n extractTimestamp(snowflake: string): number;\n age(snowflake: string): number;\n atPreviousMillisecond(snowflake: string): string;\n compare(snowflake1?: string, snowflake2?: string): number;\n}\n\ninterface RestRequestData {\n url: string;\n query?: Record<string, any>;\n body?: Record<string, any>;\n oldFormErrors?: boolean;\n retries?: number;\n}\n\nexport type RestAPI = Record<\"delete\" | \"get\" | \"patch\" | \"post\" | \"put\", (data: RestRequestData) => Promise<any>> & {\n V6OrEarlierAPIError: Error;\n V8APIError: Error;\n getAPIBaseURL(withVersion?: boolean): string;\n};\n\nexport type Permissions = \"CREATE_INSTANT_INVITE\"\n | \"KICK_MEMBERS\"\n | \"BAN_MEMBERS\"\n | \"ADMINISTRATOR\"\n | \"MANAGE_CHANNELS\"\n | \"MANAGE_GUILD\"\n | \"CHANGE_NICKNAME\"\n | \"MANAGE_NICKNAMES\"\n | \"MANAGE_ROLES\"\n | \"MANAGE_WEBHOOKS\"\n | \"MANAGE_GUILD_EXPRESSIONS\"\n | \"CREATE_GUILD_EXPRESSIONS\"\n | \"VIEW_AUDIT_LOG\"\n | \"VIEW_CHANNEL\"\n | \"VIEW_GUILD_ANALYTICS\"\n | \"VIEW_CREATOR_MONETIZATION_ANALYTICS\"\n | \"MODERATE_MEMBERS\"\n | \"SEND_MESSAGES\"\n | \"SEND_TTS_MESSAGES\"\n | \"MANAGE_MESSAGES\"\n | \"EMBED_LINKS\"\n | \"ATTACH_FILES\"\n | \"READ_MESSAGE_HISTORY\"\n | \"MENTION_EVERYONE\"\n | \"USE_EXTERNAL_EMOJIS\"\n | \"ADD_REACTIONS\"\n | \"USE_APPLICATION_COMMANDS\"\n | \"MANAGE_THREADS\"\n | \"CREATE_PUBLIC_THREADS\"\n | \"CREATE_PRIVATE_THREADS\"\n | \"USE_EXTERNAL_STICKERS\"\n | \"SEND_MESSAGES_IN_THREADS\"\n | \"SEND_VOICE_MESSAGES\"\n | \"CONNECT\"\n | \"SPEAK\"\n | \"MUTE_MEMBERS\"\n | \"DEAFEN_MEMBERS\"\n | \"MOVE_MEMBERS\"\n | \"USE_VAD\"\n | \"PRIORITY_SPEAKER\"\n | \"STREAM\"\n | \"USE_EMBEDDED_ACTIVITIES\"\n | \"USE_SOUNDBOARD\"\n | \"USE_EXTERNAL_SOUNDS\"\n | \"REQUEST_TO_SPEAK\"\n | \"MANAGE_EVENTS\"\n | \"CREATE_EVENTS\";\n\nexport type PermissionsBits = Record<Permissions, bigint>;\n\nexport interface Locale {\n name: string;\n value: string;\n localizedName: string;\n}\n\nexport interface LocaleInfo {\n code: string;\n enabled: boolean;\n name: string;\n englishName: string;\n postgresLang: string;\n}\n\nexport interface i18n {\n getAvailableLocales(): Locale[];\n getLanguages(): LocaleInfo[];\n getDefaultLocale(): string;\n getLocale(): string;\n getLocaleInfo(): LocaleInfo;\n setLocale(locale: string): void;\n\n loadPromise: Promise<void>;\n\n Messages: Record<i18nMessages, any>;\n}\n\nexport interface Clipboard {\n copy(text: string): void;\n SUPPORTS_COPY: boolean;\n}\n\nexport interface NavigationRouter {\n back(): void;\n forward(): void;\n hasNavigated(): boolean;\n getHistory(): {\n action: string;\n length: 50;\n [key: string]: any;\n };\n transitionTo(path: string, ...args: unknown[]): void;\n transitionToGuild(guildId: string, ...args: unknown[]): void;\n replaceWith(...args: unknown[]): void;\n getLastRouteChangeSource(): any;\n getLastRouteChangeSourceLocationStack(): any;\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport type { Channel, User } from \"discord-types/general\";\n\n// eslint-disable-next-line path-alias/no-relative\nimport { _resolveReady, filters, findByCodeLazy, findByPropsLazy, findLazy, waitFor } from \"../webpack\";\nimport type * as t from \"./types/utils\";\n\nexport let FluxDispatcher: t.FluxDispatcher;\n\nwaitFor([\"dispatch\", \"subscribe\"], m => {\n FluxDispatcher = m;\n const cb = () => {\n m.unsubscribe(\"CONNECTION_OPEN\", cb);\n _resolveReady();\n };\n m.subscribe(\"CONNECTION_OPEN\", cb);\n});\n\nexport let ComponentDispatch;\nwaitFor([\"ComponentDispatch\", \"ComponentDispatcher\"], m => ComponentDispatch = m.ComponentDispatch);\n\n\nexport const RestAPI: t.RestAPI = findByPropsLazy(\"getAPIBaseURL\", \"get\");\nexport const moment: typeof import(\"moment\") = findByPropsLazy(\"parseTwoDigitYear\");\n\nexport const hljs: typeof import(\"highlight.js\") = findByPropsLazy(\"highlight\", \"registerLanguage\");\n\nexport const lodash: typeof import(\"lodash\") = findByPropsLazy(\"debounce\", \"cloneDeep\");\n\nexport const i18n: t.i18n = findLazy(m => m.Messages?.[\"en-US\"]);\n\nexport let SnowflakeUtils: t.SnowflakeUtils;\nwaitFor([\"fromTimestamp\", \"extractTimestamp\"], m => SnowflakeUtils = m);\n\nexport let Parser: t.Parser;\nwaitFor(\"parseTopic\", m => Parser = m);\nexport let Alerts: t.Alerts;\nwaitFor([\"show\", \"close\"], m => Alerts = m);\n\nconst ToastType = {\n MESSAGE: 0,\n SUCCESS: 1,\n FAILURE: 2,\n CUSTOM: 3\n};\nconst ToastPosition = {\n TOP: 0,\n BOTTOM: 1\n};\n\nexport const Toasts = {\n Type: ToastType,\n Position: ToastPosition,\n // what's less likely than getting 0 from Math.random()? Getting it twice in a row\n genId: () => (Math.random() || Math.random()).toString(36).slice(2),\n\n // hack to merge with the following interface, dunno if there's a better way\n ...{} as {\n show(data: {\n message: string,\n id: string,\n /**\n * Toasts.Type\n */\n type: number,\n options?: {\n /**\n * Toasts.Position\n */\n position?: number;\n component?: React.ReactNode,\n duration?: number;\n };\n }): void;\n pop(): void;\n }\n};\n\n// This is the same module but this is easier\nwaitFor(\"showToast\", m => {\n Toasts.show = m.showToast;\n Toasts.pop = m.popToast;\n});\n\n\n/**\n * Show a simple toast. If you need more options, use Toasts.show manually\n */\nexport function showToast(message: string, type = ToastType.MESSAGE) {\n Toasts.show({\n id: Toasts.genId(),\n message,\n type\n });\n}\n\nexport const UserUtils = findByPropsLazy(\"getUser\", \"fetchCurrentUser\") as { getUser: (id: string) => Promise<User>; };\nexport const UploadHandler = findByPropsLazy(\"showUploadFileSizeExceededError\", \"promptToUpload\") as {\n promptToUpload: (files: File[], channel: Channel, draftType: Number) => void;\n};\n\nexport const ApplicationAssetUtils = findByPropsLazy(\"fetchAssetIds\", \"getAssetImage\") as {\n fetchAssetIds: (applicationId: string, e: string[]) => Promise<string[]>;\n};\n\nexport const Clipboard: t.Clipboard = findByPropsLazy(\"SUPPORTS_COPY\", \"copy\");\n\nexport const NavigationRouter: t.NavigationRouter = findByPropsLazy(\"transitionTo\", \"replaceWith\", \"transitionToGuild\");\n\nexport let SettingsRouter: any;\nwaitFor([\"open\", \"saveAccountChanges\"], m => SettingsRouter = m);\n\nexport const { Permissions: PermissionsBits } = findLazy(m => typeof m.Permissions?.ADMINISTRATOR === \"bigint\") as { Permissions: t.PermissionsBits; };\n\nexport const zustandCreate: typeof import(\"zustand\").default = findByCodeLazy(\"will be removed in v4\");\n\nconst persistFilter = filters.byCode(\"[zustand persist middleware]\");\nexport const { persist: zustandPersist }: typeof import(\"zustand/middleware\") = findLazy(m => m.persist && persistFilter(m.persist));\n\nexport const MessageActions = findByPropsLazy(\"editMessage\", \"sendMessage\");\nexport const UserProfileActions = findByPropsLazy(\"openUserProfileModal\", \"closeUserProfileModal\");\nexport const InviteActions = findByPropsLazy(\"resolveInvite\");\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nexport * from \"./classes\";\nexport * from \"./components\";\nexport * from \"./menu\";\nexport * from \"./react\";\nexport * from \"./settingsStores\";\nexport * from \"./stores\";\nexport * as ComponentTypes from \"./types/components.d\";\nexport * as MenuTypes from \"./types/menu.d\";\nexport * as UtilTypes from \"./types/utils.d\";\nexport * from \"./utils\";\n", "export default \"d73790e\"", "export default \"Vendicated/Vencord\"", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport gitHash from \"~git-hash\";\nimport gitRemote from \"~git-remote\";\n\nexport {\n gitHash,\n gitRemote\n};\n\nexport const WEBPACK_CHUNK = \"webpackChunkdiscord_app\";\nexport const REACT_GLOBAL = \"Vencord.Webpack.Common.React\";\nexport const VENCORD_USER_AGENT = `Vencord/${gitHash}${gitRemote ? ` (https://github.com/${gitRemote})` : \"\"}`;\nexport const SUPPORT_CHANNEL_ID = \"1026515880080842772\";\n\nexport interface Dev {\n name: string;\n id: bigint;\n badge?: boolean;\n}\n\n/**\n * If you made a plugin or substantial contribution, add yourself here.\n * This object is used for the plugin author list, as well as to add a contributor badge to your profile.\n * If you wish to stay fully anonymous, feel free to set ID to 0n.\n * If you are fine with attribution but don't want the badge, add badge: false\n */\nexport const Devs = /* #__PURE__*/ Object.freeze({\n Ven: {\n name: \"Vendicated\",\n id: 343383572805058560n\n },\n Arjix: {\n name: \"ArjixWasTaken\",\n id: 674710789138939916n\n },\n Cyn: {\n name: \"Cynosphere\",\n id: 150745989836308480n\n },\n Megu: {\n name: \"Megumin\",\n id: 545581357812678656n\n },\n botato: {\n name: \"botato\",\n id: 440990343899643943n\n },\n obscurity: {\n name: \"obscurity\",\n id: 336678828233588736n,\n },\n rushii: {\n name: \"rushii\",\n id: 295190422244950017n\n },\n Glitch: {\n name: \"Glitchy\",\n id: 269567451199569920n\n },\n Samu: {\n name: \"Samu\",\n id: 702973430449832038n,\n },\n Nyako: {\n name: \"nyako\",\n id: 118437263754395652n\n },\n MaiKokain: {\n name: \"Mai\",\n id: 722647978577363026n\n },\n echo: {\n name: \"ECHO\",\n id: 712639419785412668n\n },\n katlyn: {\n name: \"katlyn\",\n id: 250322741406859265n\n },\n nea: {\n name: \"nea\",\n id: 310702108997320705n,\n },\n Nuckyz: {\n name: \"Nuckyz\",\n id: 235834946571337729n\n },\n D3SOX: {\n name: \"D3SOX\",\n id: 201052085641281538n\n },\n Nickyux: {\n name: \"Nickyux\",\n id: 427146305651998721n\n },\n mantikafasi: {\n name: \"mantikafasi\",\n id: 287555395151593473n\n },\n Xinto: {\n name: \"Xinto\",\n id: 423915768191647755n\n },\n JacobTm: {\n name: \"Jacob.Tm\",\n id: 302872992097107991n\n },\n DustyAngel47: {\n name: \"DustyAngel47\",\n id: 714583473804935238n\n },\n BanTheNons: {\n name: \"BanTheNons\",\n id: 460478012794863637n\n },\n BigDuck: {\n name: \"BigDuck\",\n id: 1024588272623681609n\n },\n AverageReactEnjoyer: {\n name: \"Average React Enjoyer\",\n id: 1004904120056029256n\n },\n adryd: {\n name: \"adryd\",\n id: 0n\n },\n Tyman: {\n name: \"Tyman\",\n id: 487443883127472129n\n },\n afn: {\n name: \"afn\",\n id: 420043923822608384n\n },\n KraXen72: {\n name: \"KraXen72\",\n id: 379304073515499530n\n },\n kemo: {\n name: \"kemo\",\n id: 299693897859465228n\n },\n dzshn: {\n name: \"dzshn\",\n id: 310449948011528192n\n },\n Ducko: {\n name: \"Ducko\",\n id: 506482395269169153n\n },\n jewdev: {\n name: \"jewdev\",\n id: 222369866529636353n\n },\n Luna: {\n name: \"Luny\",\n id: 821472922140803112n\n },\n Vap: {\n name: \"Vap0r1ze\",\n id: 454072114492866560n\n },\n KingFish: {\n name: \"King Fish\",\n id: 499400512559382538n\n },\n Commandtechno: {\n name: \"Commandtechno\",\n id: 296776625432035328n,\n },\n TheSun: {\n name: \"ActuallyTheSun\",\n id: 406028027768733696n\n },\n axyie: {\n name: \"'ax\",\n id: 273562710745284628n,\n },\n pointy: {\n name: \"pointy\",\n id: 99914384989519872n\n },\n SammCheese: {\n name: \"Samm-Cheese\",\n id: 372148345894076416n\n },\n zt: {\n name: \"zt\",\n id: 289556910426816513n\n },\n captain: {\n name: \"Captain\",\n id: 347366054806159360n\n },\n nick: {\n name: \"nick\",\n id: 347884694408265729n,\n badge: false\n },\n whqwert: {\n name: \"whqwert\",\n id: 586239091520176128n\n },\n lewisakura: {\n name: \"lewisakura\",\n id: 96269247411400704n\n },\n RuiNtD: {\n name: \"RuiNtD\",\n id: 157917665162297344n\n },\n hunt: {\n name: \"hunt-g\",\n id: 222800179697287168n\n },\n cloudburst: {\n name: \"cloudburst\",\n id: 892128204150685769n\n },\n Aria: {\n name: \"Syncxv\",\n id: 549244932213309442n,\n },\n TheKodeToad: {\n name: \"TheKodeToad\",\n id: 706152404072267788n\n },\n LordElias: {\n name: \"LordElias\",\n id: 319460781567639554n\n },\n juby: {\n name: \"Juby210\",\n id: 324622488644616195n\n },\n Alyxia: {\n name: \"Alyxia Sother\",\n id: 952185386350829688n\n },\n Remty: {\n name: \"Remty\",\n id: 335055032204656642n\n },\n skyevg: {\n name: \"skyevg\",\n id: 1090310844283363348n\n },\n Dziurwa: {\n name: \"Dziurwa\",\n id: 1001086404203389018n\n },\n F53: {\n name: \"F53\",\n id: 280411966126948353n\n },\n AutumnVN: {\n name: \"AutumnVN\",\n id: 393694671383166998n\n },\n pylix: {\n name: \"pylix\",\n id: 492949202121261067n\n },\n Tyler: {\n name: \"\\\\\\\\GGTyler\\\\\\\\\",\n id: 143117463788191746n\n },\n RyanCaoDev: {\n name: \"RyanCaoDev\",\n id: 952235800110694471n,\n },\n Strencher: {\n name: \"Strencher\",\n id: 415849376598982656n\n },\n FieryFlames: {\n name: \"Fiery\",\n id: 890228870559698955n\n },\n KannaDev: {\n name: \"Kanna\",\n id: 317728561106518019n\n },\n carince: {\n name: \"carince\",\n id: 818323528755314698n\n },\n PandaNinjas: {\n name: \"PandaNinjas\",\n id: 455128749071925248n\n },\n CatNoir: {\n name: \"CatNoir\",\n id: 260371016348336128n\n },\n outfoxxed: {\n name: \"outfoxxed\",\n id: 837425748435796060n\n },\n UwUDev: {\n name: \"UwU\",\n id: 691413039156690994n,\n },\n amia: {\n name: \"amia\",\n id: 142007603549962240n\n },\n phil: {\n name: \"phil\",\n id: 305288513941667851n\n },\n ImLvna: {\n name: \"Luna <3\",\n id: 799319081723232267n\n },\n rad: {\n name: \"rad\",\n id: 610945092504780823n\n },\n AndrewDLO: {\n name: \"Andrew-DLO\",\n id: 434135504792059917n\n },\n HypedDomi: {\n name: \"HypedDomi\",\n id: 354191516979429376n\n },\n Rini: {\n name: \"Rini\",\n id: 1079479184478441643n\n },\n castdrian: {\n name: \"castdrian\",\n id: 224617799434108928n\n },\n Arrow: {\n name: \"arrow\",\n id: 958158495302176778n\n },\n bb010g: {\n name: \"bb010g\",\n id: 72791153467990016n,\n },\n Lumap: {\n name: \"lumap\",\n id: 635383782576357407n\n },\n Dolfies: {\n name: \"Dolfies\",\n id: 852892297661906993n,\n },\n RuukuLada: {\n name: \"RuukuLada\",\n id: 119705748346241027n,\n },\n blahajZip: {\n name: \"blahaj.zip\",\n id: 683954422241427471n,\n },\n archeruwu: {\n name: \"archer_uwu\",\n id: 160068695383736320n\n },\n ProffDea: {\n name: \"ProffDea\",\n id: 609329952180928513n\n },\n ant0n: {\n name: \"ant0n\",\n id: 145224646868860928n\n },\n philipbry: {\n name: \"philipbry\",\n id: 554994003318276106n\n },\n Korbo: {\n name: \"Korbo\",\n id: 455856406420258827n\n },\n maisymoe: {\n name: \"maisy\",\n id: 257109471589957632n,\n },\n Grzesiek11: {\n name: \"Grzesiek11\",\n id: 368475654662127616n,\n },\n} satisfies Record<string, Dev>);\n\n// iife so #__PURE__ works correctly\nexport const DevsById = /* #__PURE__*/ (() =>\n Object.freeze(Object.fromEntries(\n Object.entries(Devs)\n .filter(d => d[1].id !== 0n)\n .map(([_, v]) => [v.id, v] as const)\n ))\n)() as Record<string, Dev>;\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Clipboard, Toasts } from \"@webpack/common\";\n\nimport { DevsById } from \"./constants\";\n\n/**\n * Recursively merges defaults into an object and returns the same object\n * @param obj Object\n * @param defaults Defaults\n * @returns obj\n */\nexport function mergeDefaults<T>(obj: T, defaults: T): T {\n for (const key in defaults) {\n const v = defaults[key];\n if (typeof v === \"object\" && !Array.isArray(v)) {\n obj[key] ??= {} as any;\n mergeDefaults(obj[key], v);\n } else {\n obj[key] ??= v;\n }\n }\n return obj;\n}\n\n/**\n * Calls .join(\" \") on the arguments\n * classes(\"one\", \"two\") => \"one two\"\n */\nexport function classes(...classes: Array<string | null | undefined>) {\n return classes.filter(Boolean).join(\" \");\n}\n\n/**\n * Returns a promise that resolves after the specified amount of time\n */\nexport function sleep(ms: number): Promise<void> {\n return new Promise(r => setTimeout(r, ms));\n}\n\nexport function copyWithToast(text: string, toastMessage = \"Copied to clipboard!\") {\n if (Clipboard.SUPPORTS_COPY) {\n Clipboard.copy(text);\n } else {\n toastMessage = \"Your browser does not support copying to clipboard\";\n }\n Toasts.show({\n message: toastMessage,\n id: Toasts.genId(),\n type: Toasts.Type.SUCCESS\n });\n}\n\n/**\n * Check if obj is a true object: of type \"object\" and not null or array\n */\nexport function isObject(obj: unknown): obj is object {\n return typeof obj === \"object\" && obj !== null && !Array.isArray(obj);\n}\n\n/**\n * Check if an object is empty or in other words has no own properties\n */\nexport function isObjectEmpty(obj: object) {\n for (const k in obj)\n if (Object.hasOwn(obj, k)) return false;\n\n return true;\n}\n\n/**\n * Returns null if value is not a URL, otherwise return URL object.\n * Avoids having to wrap url checks in a try/catch\n */\nexport function parseUrl(urlString: string): URL | null {\n try {\n return new URL(urlString);\n } catch {\n return null;\n }\n}\n\n/**\n * Checks whether an element is on screen\n */\nexport const checkIntersecting = (el: Element) => {\n const elementBox = el.getBoundingClientRect();\n const documentHeight = Math.max(document.documentElement.clientHeight, window.innerHeight);\n return !(elementBox.bottom < 0 || elementBox.top - documentHeight >= 0);\n};\n\nexport function identity<T>(value: T): T {\n return value;\n}\n\n// https://developer.mozilla.org/en-US/docs/Web/HTTP/Browser_detection_using_the_user_agent#mobile_tablet_or_desktop\n// \"In summary, we recommend looking for the string Mobi anywhere in the User Agent to detect a mobile device.\"\nexport const isMobile = navigator.userAgent.includes(\"Mobi\");\n\nexport const isPluginDev = (id: string) => Object.hasOwn(DevsById, id);\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { React, useEffect, useMemo, useReducer, useState } from \"@webpack/common\";\n\nimport { checkIntersecting } from \"./misc\";\n\nexport * from \"./lazyReact\";\n\nexport const NoopComponent = () => null;\n\n/**\n * Check if an element is on screen\n * @param intersectOnly If `true`, will only update the state when the element comes into view\n * @returns [refCallback, isIntersecting]\n */\nexport const useIntersection = (intersectOnly = false): [\n refCallback: React.RefCallback<Element>,\n isIntersecting: boolean,\n] => {\n const observerRef = React.useRef<IntersectionObserver | null>(null);\n const [isIntersecting, setIntersecting] = useState(false);\n\n const refCallback = (element: Element | null) => {\n observerRef.current?.disconnect();\n observerRef.current = null;\n\n if (!element) return;\n\n if (checkIntersecting(element)) {\n setIntersecting(true);\n if (intersectOnly) return;\n }\n\n observerRef.current = new IntersectionObserver(entries => {\n for (const entry of entries) {\n if (entry.target !== element) continue;\n if (entry.isIntersecting && intersectOnly) {\n setIntersecting(true);\n observerRef.current?.disconnect();\n observerRef.current = null;\n } else {\n setIntersecting(entry.isIntersecting);\n }\n }\n });\n observerRef.current.observe(element);\n };\n\n return [refCallback, isIntersecting];\n};\n\ntype AwaiterRes<T> = [T, any, boolean];\ninterface AwaiterOpts<T> {\n fallbackValue: T;\n deps?: unknown[];\n onError?(e: any): void;\n onSuccess?(value: T): void;\n}\n/**\n * Await a promise\n * @param factory Factory\n * @param fallbackValue The fallback value that will be used until the promise resolved\n * @returns [value, error, isPending]\n */\nexport function useAwaiter<T>(factory: () => Promise<T>): AwaiterRes<T | null>;\nexport function useAwaiter<T>(factory: () => Promise<T>, providedOpts: AwaiterOpts<T>): AwaiterRes<T>;\nexport function useAwaiter<T>(factory: () => Promise<T>, providedOpts?: AwaiterOpts<T | null>): AwaiterRes<T | null> {\n const opts: Required<AwaiterOpts<T | null>> = Object.assign({\n fallbackValue: null,\n deps: [],\n onError: null,\n }, providedOpts);\n const [state, setState] = useState({\n value: opts.fallbackValue,\n error: null,\n pending: true\n });\n\n useEffect(() => {\n let isAlive = true;\n if (!state.pending) setState({ ...state, pending: true });\n\n factory()\n .then(value => {\n if (!isAlive) return;\n setState({ value, error: null, pending: false });\n opts.onSuccess?.(value);\n })\n .catch(error => {\n if (!isAlive) return;\n setState({ value: null, error, pending: false });\n opts.onError?.(error);\n });\n\n return () => void (isAlive = false);\n }, opts.deps);\n\n return [state.value, state.error, state.pending];\n}\n\n/**\n * Returns a function that can be used to force rerender react components\n */\nexport function useForceUpdater(): () => void;\nexport function useForceUpdater(withDep: true): [unknown, () => void];\nexport function useForceUpdater(withDep?: true) {\n const r = useReducer(x => x + 1, 0);\n return withDep ? r : r[1];\n}\n\ninterface TimerOpts {\n interval?: number;\n deps?: unknown[];\n}\n\nexport function useTimer({ interval = 1000, deps = [] }: TimerOpts) {\n const [time, setTime] = useState(0);\n const start = useMemo(() => Date.now(), deps);\n\n useEffect(() => {\n const intervalId = setInterval(() => setTime(Date.now() - start), interval);\n\n return () => {\n setTime(0);\n clearInterval(intervalId);\n };\n }, deps);\n\n return time;\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport \"./ErrorCard.css\";\n\nimport { classes } from \"@utils/misc\";\nimport type { HTMLProps } from \"react\";\n\nexport function ErrorCard(props: React.PropsWithChildren<HTMLProps<HTMLDivElement>>) {\n return (\n <div {...props} className={classes(props.className, \"vc-error-card\")}>\n {props.children}\n </div>\n );\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Logger } from \"@utils/Logger\";\nimport { Margins } from \"@utils/margins\";\nimport { LazyComponent } from \"@utils/react\";\nimport { React } from \"@webpack/common\";\n\nimport { ErrorCard } from \"./ErrorCard\";\n\ninterface Props<T = any> {\n /** Render nothing if an error occurs */\n noop?: boolean;\n /** Fallback component to render if an error occurs */\n fallback?: React.ComponentType<React.PropsWithChildren<{ error: any; message: string; stack: string; }>>;\n /** called when an error occurs. The props property is only available if using .wrap */\n onError?(data: { error: Error, errorInfo: React.ErrorInfo, props: T; }): void;\n /** Custom error message */\n message?: string;\n\n /** The props passed to the wrapped component. Only used by wrap */\n wrappedProps?: T;\n}\n\nconst color = \"#e78284\";\n\nconst logger = new Logger(\"React ErrorBoundary\", color);\n\nconst NO_ERROR = {};\n\n// We might want to import this in a place where React isn't ready yet.\n// Thus, wrap in a LazyComponent\nconst ErrorBoundary = LazyComponent(() => {\n return class ErrorBoundary extends React.PureComponent<React.PropsWithChildren<Props>> {\n state = {\n error: NO_ERROR as any,\n stack: \"\",\n message: \"\"\n };\n\n static getDerivedStateFromError(error: any) {\n let stack = error?.stack ?? \"\";\n let message = error?.message || String(error);\n\n if (error instanceof Error && stack) {\n const eolIdx = stack.indexOf(\"\\n\");\n if (eolIdx !== -1) {\n message = stack.slice(0, eolIdx);\n stack = stack.slice(eolIdx + 1).replace(/https:\\/\\/\\S+\\/assets\\//g, \"\");\n }\n }\n\n return { error, stack, message };\n }\n\n componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {\n this.props.onError?.({ error, errorInfo, props: this.props.wrappedProps });\n logger.error(\"A component threw an Error\\n\", error);\n logger.error(\"Component Stack\", errorInfo.componentStack);\n }\n\n render() {\n if (this.state.error === NO_ERROR) return this.props.children;\n\n if (this.props.noop) return null;\n\n if (this.props.fallback)\n return <this.props.fallback\n children={this.props.children}\n {...this.state}\n />;\n\n const msg = this.props.message || \"An error occurred while rendering this Component. More info can be found below and in your console.\";\n\n return (\n <ErrorCard style={{ overflow: \"hidden\" }}>\n <h1>Oh no!</h1>\n <p>{msg}</p>\n <code>\n {this.state.message}\n {!!this.state.stack && (\n <pre className={Margins.top8}>\n {this.state.stack}\n </pre>\n )}\n </code>\n </ErrorCard>\n );\n }\n };\n}) as\n React.ComponentType<React.PropsWithChildren<Props>> & {\n wrap<T extends object = any>(Component: React.ComponentType<T>, errorBoundaryProps?: Omit<Props<T>, \"wrappedProps\">): React.FunctionComponent<T>;\n };\n\nErrorBoundary.wrap = (Component, errorBoundaryProps) => props => (\n <ErrorBoundary {...errorBoundaryProps} wrappedProps={props}>\n <Component {...props} />\n </ErrorBoundary>\n);\n\nexport default ErrorBoundary;\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nexport function Heart() {\n return (\n <svg\n aria-hidden=\"true\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n width=\"16\"\n style={{ marginRight: \"0.5em\", transform: \"translateY(2px)\" }}\n >\n <path\n fill=\"#db61a2\"\n fill-rule=\"evenodd\"\n d=\"M4.25 2.5c-1.336 0-2.75 1.164-2.75 3 0 2.15 1.58 4.144 3.365 5.682A20.565 20.565 0 008 13.393a20.561 20.561 0 003.135-2.211C12.92 9.644 14.5 7.65 14.5 5.5c0-1.836-1.414-3-2.75-3-1.373 0-2.609.986-3.029 2.456a.75.75 0 01-1.442 0C6.859 3.486 5.623 2.5 4.25 2.5zM8 14.25l-.345.666-.002-.001-.006-.003-.018-.01a7.643 7.643 0 01-.31-.17 22.075 22.075 0 01-3.434-2.414C2.045 10.731 0 8.35 0 5.5 0 2.836 2.086 1 4.25 1 5.797 1 7.153 1.802 8 3.02 8.847 1.802 10.203 1 11.75 1 13.914 1 16 2.836 16 5.5c0 2.85-2.045 5.231-3.885 6.818a22.08 22.08 0 01-3.744 2.584l-.018.01-.006.003h-.002L8 14.25zm0 0l.345.666a.752.752 0 01-.69 0L8 14.25z\"\n />\n </svg>\n );\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Button } from \"@webpack/common\";\n\nimport { Heart } from \"./Heart\";\n\nexport default function DonateButton(props: any) {\n return (\n <Button\n {...props}\n look={Button.Looks.LINK}\n color={Button.Colors.TRANSPARENT}\n onClick={() => VencordNative.native.openExternal(\"https://github.com/sponsors/Vendicated\")}\n >\n <Heart />\n Donate\n </Button>\n );\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport type { React } from \"@webpack/common\";\n\nexport function Flex(props: React.PropsWithChildren<{\n flexDirection?: React.CSSProperties[\"flexDirection\"];\n style?: React.CSSProperties;\n className?: string;\n} & React.HTMLProps<HTMLDivElement>>) {\n props.style ??= {};\n props.style.display = \"flex\";\n // TODO(ven): Remove me, what was I thinking??\n props.style.gap ??= \"1em\";\n props.style.flexDirection ||= props.flexDirection;\n delete props.flexDirection;\n return (\n <div {...props}>\n {props.children}\n </div>\n );\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { findByPropsLazy, findExportedComponentLazy } from \"@webpack\";\nimport type { ComponentType, PropsWithChildren, ReactNode, Ref } from \"react\";\n\nimport { LazyComponent } from \"./react\";\n\nexport const enum ModalSize {\n SMALL = \"small\",\n MEDIUM = \"medium\",\n LARGE = \"large\",\n DYNAMIC = \"dynamic\",\n}\n\nconst enum ModalTransitionState {\n ENTERING,\n ENTERED,\n EXITING,\n EXITED,\n HIDDEN,\n}\n\nexport interface ModalProps {\n transitionState: ModalTransitionState;\n onClose(): Promise<void>;\n}\n\nexport interface ModalOptions {\n modalKey?: string;\n onCloseRequest?: (() => void);\n onCloseCallback?: (() => void);\n}\n\ntype RenderFunction = (props: ModalProps) => ReactNode;\n\nexport const Modals = findByPropsLazy(\"ModalRoot\", \"ModalCloseButton\") as {\n ModalRoot: ComponentType<PropsWithChildren<{\n transitionState: ModalTransitionState;\n size?: ModalSize;\n role?: \"alertdialog\" | \"dialog\";\n className?: string;\n fullscreenOnMobile?: boolean;\n \"aria-label\"?: string;\n \"aria-labelledby\"?: string;\n onAnimationEnd?(): string;\n }>>;\n ModalHeader: ComponentType<PropsWithChildren<{\n /** Flex.Justify.START */\n justify?: string;\n /** Flex.Direction.HORIZONTAL */\n direction?: string;\n /** Flex.Align.CENTER */\n align?: string;\n /** Flex.Wrap.NO_WRAP */\n wrap?: string;\n separator?: boolean;\n\n className?: string;\n }>>;\n /** This also accepts Scroller props but good luck with that */\n ModalContent: ComponentType<PropsWithChildren<{\n className?: string;\n scrollerRef?: Ref<HTMLElement>;\n [prop: string]: any;\n }>>;\n ModalFooter: ComponentType<PropsWithChildren<{\n /** Flex.Justify.START */\n justify?: string;\n /** Flex.Direction.HORIZONTAL_REVERSE */\n direction?: string;\n /** Flex.Align.STRETCH */\n align?: string;\n /** Flex.Wrap.NO_WRAP */\n wrap?: string;\n separator?: boolean;\n\n className?: string;\n }>>;\n ModalCloseButton: ComponentType<{\n focusProps?: any;\n onClick(): void;\n withCircleBackground?: boolean;\n hideOnFullscreen?: boolean;\n className?: string;\n }>;\n};\n\nexport type ImageModal = ComponentType<{\n className?: string;\n src: string;\n placeholder: string;\n original: string;\n width?: number;\n height?: number;\n animated?: boolean;\n responsive?: boolean;\n renderLinkComponent(props: any): ReactNode;\n maxWidth?: number;\n maxHeight?: number;\n shouldAnimate?: boolean;\n onClose?(): void;\n shouldHideMediaOptions?: boolean;\n}>;\n\nexport const ImageModal = findExportedComponentLazy(\"ImageModal\") as ImageModal;\n\nexport const ModalRoot = LazyComponent(() => Modals.ModalRoot);\nexport const ModalHeader = LazyComponent(() => Modals.ModalHeader);\nexport const ModalContent = LazyComponent(() => Modals.ModalContent);\nexport const ModalFooter = LazyComponent(() => Modals.ModalFooter);\nexport const ModalCloseButton = LazyComponent(() => Modals.ModalCloseButton);\n\nconst ModalAPI = findByPropsLazy(\"openModalLazy\");\n\n/**\n * Wait for the render promise to resolve, then open a modal with it.\n * This is equivalent to render().then(openModal)\n * You should use the Modal components exported by this file\n */\nexport function openModalLazy(render: () => Promise<RenderFunction>, options?: ModalOptions & { contextKey?: string; }): Promise<string> {\n return ModalAPI.openModalLazy(render, options);\n}\n\n/**\n * Open a Modal with the given render function.\n * You should use the Modal components exported by this file\n */\nexport function openModal(render: RenderFunction, options?: ModalOptions, contextKey?: string): string {\n return ModalAPI.openModal(render, options, contextKey);\n}\n\n/**\n * Close a modal by its key\n */\nexport function closeModal(modalKey: string, contextKey?: string): void {\n return ModalAPI.closeModal(modalKey, contextKey);\n}\n\n/**\n * Close all open modals\n */\nexport function closeAllModals(): void {\n return ModalAPI.closeAllModals();\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Command } from \"@api/Commands\";\nimport { FluxEvents } from \"@webpack/types\";\nimport { Promisable } from \"type-fest\";\n\n// exists to export default definePlugin({...})\nexport default function definePlugin<P extends PluginDef>(p: P & Record<string, any>) {\n return p;\n}\n\nexport type ReplaceFn = (match: string, ...groups: string[]) => string;\n\nexport interface PatchReplacement {\n match: string | RegExp;\n replace: string | ReplaceFn;\n predicate?(): boolean;\n}\n\nexport interface Patch {\n plugin: string;\n find: string;\n replacement: PatchReplacement | PatchReplacement[];\n /** Whether this patch should apply to multiple modules */\n all?: boolean;\n /** Do not warn if this patch did no changes */\n noWarn?: boolean;\n /** Only apply this set of replacements if all of them succeed. Use this if your replacements depend on each other */\n group?: boolean;\n predicate?(): boolean;\n}\n\nexport interface PluginAuthor {\n name: string;\n id: BigInt;\n}\n\nexport interface Plugin extends PluginDef {\n patches?: Patch[];\n started: boolean;\n isDependency?: boolean;\n}\n\nexport interface PluginDef {\n name: string;\n description: string;\n authors: PluginAuthor[];\n start?(): void;\n stop?(): void;\n patches?: Omit<Patch, \"plugin\">[];\n /**\n * List of commands. If you specify these, you must add CommandsAPI to dependencies\n */\n commands?: Command[];\n /**\n * A list of other plugins that your plugin depends on.\n * These will automatically be enabled and loaded before your plugin\n * Common examples are CommandsAPI, MessageEventsAPI...\n */\n dependencies?: string[],\n /**\n * Whether this plugin is required and forcefully enabled\n */\n required?: boolean;\n /**\n * Whether this plugin should be enabled by default, but can be disabled\n */\n enabledByDefault?: boolean;\n /**\n * When to call the start() method\n * @default StartAt.WebpackReady\n */\n startAt?: StartAt,\n /**\n * Optionally provide settings that the user can configure in the Plugins tab of settings.\n * @deprecated Use `settings` instead\n */\n // TODO: Remove when everything is migrated to `settings`\n options?: Record<string, PluginOptionsItem>;\n /**\n * Optionally provide settings that the user can configure in the Plugins tab of settings.\n */\n settings?: DefinedSettings;\n /**\n * Check that this returns true before allowing a save to complete.\n * If a string is returned, show the error to the user.\n */\n beforeSave?(options: Record<string, any>): Promisable<true | string>;\n /**\n * Allows you to specify a custom Component that will be rendered in your\n * plugin's settings page\n */\n settingsAboutComponent?: React.ComponentType<{\n tempSettings?: Record<string, any>;\n }>;\n /**\n * Allows you to subscribe to Flux events\n */\n flux?: {\n [E in FluxEvents]?: (event: any) => void;\n };\n /**\n * Allows you to add custom actions to the Vencord Toolbox.\n * The key will be used as text for the button\n */\n toolboxActions?: Record<string, () => void>;\n\n tags?: string[];\n}\n\nexport const enum StartAt {\n /** Right away, as soon as Vencord initialised */\n Init = \"Init\",\n /** On the DOMContentLoaded event, so once the document is ready */\n DOMContentLoaded = \"DOMContentLoaded\",\n /** Once Discord's core webpack modules have finished loading, so as soon as things like react and flux are available */\n WebpackReady = \"WebpackReady\"\n}\n\nexport const enum OptionType {\n STRING,\n NUMBER,\n BIGINT,\n BOOLEAN,\n SELECT,\n SLIDER,\n COMPONENT,\n}\n\nexport type SettingsDefinition = Record<string, PluginSettingDef>;\nexport type SettingsChecks<D extends SettingsDefinition> = {\n [K in keyof D]?: D[K] extends PluginSettingComponentDef ? IsDisabled<DefinedSettings<D>> :\n (IsDisabled<DefinedSettings<D>> & IsValid<PluginSettingType<D[K]>, DefinedSettings<D>>);\n};\n\nexport type PluginSettingDef = (\n | PluginSettingStringDef\n | PluginSettingNumberDef\n | PluginSettingBooleanDef\n | PluginSettingSelectDef\n | PluginSettingSliderDef\n | PluginSettingComponentDef\n | PluginSettingBigIntDef\n) & PluginSettingCommon;\n\nexport interface PluginSettingCommon {\n description: string;\n placeholder?: string;\n onChange?(newValue: any): void;\n /**\n * Whether changing this setting requires a restart\n */\n restartNeeded?: boolean;\n componentProps?: Record<string, any>;\n /**\n * Hide this setting from the settings UI\n */\n hidden?: boolean;\n /**\n * Set this if the setting only works on Browser or Desktop, not both\n */\n target?: \"WEB\" | \"DESKTOP\" | \"BOTH\";\n}\ninterface IsDisabled<D = unknown> {\n /**\n * Checks if this setting should be disabled\n */\n disabled?(this: D): boolean;\n}\ninterface IsValid<T, D = unknown> {\n /**\n * Prevents the user from saving settings if this is false or a string\n */\n isValid?(this: D, value: T): boolean | string;\n}\n\nexport interface PluginSettingStringDef {\n type: OptionType.STRING;\n default?: string;\n}\nexport interface PluginSettingNumberDef {\n type: OptionType.NUMBER;\n default?: number;\n}\nexport interface PluginSettingBigIntDef {\n type: OptionType.BIGINT;\n default?: BigInt;\n}\nexport interface PluginSettingBooleanDef {\n type: OptionType.BOOLEAN;\n default?: boolean;\n}\n\nexport interface PluginSettingSelectDef {\n type: OptionType.SELECT;\n options: readonly PluginSettingSelectOption[];\n}\nexport interface PluginSettingSelectOption {\n label: string;\n value: string | number | boolean;\n default?: boolean;\n}\n\nexport interface PluginSettingSliderDef {\n type: OptionType.SLIDER;\n /**\n * All the possible values in the slider. Needs at least two values.\n */\n markers: number[];\n /**\n * Default value to use\n */\n default: number;\n /**\n * If false, allow users to select values in-between your markers.\n */\n stickToMarkers?: boolean;\n}\n\ninterface IPluginOptionComponentProps {\n /**\n * Run this when the value changes.\n *\n * NOTE: The user will still need to click save to apply these changes.\n */\n setValue(newValue: any): void;\n /**\n * Set to true to prevent the user from saving.\n *\n * NOTE: This will not show the error to the user. It will only stop them saving.\n * Make sure to show the error in your component.\n */\n setError(error: boolean): void;\n /**\n * The options object\n */\n option: PluginSettingComponentDef;\n}\n\nexport interface PluginSettingComponentDef {\n type: OptionType.COMPONENT;\n component: (props: IPluginOptionComponentProps) => JSX.Element;\n}\n\n/** Maps a `PluginSettingDef` to its value type */\ntype PluginSettingType<O extends PluginSettingDef> = O extends PluginSettingStringDef ? string :\n O extends PluginSettingNumberDef ? number :\n O extends PluginSettingBigIntDef ? BigInt :\n O extends PluginSettingBooleanDef ? boolean :\n O extends PluginSettingSelectDef ? O[\"options\"][number][\"value\"] :\n O extends PluginSettingSliderDef ? number :\n O extends PluginSettingComponentDef ? any :\n never;\ntype PluginSettingDefaultType<O extends PluginSettingDef> = O extends PluginSettingSelectDef ? (\n O[\"options\"] extends { default?: boolean; }[] ? O[\"options\"][number][\"value\"] : undefined\n) : O extends { default: infer T; } ? T : undefined;\n\ntype SettingsStore<D extends SettingsDefinition> = {\n [K in keyof D]: PluginSettingType<D[K]> | PluginSettingDefaultType<D[K]>;\n};\n\n/** An instance of defined plugin settings */\nexport interface DefinedSettings<\n Def extends SettingsDefinition = SettingsDefinition,\n Checks extends SettingsChecks<Def> = {},\n PrivateSettings extends object = {}\n> {\n /** Shorthand for `Vencord.Settings.plugins.PluginName`, but with typings */\n store: SettingsStore<Def> & PrivateSettings;\n /**\n * React hook for getting the settings for this plugin\n * @param filter optional filter to avoid rerenders for irrelevent settings\n */\n use<F extends Extract<keyof Def | keyof PrivateSettings, string>>(filter?: F[]): Pick<SettingsStore<Def> & PrivateSettings, F>;\n /** Definitions of each setting */\n def: Def;\n /** Setting methods with return values that could rely on other settings */\n checks: Checks;\n /**\n * Name of the plugin these settings belong to,\n * will be an empty string until plugin is initialized\n */\n pluginName: string;\n\n withPrivateSettings<T extends object>(): DefinedSettings<Def, Checks, T>;\n}\n\nexport type PartialExcept<T, R extends keyof T> = Partial<T> & Required<Pick<T, R>>;\n\nexport type IpcRes<V = any> = { ok: true; value: V; } | { ok: false, error: any; };\n\n/* -------------------------------------------- */\n/* Legacy Options Types */\n/* -------------------------------------------- */\n\nexport type PluginOptionBase = PluginSettingCommon & IsDisabled;\nexport type PluginOptionsItem =\n | PluginOptionString\n | PluginOptionNumber\n | PluginOptionBoolean\n | PluginOptionSelect\n | PluginOptionSlider\n | PluginOptionComponent;\nexport type PluginOptionString = PluginSettingStringDef & PluginSettingCommon & IsDisabled & IsValid<string>;\nexport type PluginOptionNumber = (PluginSettingNumberDef | PluginSettingBigIntDef) & PluginSettingCommon & IsDisabled & IsValid<number | BigInt>;\nexport type PluginOptionBoolean = PluginSettingBooleanDef & PluginSettingCommon & IsDisabled & IsValid<boolean>;\nexport type PluginOptionSelect = PluginSettingSelectDef & PluginSettingCommon & IsDisabled & IsValid<PluginSettingSelectOption>;\nexport type PluginOptionSlider = PluginSettingSliderDef & PluginSettingCommon & IsDisabled & IsValid<number>;\nexport type PluginOptionComponent = PluginSettingComponentDef & PluginSettingCommon;\n\nexport type PluginNative<PluginExports extends Record<string, (event: Electron.IpcMainInvokeEvent, ...args: any[]) => any>> = {\n [key in keyof PluginExports]:\n PluginExports[key] extends (event: Electron.IpcMainInvokeEvent, ...args: infer Args) => infer Return\n ? (...args: Args) => Return extends Promise<any> ? Return : Promise<Return>\n : never;\n};\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { BadgePosition, BadgeUserArgs, ProfileBadge } from \"@api/Badges\";\nimport DonateButton from \"@components/DonateButton\";\nimport ErrorBoundary from \"@components/ErrorBoundary\";\nimport { Flex } from \"@components/Flex\";\nimport { Heart } from \"@components/Heart\";\nimport { Devs } from \"@utils/constants\";\nimport { Margins } from \"@utils/margins\";\nimport { isPluginDev } from \"@utils/misc\";\nimport { closeModal, Modals, openModal } from \"@utils/modal\";\nimport definePlugin from \"@utils/types\";\nimport { Forms, Toasts } from \"@webpack/common\";\n\nconst CONTRIBUTOR_BADGE = \"https://vencord.dev/assets/favicon.png\";\n\nconst ContributorBadge: ProfileBadge = {\n description: \"Vencord Contributor\",\n image: CONTRIBUTOR_BADGE,\n position: BadgePosition.START,\n props: {\n style: {\n borderRadius: \"50%\",\n transform: \"scale(0.9)\" // The image is a bit too big compared to default badges\n }\n },\n shouldShow: ({ user }) => isPluginDev(user.id),\n link: \"https://github.com/Vendicated/Vencord\"\n};\n\nlet DonorBadges = {} as Record<string, Array<Record<\"tooltip\" | \"badge\", string>>>;\n\nasync function loadBadges(noCache = false) {\n DonorBadges = {};\n\n const init = {} as RequestInit;\n if (noCache)\n init.cache = \"no-cache\";\n\n DonorBadges = await fetch(\"https://badges.vencord.dev/badges.json\", init)\n .then(r => r.json());\n}\n\nexport default definePlugin({\n name: \"BadgeAPI\",\n description: \"API to add badges to users.\",\n authors: [Devs.Megu, Devs.Ven, Devs.TheSun],\n required: true,\n patches: [\n /* Patch the badge list component on user profiles */\n {\n find: \"Messages.PROFILE_USER_BADGES,role:\",\n replacement: [\n {\n match: /&&(\\i)\\.push\\(\\{id:\"premium\".+?\\}\\);/,\n replace: \"$&$1.unshift(...Vencord.Api.Badges._getBadges(arguments[0]));\",\n },\n {\n // alt: \"\", aria-hidden: false, src: originalSrc\n match: /alt:\" \",\"aria-hidden\":!0,src:(?=(\\i)\\.src)/,\n // ...badge.props, ..., src: badge.image ?? ...\n replace: \"...$1.props,$& $1.image??\"\n },\n // replace their component with ours if applicable\n {\n match: /(?<=text:(\\i)\\.description,spacing:12,)children:/,\n replace: \"children:$1.component ? () => $self.renderBadgeComponent($1) :\"\n },\n // conditionally override their onClick with badge.onClick if it exists\n {\n match: /href:(\\i)\\.link/,\n replace: \"...($1.onClick && { onClick: $1.onClick }),$&\"\n }\n ]\n }\n ],\n\n toolboxActions: {\n async \"Refetch Badges\"() {\n await loadBadges(true);\n Toasts.show({\n id: Toasts.genId(),\n message: \"Successfully refetched badges!\",\n type: Toasts.Type.SUCCESS\n });\n }\n },\n\n async start() {\n Vencord.Api.Badges.addBadge(ContributorBadge);\n await loadBadges();\n },\n\n renderBadgeComponent: ErrorBoundary.wrap((badge: ProfileBadge & BadgeUserArgs) => {\n const Component = badge.component!;\n return <Component {...badge} />;\n }, { noop: true }),\n\n\n getDonorBadges(userId: string) {\n return DonorBadges[userId]?.map(badge => ({\n image: badge.badge,\n description: badge.tooltip,\n position: BadgePosition.START,\n props: {\n style: {\n borderRadius: \"50%\",\n transform: \"scale(0.9)\" // The image is a bit too big compared to default badges\n }\n },\n onClick() {\n const modalKey = openModal(props => (\n <ErrorBoundary noop onError={() => {\n closeModal(modalKey);\n VencordNative.native.openExternal(\"https://github.com/sponsors/Vendicated\");\n }}>\n <Modals.ModalRoot {...props}>\n <Modals.ModalHeader>\n <Flex style={{ width: \"100%\", justifyContent: \"center\" }}>\n <Forms.FormTitle\n tag=\"h2\"\n style={{\n width: \"100%\",\n textAlign: \"center\",\n margin: 0\n }}\n >\n <Heart />\n Vencord Donor\n </Forms.FormTitle>\n </Flex>\n </Modals.ModalHeader>\n <Modals.ModalContent>\n <Flex>\n <img\n role=\"presentation\"\n src=\"https://cdn.discordapp.com/emojis/1026533070955872337.png\"\n alt=\"\"\n style={{ margin: \"auto\" }}\n />\n <img\n role=\"presentation\"\n src=\"https://cdn.discordapp.com/emojis/1026533090627174460.png\"\n alt=\"\"\n style={{ margin: \"auto\" }}\n />\n </Flex>\n <div style={{ padding: \"1em\" }}>\n <Forms.FormText>\n This Badge is a special perk for Vencord Donors\n </Forms.FormText>\n <Forms.FormText className={Margins.top20}>\n Please consider supporting the development of Vencord by becoming a donor. It would mean a lot!!\n </Forms.FormText>\n </div>\n </Modals.ModalContent>\n <Modals.ModalFooter>\n <Flex style={{ width: \"100%\", justifyContent: \"center\" }}>\n <DonateButton />\n </Flex>\n </Modals.ModalFooter>\n </Modals.ModalRoot>\n </ErrorBoundary>\n ));\n },\n }));\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\n\nexport default definePlugin({\n name: \"CommandsAPI\",\n authors: [Devs.Arjix],\n description: \"Api required by anything that uses commands\",\n patches: [\n // obtain BUILT_IN_COMMANDS instance\n {\n find: ',\"tenor\"',\n replacement: [\n {\n // Matches BUILT_IN_COMMANDS. This is not exported so this is\n // the only way. _init() just returns the same object to make the\n // patch simpler\n\n // textCommands = builtInCommands.filter(...)\n match: /(?<=\\w=)(\\w)(\\.filter\\(.{0,60}tenor)/,\n replace: \"Vencord.Api.Commands._init($1)$2\",\n }\n ],\n },\n // command error handling\n {\n find: \"Unexpected value for option\",\n replacement: {\n // return [2, cmd.execute(args, ctx)]\n match: /,(\\i)\\.execute\\((\\i),(\\i)\\)/,\n replace: (_, cmd, args, ctx) => `,Vencord.Api.Commands._handleCommand(${cmd}, ${args}, ${ctx})`\n }\n },\n // Show plugin name instead of \"Built-In\"\n {\n find: \".source,children\",\n replacement: {\n // ...children: p?.name\n match: /(?<=:(.{1,3})\\.displayDescription\\}.{0,200}\\.source,children:)[^}]+/,\n replace: \"$1.plugin||($&)\"\n }\n }\n ],\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\n\nexport default definePlugin({\n name: \"ContextMenuAPI\",\n description: \"API for adding/removing items to/from context menus.\",\n authors: [Devs.Nuckyz, Devs.Ven],\n required: true,\n\n patches: [\n {\n find: \"\u266B (\u3064\uFF61\u25D5\u203F\u203F\u25D5\uFF61)\u3064 \u266A\",\n replacement: {\n match: /let{navId:/,\n replace: \"Vencord.Api.ContextMenu._patchContextMenu(arguments[0]);$&\"\n }\n },\n {\n find: \".Menu,{\",\n all: true,\n replacement: {\n match: /Menu,{(?<=\\.jsxs?\\)\\(\\i\\.Menu,{)/g,\n replace: \"$&contextMenuApiArguments:typeof arguments!=='undefined'?arguments:[],\"\n }\n }\n ]\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\n\nexport default definePlugin({\n name: \"MemberListDecoratorsAPI\",\n description: \"API to add decorators to member list (both in servers and DMs)\",\n authors: [Devs.TheSun, Devs.Ven],\n patches: [\n {\n find: \".lostPermission)\",\n replacement: [\n {\n match: /let\\{[^}]*lostPermissionTooltipText:\\i[^}]*\\}=(\\i),/,\n replace: \"$&vencordProps=$1,\"\n }, {\n match: /decorators:.{0,100}?children:\\[/,\n replace: \"$&...(typeof vencordProps=='undefined'?[]:Vencord.Api.MemberListDecorators.__getDecorators(vencordProps)),\"\n }\n ]\n },\n {\n find: \"PrivateChannel.renderAvatar\",\n replacement: {\n match: /decorators:(\\i\\.isSystemDM\\(\\))\\?(.+?):null/,\n replace: \"decorators:[...Vencord.Api.MemberListDecorators.__getDecorators(arguments[0]), $1?$2:null]\"\n }\n }\n ],\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\n\nexport default definePlugin({\n name: \"MessageAccessoriesAPI\",\n description: \"API to add message accessories.\",\n authors: [Devs.Cyn],\n patches: [\n {\n find: \".Messages.REMOVE_ATTACHMENT_BODY\",\n replacement: {\n match: /(?<=.container\\)?,children:)(\\[.+?\\])/,\n replace: \"Vencord.Api.MessageAccessories._modifyAccessories($1,this.props)\",\n },\n },\n ],\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\n\nexport default definePlugin({\n name: \"MessageDecorationsAPI\",\n description: \"API to add decorations to messages\",\n authors: [Devs.TheSun],\n patches: [\n {\n find: '\"Message Username\"',\n replacement: {\n match: /\\.Messages\\.GUILD_COMMUNICATION_DISABLED_BOTTOM_SHEET_TITLE.+?}\\),\\i(?=\\])/,\n replace: \"$&,...Vencord.Api.MessageDecorations.__addDecorationsToMessage(arguments[0])\"\n }\n }\n ],\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\n\nexport default definePlugin({\n name: \"MessageEventsAPI\",\n description: \"Api required by anything using message events.\",\n authors: [Devs.Arjix, Devs.hunt, Devs.Ven],\n patches: [\n {\n find: '\"MessageActionCreators\"',\n replacement: {\n match: /async editMessage\\(.+?\\)\\{/,\n replace: \"$&await Vencord.Api.MessageEvents._handlePreEdit(...arguments);\"\n }\n },\n {\n find: \".handleSendMessage=\",\n replacement: {\n // props.chatInputType...then((function(isMessageValid)... var parsedMessage = b.c.parse(channel,... var replyOptions = f.g.getSendMessageOptionsForReply(pendingReply);\n // Lookbehind: validateMessage)({openWarningPopout:..., type: i.props.chatInputType, content: t, stickers: r, ...}).then((function(isMessageValid)\n match: /(type:this\\.props\\.chatInputType.+?\\.then\\()(\\i=>\\{.+?let (\\i)=\\i\\.\\i\\.parse\\((\\i),.+?let (\\i)=\\i\\.\\i\\.getSendMessageOptionsForReply\\(\\i\\);)(?<=\\)\\(({.+?})\\)\\.then.+?)/,\n // props.chatInputType...then((async function(isMessageValid)... var replyOptions = f.g.getSendMessageOptionsForReply(pendingReply); if(await Vencord.api...) return { shoudClear:true, shouldRefocus:true };\n replace: (_, rest1, rest2, parsedMessage, channel, replyOptions, extra) => \"\" +\n `${rest1}async ${rest2}` +\n `if(await Vencord.Api.MessageEvents._handlePreSend(${channel}.id,${parsedMessage},${extra},${replyOptions}))` +\n \"return{shoudClear:true,shouldRefocus:true};\"\n }\n },\n {\n find: '(\"interactionUsernameProfile',\n replacement: {\n match: /let\\{id:\\i}=(\\i),{id:\\i}=(\\i);return \\i\\.useCallback\\((\\i)=>\\{/,\n replace: (m, message, channel, event) =>\n // the message param is shadowed by the event param, so need to alias them\n `const vcMsg=${message},vcChan=${channel};${m}Vencord.Api.MessageEvents._handleClick(vcMsg, vcChan, ${event});`\n }\n }\n ]\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\n\nexport default definePlugin({\n name: \"MessagePopoverAPI\",\n description: \"API to add buttons to message popovers.\",\n authors: [Devs.KingFish, Devs.Ven, Devs.Nuckyz],\n patches: [{\n find: \"Messages.MESSAGE_UTILITIES_A11Y_LABEL\",\n replacement: {\n // foo && !bar ? createElement(reactionStuffs)... createElement(blah,...makeElement(reply-other))\n match: /\\i&&!\\i\\?\\(0,\\i\\.jsxs?\\)\\(.{0,200}renderEmojiPicker:.{0,500}\\?(\\i)\\(\\{key:\"reply-other\"/,\n replace: (m, makeElement) => {\n const msg = m.match(/message:(.{1,3}),/)?.[1];\n if (!msg) throw new Error(\"Could not find message variable\");\n return `...Vencord.Api.MessagePopover._buildPopoverElements(${msg},${makeElement}),${m}`;\n }\n }\n }],\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\n\nexport default definePlugin({\n name: \"NoticesAPI\",\n description: \"Fixes notices being automatically dismissed\",\n authors: [Devs.Ven],\n required: true,\n patches: [\n {\n find: 'displayName=\"NoticeStore\"',\n replacement: [\n {\n match: /\\i=null;(?=.{0,80}getPremiumSubscription\\(\\))/g,\n replace: \"if(Vencord.Api.Notices.currentNotice)return false;$&\"\n },\n {\n match: /(?<=,NOTICE_DISMISS:function\\(\\i\\){)return null!=(\\i)/,\n replace: \"if($1.id==\\\"VencordNotice\\\")return($1=null,Vencord.Api.Notices.nextNotice(),true);$&\"\n }\n ]\n }\n ],\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\n\nexport default definePlugin({\n name: \"ServerListAPI\",\n authors: [Devs.kemo],\n description: \"Api required for plugins that modify the server list\",\n patches: [\n {\n find: \"Messages.DISCODO_DISABLED\",\n replacement: {\n match: /(?<=Messages\\.DISCODO_DISABLED.+?return)(\\(.{0,75}?tutorialContainer.+?}\\))(?=}function)/,\n replace: \"[$1].concat(Vencord.Api.ServerList.renderAll(Vencord.Api.ServerList.ServerListRenderPosition.Above))\"\n }\n },\n {\n find: \"Messages.SERVERS,children\",\n replacement: {\n match: /(?<=Messages\\.SERVERS,children:).+?default:return null\\}\\}\\)/,\n replace: \"Vencord.Api.ServerList.renderAll(Vencord.Api.ServerList.ServerListRenderPosition.In).concat($&)\"\n }\n }\n ]\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\n\nexport default definePlugin({\n name: \"NoTrack\",\n description: \"Disable Discord's tracking ('science'), metrics and Sentry crash reporting\",\n authors: [Devs.Cyn, Devs.Ven, Devs.Nuckyz, Devs.Arrow],\n required: true,\n patches: [\n {\n find: \"AnalyticsActionHandlers.handle\",\n replacement: {\n match: /^.+$/,\n replace: \"()=>{}\",\n },\n },\n {\n find: \"window.DiscordSentry=\",\n replacement: {\n match: /^.+$/,\n replace: \"()=>{}\",\n }\n },\n {\n find: \".METRICS,\",\n replacement: [\n {\n match: /this\\._intervalId=/,\n replace: \"this._intervalId=undefined&&\"\n },\n {\n match: /(increment\\(\\i\\){)/,\n replace: \"$1return;\"\n }\n ]\n },\n {\n find: \".installedLogHooks)\",\n replacement: {\n // if getDebugLogging() returns false, the hooks don't get installed.\n match: \"getDebugLogging(){\",\n replace: \"getDebugLogging(){return false;\"\n }\n },\n ]\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Logger } from \"@utils/Logger\";\nimport type { ReactElement } from \"react\";\n\ntype ContextMenuPatchCallbackReturn = (() => void) | void;\n/**\n * @param children The rendered context menu elements\n * @param args Any arguments passed into making the context menu, like the guild, channel, user or message for example\n * @returns A callback which is only ran once used to modify the context menu elements (Use to avoid duplicates)\n */\nexport type NavContextMenuPatchCallback = (children: Array<ReactElement | null>, ...args: Array<any>) => ContextMenuPatchCallbackReturn;\n/**\n * @param navId The navId of the context menu being patched\n * @param children The rendered context menu elements\n * @param args Any arguments passed into making the context menu, like the guild, channel, user or message for example\n * @returns A callback which is only ran once used to modify the context menu elements (Use to avoid duplicates)\n */\nexport type GlobalContextMenuPatchCallback = (navId: string, children: Array<ReactElement | null>, ...args: Array<any>) => ContextMenuPatchCallbackReturn;\n\nconst ContextMenuLogger = new Logger(\"ContextMenu\");\n\nexport const navPatches = new Map<string, Set<NavContextMenuPatchCallback>>();\nexport const globalPatches = new Set<GlobalContextMenuPatchCallback>();\n\n/**\n * Add a context menu patch\n * @param navId The navId(s) for the context menu(s) to patch\n * @param patch The patch to be applied\n */\nexport function addContextMenuPatch(navId: string | Array<string>, patch: NavContextMenuPatchCallback) {\n if (!Array.isArray(navId)) navId = [navId];\n for (const id of navId) {\n let contextMenuPatches = navPatches.get(id);\n if (!contextMenuPatches) {\n contextMenuPatches = new Set();\n navPatches.set(id, contextMenuPatches);\n }\n\n contextMenuPatches.add(patch);\n }\n}\n\n/**\n * Add a global context menu patch that fires the patch for all context menus\n * @param patch The patch to be applied\n */\nexport function addGlobalContextMenuPatch(patch: GlobalContextMenuPatchCallback) {\n globalPatches.add(patch);\n}\n\n/**\n * Remove a context menu patch\n * @param navId The navId(s) for the context menu(s) to remove the patch\n * @param patch The patch to be removed\n * @returns Whether the patch was successfully removed from the context menu(s)\n */\nexport function removeContextMenuPatch<T extends string | Array<string>>(navId: T, patch: NavContextMenuPatchCallback): T extends string ? boolean : Array<boolean> {\n const navIds = Array.isArray(navId) ? navId : [navId as string];\n\n const results = navIds.map(id => navPatches.get(id)?.delete(patch) ?? false);\n\n return (Array.isArray(navId) ? results : results[0]) as T extends string ? boolean : Array<boolean>;\n}\n\n/**\n * Remove a global context menu patch\n * @param patch The patch to be removed\n * @returns Whether the patch was successfully removed\n */\nexport function removeGlobalContextMenuPatch(patch: GlobalContextMenuPatchCallback): boolean {\n return globalPatches.delete(patch);\n}\n\n/**\n * A helper function for finding the children array of a group nested inside a context menu based on the id(s) of its children\n * @param id The id of the child. If an array is specified, all ids will be tried\n * @param children The context menu children\n */\nexport function findGroupChildrenByChildId(id: string | string[], children: Array<ReactElement | null>, _itemsArray?: Array<ReactElement | null>): Array<ReactElement | null> | null {\n for (const child of children) {\n if (child == null) continue;\n\n if (\n (Array.isArray(id) && id.some(id => child.props?.id === id))\n || child.props?.id === id\n ) return _itemsArray ?? null;\n\n let nextChildren = child.props?.children;\n if (nextChildren) {\n if (!Array.isArray(nextChildren)) {\n nextChildren = [nextChildren];\n child.props.children = nextChildren;\n }\n\n const found = findGroupChildrenByChildId(id, nextChildren, nextChildren);\n if (found !== null) return found;\n }\n }\n\n return null;\n}\n\ninterface ContextMenuProps {\n contextMenuApiArguments?: Array<any>;\n navId: string;\n children: Array<ReactElement | null>;\n \"aria-label\": string;\n onSelect: (() => void) | undefined;\n onClose: (callback: (...args: Array<any>) => any) => void;\n}\n\nconst patchedMenus = new WeakSet();\n\nexport function _patchContextMenu(props: ContextMenuProps) {\n props.contextMenuApiArguments ??= [];\n const contextMenuPatches = navPatches.get(props.navId);\n\n if (!Array.isArray(props.children)) props.children = [props.children];\n\n if (contextMenuPatches) {\n for (const patch of contextMenuPatches) {\n try {\n const callback = patch(props.children, ...props.contextMenuApiArguments);\n if (!patchedMenus.has(props)) callback?.();\n } catch (err) {\n ContextMenuLogger.error(`Patch for ${props.navId} errored,`, err);\n }\n }\n }\n\n for (const patch of globalPatches) {\n try {\n const callback = patch(props.navId, props.children, ...props.contextMenuApiArguments);\n if (!patchedMenus.has(props)) callback?.();\n } catch (err) {\n ContextMenuLogger.error(\"Global patch errored,\", err);\n }\n }\n\n patchedMenus.add(props);\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\n/**\n * Returns a new function that will call the wrapped function\n * after the specified delay. If the function is called again\n * within the delay, the timer will be reset.\n * @param func The function to wrap\n * @param delay The delay in milliseconds\n */\nexport function debounce<T extends Function>(func: T, delay = 300): T {\n let timeout: NodeJS.Timeout;\n return function (...args: any[]) {\n clearTimeout(timeout);\n timeout = setTimeout(() => { func(...args); }, delay);\n } as any;\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nexport const { localStorage } = window;\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Promisable } from \"type-fest\";\n\n/**\n * A queue that can be used to run tasks consecutively.\n * Highly recommended for things like fetching data from Discord\n */\nexport class Queue {\n /**\n * @param maxSize The maximum amount of functions that can be queued at once.\n * If the queue is full, the oldest function will be removed.\n */\n constructor(public readonly maxSize = Infinity) { }\n\n private queue = [] as Array<() => Promisable<unknown>>;\n\n private promise?: Promise<any>;\n\n private next() {\n const func = this.queue.shift();\n if (func)\n this.promise = Promise.resolve()\n .then(func)\n .finally(() => this.next());\n else\n this.promise = undefined;\n }\n\n private run() {\n if (!this.promise)\n this.next();\n }\n\n /**\n * Append a task at the end of the queue. This task will be executed after all other tasks\n * If the queue exceeds the specified maxSize, the first task in queue will be removed.\n * @param func Task\n */\n push<T>(func: () => Promisable<T>) {\n if (this.size >= this.maxSize)\n this.queue.shift();\n\n this.queue.push(func);\n this.run();\n }\n\n /**\n * Prepend a task at the beginning of the queue. This task will be executed next\n * If the queue exceeds the specified maxSize, the last task in queue will be removed.\n * @param func Task\n */\n unshift<T>(func: () => Promisable<T>) {\n if (this.size >= this.maxSize)\n this.queue.pop();\n\n this.queue.unshift(func);\n this.run();\n }\n\n /**\n * The amount of tasks in the queue\n */\n get size() {\n return this.queue.length;\n }\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport \"./styles.css\";\n\nimport { useSettings } from \"@api/Settings\";\nimport ErrorBoundary from \"@components/ErrorBoundary\";\nimport { classes } from \"@utils/misc\";\nimport { React, useEffect, useMemo, useState, useStateFromStores, WindowStore } from \"@webpack/common\";\n\nimport { NotificationData } from \"./Notifications\";\n\nexport default ErrorBoundary.wrap(function NotificationComponent({\n title,\n body,\n richBody,\n color,\n icon,\n onClick,\n onClose,\n image,\n permanent,\n className,\n dismissOnClick\n}: NotificationData & { className?: string; }) {\n const { timeout, position } = useSettings([\"notifications.timeout\", \"notifications.position\"]).notifications;\n const hasFocus = useStateFromStores([WindowStore], () => WindowStore.isFocused());\n\n const [isHover, setIsHover] = useState(false);\n const [elapsed, setElapsed] = useState(0);\n\n const start = useMemo(() => Date.now(), [timeout, isHover, hasFocus]);\n\n useEffect(() => {\n if (isHover || !hasFocus || timeout === 0 || permanent) return void setElapsed(0);\n\n const intervalId = setInterval(() => {\n const elapsed = Date.now() - start;\n if (elapsed >= timeout)\n onClose!();\n else\n setElapsed(elapsed);\n }, 10);\n\n return () => clearInterval(intervalId);\n }, [timeout, isHover, hasFocus]);\n\n const timeoutProgress = elapsed / timeout;\n\n return (\n <button\n className={classes(\"vc-notification-root\", className)}\n style={position === \"bottom-right\" ? { bottom: \"1rem\" } : { top: \"3rem\" }}\n onClick={() => {\n onClick?.();\n if (dismissOnClick !== false)\n onClose!();\n }}\n onContextMenu={e => {\n e.preventDefault();\n e.stopPropagation();\n onClose!();\n }}\n onMouseEnter={() => setIsHover(true)}\n onMouseLeave={() => setIsHover(false)}\n >\n <div className=\"vc-notification\">\n {icon && <img className=\"vc-notification-icon\" src={icon} alt=\"\" />}\n <div className=\"vc-notification-content\">\n <div className=\"vc-notification-header\">\n <h2 className=\"vc-notification-title\">{title}</h2>\n <button\n className=\"vc-notification-close-btn\"\n onClick={e => {\n e.preventDefault();\n e.stopPropagation();\n onClose!();\n }}\n >\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n role=\"img\"\n aria-labelledby=\"vc-notification-dismiss-title\"\n >\n <title id=\"vc-notification-dismiss-title\">Dismiss Notification</title>\n <path fill=\"currentColor\" d=\"M18.4 4L12 10.4L5.6 4L4 5.6L10.4 12L4 18.4L5.6 20L12 13.6L18.4 20L20 18.4L13.6 12L20 5.6L18.4 4Z\" />\n </svg>\n </button>\n </div>\n <div>\n {richBody ?? <p className=\"vc-notification-p\">{body}</p>}\n </div>\n </div>\n </div>\n {image && <img className=\"vc-notification-img\" src={image} alt=\"\" />}\n {timeout !== 0 && !permanent && (\n <div\n className=\"vc-notification-progressbar\"\n style={{ width: `${(1 - timeoutProgress) * 100}%`, backgroundColor: color || \"var(--brand-experiment)\" }}\n />\n )}\n </button>\n );\n}, {\n onError: ({ props }) => props.onClose!()\n});\n", "/* eslint-disable simple-header/header */\n\n/*!\n * idb-keyval v6.2.0\n * Copyright 2016, Jake Archibald\n * Copyright 2022, Vendicated\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport function promisifyRequest<T = undefined>(\n request: IDBRequest<T> | IDBTransaction,\n): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n // @ts-ignore - file size hacks\n request.oncomplete = request.onsuccess = () => resolve(request.result);\n // @ts-ignore - file size hacks\n request.onabort = request.onerror = () => reject(request.error);\n });\n}\n\nexport function createStore(dbName: string, storeName: string): UseStore {\n const request = indexedDB.open(dbName);\n request.onupgradeneeded = () => request.result.createObjectStore(storeName);\n const dbp = promisifyRequest(request);\n\n return (txMode, callback) =>\n dbp.then(db =>\n callback(db.transaction(storeName, txMode).objectStore(storeName)),\n );\n}\n\nexport type UseStore = <T>(\n txMode: IDBTransactionMode,\n callback: (store: IDBObjectStore) => T | PromiseLike<T>,\n) => Promise<T>;\n\nlet defaultGetStoreFunc: UseStore | undefined;\n\nfunction defaultGetStore() {\n if (!defaultGetStoreFunc) {\n defaultGetStoreFunc = createStore(\"VencordData\", \"VencordStore\");\n }\n return defaultGetStoreFunc;\n}\n\n/**\n * Get a value by its key.\n *\n * @param key\n * @param customStore Method to get a custom store. Use with caution (see the docs).\n */\nexport function get<T = any>(\n key: IDBValidKey,\n customStore = defaultGetStore(),\n): Promise<T | undefined> {\n return customStore(\"readonly\", store => promisifyRequest(store.get(key)));\n}\n\n/**\n * Set a value with a key.\n *\n * @param key\n * @param value\n * @param customStore Method to get a custom store. Use with caution (see the docs).\n */\nexport function set(\n key: IDBValidKey,\n value: any,\n customStore = defaultGetStore(),\n): Promise<void> {\n return customStore(\"readwrite\", store => {\n store.put(value, key);\n return promisifyRequest(store.transaction);\n });\n}\n\n/**\n * Set multiple values at once. This is faster than calling set() multiple times.\n * It's also atomic \u2013 if one of the pairs can't be added, none will be added.\n *\n * @param entries Array of entries, where each entry is an array of `[key, value]`.\n * @param customStore Method to get a custom store. Use with caution (see the docs).\n */\nexport function setMany(\n entries: [IDBValidKey, any][],\n customStore = defaultGetStore(),\n): Promise<void> {\n return customStore(\"readwrite\", store => {\n entries.forEach(entry => store.put(entry[1], entry[0]));\n return promisifyRequest(store.transaction);\n });\n}\n\n/**\n * Get multiple values by their keys\n *\n * @param keys\n * @param customStore Method to get a custom store. Use with caution (see the docs).\n */\nexport function getMany<T = any>(\n keys: IDBValidKey[],\n customStore = defaultGetStore(),\n): Promise<T[]> {\n return customStore(\"readonly\", store =>\n Promise.all(keys.map(key => promisifyRequest(store.get(key)))),\n );\n}\n\n/**\n * Update a value. This lets you see the old value and update it as an atomic operation.\n *\n * @param key\n * @param updater A callback that takes the old value and returns a new value.\n * @param customStore Method to get a custom store. Use with caution (see the docs).\n */\nexport function update<T = any>(\n key: IDBValidKey,\n updater: (oldValue: T | undefined) => T,\n customStore = defaultGetStore(),\n): Promise<void> {\n return customStore(\n \"readwrite\",\n store =>\n // Need to create the promise manually.\n // If I try to chain promises, the transaction closes in browsers\n // that use a promise polyfill (IE10/11).\n new Promise((resolve, reject) => {\n store.get(key).onsuccess = function () {\n try {\n store.put(updater(this.result), key);\n resolve(promisifyRequest(store.transaction));\n } catch (err) {\n reject(err);\n }\n };\n }),\n );\n}\n\n/**\n * Delete a particular key from the store.\n *\n * @param key\n * @param customStore Method to get a custom store. Use with caution (see the docs).\n */\nexport function del(\n key: IDBValidKey,\n customStore = defaultGetStore(),\n): Promise<void> {\n return customStore(\"readwrite\", store => {\n store.delete(key);\n return promisifyRequest(store.transaction);\n });\n}\n\n/**\n * Delete multiple keys at once.\n *\n * @param keys List of keys to delete.\n * @param customStore Method to get a custom store. Use with caution (see the docs).\n */\nexport function delMany(\n keys: IDBValidKey[],\n customStore = defaultGetStore(),\n): Promise<void> {\n return customStore(\"readwrite\", (store: IDBObjectStore) => {\n keys.forEach((key: IDBValidKey) => store.delete(key));\n return promisifyRequest(store.transaction);\n });\n}\n\n/**\n * Clear all values in the store.\n *\n * @param customStore Method to get a custom store. Use with caution (see the docs).\n */\nexport function clear(customStore = defaultGetStore()): Promise<void> {\n return customStore(\"readwrite\", store => {\n store.clear();\n return promisifyRequest(store.transaction);\n });\n}\n\nfunction eachCursor(\n store: IDBObjectStore,\n callback: (cursor: IDBCursorWithValue) => void,\n): Promise<void> {\n store.openCursor().onsuccess = function () {\n if (!this.result) return;\n callback(this.result);\n this.result.continue();\n };\n return promisifyRequest(store.transaction);\n}\n\n/**\n * Get all keys in the store.\n *\n * @param customStore Method to get a custom store. Use with caution (see the docs).\n */\nexport function keys<KeyType extends IDBValidKey>(\n customStore = defaultGetStore(),\n): Promise<KeyType[]> {\n return customStore(\"readonly\", store => {\n // Fast path for modern browsers\n if (store.getAllKeys) {\n return promisifyRequest(\n store.getAllKeys() as unknown as IDBRequest<KeyType[]>,\n );\n }\n\n const items: KeyType[] = [];\n\n return eachCursor(store, cursor =>\n items.push(cursor.key as KeyType),\n ).then(() => items);\n });\n}\n\n/**\n * Get all values in the store.\n *\n * @param customStore Method to get a custom store. Use with caution (see the docs).\n */\nexport function values<T = any>(customStore = defaultGetStore()): Promise<T[]> {\n return customStore(\"readonly\", store => {\n // Fast path for modern browsers\n if (store.getAll) {\n return promisifyRequest(store.getAll() as IDBRequest<T[]>);\n }\n\n const items: T[] = [];\n\n return eachCursor(store, cursor => items.push(cursor.value as T)).then(\n () => items,\n );\n });\n}\n\n/**\n * Get all entries in the store. Each entry is an array of `[key, value]`.\n *\n * @param customStore Method to get a custom store. Use with caution (see the docs).\n */\nexport function entries<KeyType extends IDBValidKey, ValueType = any>(\n customStore = defaultGetStore(),\n): Promise<[KeyType, ValueType][]> {\n return customStore(\"readonly\", store => {\n // Fast path for modern browsers\n // (although, hopefully we'll get a simpler path some day)\n if (store.getAll && store.getAllKeys) {\n return Promise.all([\n promisifyRequest(\n store.getAllKeys() as unknown as IDBRequest<KeyType[]>,\n ),\n promisifyRequest(store.getAll() as IDBRequest<ValueType[]>),\n ]).then(([keys, values]) => keys.map((key, i) => [key, values[i]]));\n }\n\n const items: [KeyType, ValueType][] = [];\n\n return customStore(\"readonly\", store =>\n eachCursor(store, cursor =>\n items.push([cursor.key as KeyType, cursor.value]),\n ).then(() => items),\n );\n });\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport type { MapValue } from \"type-fest/source/entry\";\n\nexport type Style = MapValue<typeof VencordStyles>;\n\nexport const styleMap = window.VencordStyles ??= new Map();\n\nexport function requireStyle(name: string) {\n const style = styleMap.get(name);\n if (!style) throw new Error(`Style \"${name}\" does not exist`);\n return style;\n}\n\n/**\n * A style's name can be obtained from importing a stylesheet with `?managed` at the end of the import\n * @param name The name of the style\n * @returns `false` if the style was already enabled, `true` otherwise\n * @example\n * import pluginStyle from \"./plugin.css?managed\";\n *\n * // Inside some plugin method like \"start()\" or \"[option].onChange()\"\n * enableStyle(pluginStyle);\n */\nexport function enableStyle(name: string) {\n const style = requireStyle(name);\n\n if (style.dom?.isConnected)\n return false;\n\n if (!style.dom) {\n style.dom = document.createElement(\"style\");\n style.dom.dataset.vencordName = style.name;\n }\n compileStyle(style);\n\n document.head.appendChild(style.dom);\n return true;\n}\n\n/**\n * @param name The name of the style\n * @returns `false` if the style was already disabled, `true` otherwise\n * @see {@link enableStyle} for info on getting the name of an imported style\n */\nexport function disableStyle(name: string) {\n const style = requireStyle(name);\n if (!style.dom?.isConnected)\n return false;\n\n style.dom.remove();\n style.dom = null;\n return true;\n}\n\n/**\n * @param name The name of the style\n * @returns `true` in most cases, may return `false` in some edge cases\n * @see {@link enableStyle} for info on getting the name of an imported style\n */\nexport const toggleStyle = (name: string) => isStyleEnabled(name) ? disableStyle(name) : enableStyle(name);\n\n/**\n * @param name The name of the style\n * @returns Whether the style is enabled\n * @see {@link enableStyle} for info on getting the name of an imported style\n */\nexport const isStyleEnabled = (name: string) => requireStyle(name).dom?.isConnected ?? false;\n\n/**\n * Sets the variables of a style\n * ```ts\n * // -- plugin.ts --\n * import pluginStyle from \"./plugin.css?managed\";\n * import { setStyleVars } from \"@api/Styles\";\n * import { findByPropsLazy } from \"@webpack\";\n * const classNames = findByPropsLazy(\"thin\", \"scrollerBase\"); // { thin: \"thin-31rlnD scrollerBase-_bVAAt\", ... }\n *\n * // Inside some plugin method like \"start()\"\n * setStyleClassNames(pluginStyle, classNames);\n * enableStyle(pluginStyle);\n * ```\n * ```scss\n * // -- plugin.css --\n * .plugin-root [--thin]::-webkit-scrollbar { ... }\n * ```\n * ```scss\n * // -- final stylesheet --\n * .plugin-root .thin-31rlnD.scrollerBase-_bVAAt::-webkit-scrollbar { ... }\n * ```\n * @param name The name of the style\n * @param classNames An object where the keys are the variable names and the values are the variable values\n * @param recompile Whether to recompile the style after setting the variables, defaults to `true`\n * @see {@link enableStyle} for info on getting the name of an imported style\n */\nexport const setStyleClassNames = (name: string, classNames: Record<string, string>, recompile = true) => {\n const style = requireStyle(name);\n style.classNames = classNames;\n if (recompile && isStyleEnabled(style.name))\n compileStyle(style);\n};\n\n/**\n * Updates the stylesheet after doing the following to the sourcecode:\n * - Interpolate style classnames\n * @param style **_Must_ be a style with a DOM element**\n * @see {@link setStyleClassNames} for more info on style classnames\n */\nexport const compileStyle = (style: Style) => {\n if (!style.dom) throw new Error(\"Style has no DOM element\");\n\n style.dom.textContent = style.source\n .replace(/\\[--(\\w+)\\]/g, (match, name) => {\n const className = style.classNames[name];\n return className ? classNameToSelector(className) : match;\n });\n};\n\n/**\n * @param name The classname\n * @param prefix A prefix to add each class, defaults to `\"\"`\n * @return A css selector for the classname\n * @example\n * classNameToSelector(\"foo bar\") // => \".foo.bar\"\n */\nexport const classNameToSelector = (name: string, prefix = \"\") => name.split(\" \").map(n => `.${prefix}${n}`).join(\"\");\n\ntype ClassNameFactoryArg = string | string[] | Record<string, unknown> | false | null | undefined | 0 | \"\";\n/**\n * @param prefix The prefix to add to each class, defaults to `\"\"`\n * @returns A classname generator function\n * @example\n * const cl = classNameFactory(\"plugin-\");\n *\n * cl(\"base\", [\"item\", \"editable\"], { selected: null, disabled: true })\n * // => \"plugin-base plugin-item plugin-editable plugin-disabled\"\n */\nexport const classNameFactory = (prefix: string = \"\") => (...args: ClassNameFactoryArg[]) => {\n const classNames = new Set<string>();\n for (const arg of args) {\n if (arg && typeof arg === \"string\") classNames.add(arg);\n else if (Array.isArray(arg)) arg.forEach(name => classNames.add(name));\n else if (arg && typeof arg === \"object\") Object.entries(arg).forEach(([name, value]) => value && classNames.add(name));\n }\n return Array.from(classNames, name => prefix + name).join(\" \");\n};\n", "export { urlAlphabet } from './url-alphabet/index.js'\nexport let random = bytes => crypto.getRandomValues(new Uint8Array(bytes))\nexport let customRandom = (alphabet, defaultSize, getRandom) => {\n let mask = (2 << (Math.log(alphabet.length - 1) / Math.LN2)) - 1\n let step = -~((1.6 * mask * defaultSize) / alphabet.length)\n return (size = defaultSize) => {\n let id = ''\n while (true) {\n let bytes = getRandom(step)\n let j = step\n while (j--) {\n id += alphabet[bytes[j] & mask] || ''\n if (id.length === size) return id\n }\n }\n }\n}\nexport let customAlphabet = (alphabet, size = 21) =>\n customRandom(alphabet, size, random)\nexport let nanoid = (size = 21) =>\n crypto.getRandomValues(new Uint8Array(size)).reduce((id, byte) => {\n byte &= 63\n if (byte < 36) {\n id += byte.toString(36)\n } else if (byte < 62) {\n id += (byte - 26).toString(36).toUpperCase()\n } else if (byte > 62) {\n id += '-'\n } else {\n id += '_'\n }\n return id\n }, '')\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport * as DataStore from \"@api/DataStore\";\nimport { Settings } from \"@api/Settings\";\nimport { classNameFactory } from \"@api/Styles\";\nimport { closeModal, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from \"@utils/modal\";\nimport { useAwaiter } from \"@utils/react\";\nimport { Alerts, Button, Forms, moment, React, Text, Timestamp, useEffect, useReducer, useState } from \"@webpack/common\";\nimport { nanoid } from \"nanoid\";\nimport type { DispatchWithoutAction } from \"react\";\n\nimport NotificationComponent from \"./NotificationComponent\";\nimport type { NotificationData } from \"./Notifications\";\n\ninterface PersistentNotificationData extends Pick<NotificationData, \"title\" | \"body\" | \"image\" | \"icon\" | \"color\"> {\n timestamp: number;\n id: string;\n}\n\nconst KEY = \"notification-log\";\n\nconst getLog = async () => {\n const log = await DataStore.get(KEY) as PersistentNotificationData[] | undefined;\n return log ?? [];\n};\n\nconst cl = classNameFactory(\"vc-notification-log-\");\nconst signals = new Set<DispatchWithoutAction>();\n\nexport async function persistNotification(notification: NotificationData) {\n if (notification.noPersist) return;\n\n const limit = Settings.notifications.logLimit;\n if (limit === 0) return;\n\n await DataStore.update(KEY, (old: PersistentNotificationData[] | undefined) => {\n const log = old ?? [];\n\n // Omit stuff we don't need\n const {\n onClick, onClose, richBody, permanent, noPersist, dismissOnClick,\n ...pureNotification\n } = notification;\n\n log.unshift({\n ...pureNotification,\n timestamp: Date.now(),\n id: nanoid()\n });\n\n if (log.length > limit && limit !== 200)\n log.length = limit;\n\n return log;\n });\n\n signals.forEach(x => x());\n}\n\nexport async function deleteNotification(timestamp: number) {\n const log = await getLog();\n const index = log.findIndex(x => x.timestamp === timestamp);\n if (index === -1) return;\n\n log.splice(index, 1);\n await DataStore.set(KEY, log);\n signals.forEach(x => x());\n}\n\nexport function useLogs() {\n const [signal, setSignal] = useReducer(x => x + 1, 0);\n\n useEffect(() => {\n signals.add(setSignal);\n return () => void signals.delete(setSignal);\n }, []);\n\n const [log, _, pending] = useAwaiter(getLog, {\n fallbackValue: [],\n deps: [signal]\n });\n\n return [log, pending] as const;\n}\n\nfunction NotificationEntry({ data }: { data: PersistentNotificationData; }) {\n const [removing, setRemoving] = useState(false);\n const ref = React.useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const div = ref.current!;\n\n const setHeight = () => {\n if (div.clientHeight === 0) return requestAnimationFrame(setHeight);\n div.style.height = `${div.clientHeight}px`;\n };\n\n setHeight();\n }, []);\n\n return (\n <div className={cl(\"wrapper\", { removing })} ref={ref}>\n <NotificationComponent\n {...data}\n permanent={true}\n dismissOnClick={false}\n onClose={() => {\n if (removing) return;\n setRemoving(true);\n\n setTimeout(() => deleteNotification(data.timestamp), 200);\n }}\n richBody={\n <div className={cl(\"body\")}>\n {data.body}\n <Timestamp timestamp={moment(data.timestamp)} className={cl(\"timestamp\")} />\n </div>\n }\n />\n </div>\n );\n}\n\nexport function NotificationLog({ log, pending }: { log: PersistentNotificationData[], pending: boolean; }) {\n if (!log.length && !pending)\n return (\n <div className={cl(\"container\")}>\n <div className={cl(\"empty\")} />\n <Forms.FormText style={{ textAlign: \"center\" }}>\n No notifications yet\n </Forms.FormText>\n </div>\n );\n\n return (\n <div className={cl(\"container\")}>\n {log.map(n => <NotificationEntry data={n} key={n.id} />)}\n </div>\n );\n}\n\nfunction LogModal({ modalProps, close }: { modalProps: ModalProps; close(): void; }) {\n const [log, pending] = useLogs();\n\n return (\n <ModalRoot {...modalProps} size={ModalSize.LARGE}>\n <ModalHeader>\n <Text variant=\"heading-lg/semibold\" style={{ flexGrow: 1 }}>Notification Log</Text>\n <ModalCloseButton onClick={close} />\n </ModalHeader>\n\n <ModalContent>\n <NotificationLog log={log} pending={pending} />\n </ModalContent>\n\n <ModalFooter>\n <Button\n disabled={log.length === 0}\n onClick={() => {\n Alerts.show({\n title: \"Are you sure?\",\n body: `This will permanently remove ${log.length} notification${log.length === 1 ? \"\" : \"s\"}. This action cannot be undone.`,\n async onConfirm() {\n await DataStore.set(KEY, []);\n signals.forEach(x => x());\n },\n confirmText: \"Do it!\",\n confirmColor: \"vc-notification-log-danger-btn\",\n cancelText: \"Nevermind\"\n });\n }}\n >\n Clear Notification Log\n </Button>\n </ModalFooter>\n </ModalRoot>\n );\n}\n\nexport function openNotificationLogModal() {\n const key = openModal(modalProps => (\n <LogModal\n modalProps={modalProps}\n close={() => closeModal(key)}\n />\n ));\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Settings } from \"@api/Settings\";\nimport { Queue } from \"@utils/Queue\";\nimport { ReactDOM } from \"@webpack/common\";\nimport type { ReactNode } from \"react\";\nimport type { Root } from \"react-dom/client\";\n\nimport NotificationComponent from \"./NotificationComponent\";\nimport { persistNotification } from \"./notificationLog\";\n\nconst NotificationQueue = new Queue();\n\nlet reactRoot: Root;\nlet id = 42;\n\nfunction getRoot() {\n if (!reactRoot) {\n const container = document.createElement(\"div\");\n container.id = \"vc-notification-container\";\n document.body.append(container);\n reactRoot = ReactDOM.createRoot(container);\n }\n return reactRoot;\n}\n\nexport interface NotificationData {\n title: string;\n body: string;\n /**\n * Same as body but can be a custom component.\n * Will be used over body if present.\n * Not supported on desktop notifications, those will fall back to body */\n richBody?: ReactNode;\n /** Small icon. This is for things like profile pictures and should be square */\n icon?: string;\n /** Large image. Optimally, this should be around 16x9 but it doesn't matter much. Desktop Notifications might not support this */\n image?: string;\n onClick?(): void;\n onClose?(): void;\n color?: string;\n /** Whether this notification should not have a timeout */\n permanent?: boolean;\n /** Whether this notification should not be persisted in the Notification Log */\n noPersist?: boolean;\n /** Whether this notification should be dismissed when clicked (defaults to true) */\n dismissOnClick?: boolean;\n}\n\nfunction _showNotification(notification: NotificationData, id: number) {\n const root = getRoot();\n return new Promise<void>(resolve => {\n root.render(\n <NotificationComponent key={id} {...notification} onClose={() => {\n notification.onClose?.();\n root.render(null);\n resolve();\n }} />,\n );\n });\n}\n\nfunction shouldBeNative() {\n if (typeof Notification === \"undefined\") return false;\n\n const { useNative } = Settings.notifications;\n if (useNative === \"always\") return true;\n if (useNative === \"not-focused\") return !document.hasFocus();\n return false;\n}\n\nexport async function requestPermission() {\n return (\n Notification.permission === \"granted\" ||\n (Notification.permission !== \"denied\" && (await Notification.requestPermission()) === \"granted\")\n );\n}\n\nexport async function showNotification(data: NotificationData) {\n persistNotification(data);\n\n if (shouldBeNative() && await requestPermission()) {\n const { title, body, icon, image, onClick = null, onClose = null } = data;\n const n = new Notification(title, {\n body,\n icon,\n image\n });\n n.onclick = onClick;\n n.onclose = onClose;\n } else {\n NotificationQueue.push(() => _showNotification(data, id++));\n }\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nexport * from \"./Notifications\";\n", "// DEFLATE is a complex format; to read this code, you should probably check the RFC first:\n// https://tools.ietf.org/html/rfc1951\n// You may also wish to take a look at the guide I made about this program:\n// https://gist.github.com/101arrowz/253f31eb5abc3d9275ab943003ffecad\n// Some of the following code is similar to that of UZIP.js:\n// https://github.com/photopea/UZIP.js\n// However, the vast majority of the codebase has diverged from UZIP.js to increase performance and reduce bundle size.\n// Sometimes 0 will appear where -1 would be more appropriate. This is because using a uint\n// is better for memory in most engines (I *think*).\nvar ch2 = {};\nvar wk = (function (c, id, msg, transfer, cb) {\n var w = new Worker(ch2[id] || (ch2[id] = URL.createObjectURL(new Blob([\n c + ';addEventListener(\"error\",function(e){e=e.error;postMessage({$e$:[e.message,e.code,e.stack]})})'\n ], { type: 'text/javascript' }))));\n w.onmessage = function (e) {\n var d = e.data, ed = d.$e$;\n if (ed) {\n var err = new Error(ed[0]);\n err['code'] = ed[1];\n err.stack = ed[2];\n cb(err, null);\n }\n else\n cb(null, d);\n };\n w.postMessage(msg, transfer);\n return w;\n});\n\n// aliases for shorter compressed code (most minifers don't do this)\nvar u8 = Uint8Array, u16 = Uint16Array, u32 = Uint32Array;\n// fixed length extra bits\nvar fleb = new u8([0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, /* unused */ 0, 0, /* impossible */ 0]);\n// fixed distance extra bits\n// see fleb note\nvar fdeb = new u8([0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, /* unused */ 0, 0]);\n// code length index map\nvar clim = new u8([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]);\n// get base, reverse index map from extra bits\nvar freb = function (eb, start) {\n var b = new u16(31);\n for (var i = 0; i < 31; ++i) {\n b[i] = start += 1 << eb[i - 1];\n }\n // numbers here are at max 18 bits\n var r = new u32(b[30]);\n for (var i = 1; i < 30; ++i) {\n for (var j = b[i]; j < b[i + 1]; ++j) {\n r[j] = ((j - b[i]) << 5) | i;\n }\n }\n return [b, r];\n};\nvar _a = freb(fleb, 2), fl = _a[0], revfl = _a[1];\n// we can ignore the fact that the other numbers are wrong; they never happen anyway\nfl[28] = 258, revfl[258] = 28;\nvar _b = freb(fdeb, 0), fd = _b[0], revfd = _b[1];\n// map of value to reverse (assuming 16 bits)\nvar rev = new u16(32768);\nfor (var i = 0; i < 32768; ++i) {\n // reverse table algorithm from SO\n var x = ((i & 0xAAAA) >>> 1) | ((i & 0x5555) << 1);\n x = ((x & 0xCCCC) >>> 2) | ((x & 0x3333) << 2);\n x = ((x & 0xF0F0) >>> 4) | ((x & 0x0F0F) << 4);\n rev[i] = (((x & 0xFF00) >>> 8) | ((x & 0x00FF) << 8)) >>> 1;\n}\n// create huffman tree from u8 \"map\": index -> code length for code index\n// mb (max bits) must be at most 15\n// TODO: optimize/split up?\nvar hMap = (function (cd, mb, r) {\n var s = cd.length;\n // index\n var i = 0;\n // u16 \"map\": index -> # of codes with bit length = index\n var l = new u16(mb);\n // length of cd must be 288 (total # of codes)\n for (; i < s; ++i) {\n if (cd[i])\n ++l[cd[i] - 1];\n }\n // u16 \"map\": index -> minimum code for bit length = index\n var le = new u16(mb);\n for (i = 0; i < mb; ++i) {\n le[i] = (le[i - 1] + l[i - 1]) << 1;\n }\n var co;\n if (r) {\n // u16 \"map\": index -> number of actual bits, symbol for code\n co = new u16(1 << mb);\n // bits to remove for reverser\n var rvb = 15 - mb;\n for (i = 0; i < s; ++i) {\n // ignore 0 lengths\n if (cd[i]) {\n // num encoding both symbol and bits read\n var sv = (i << 4) | cd[i];\n // free bits\n var r_1 = mb - cd[i];\n // start value\n var v = le[cd[i] - 1]++ << r_1;\n // m is end value\n for (var m = v | ((1 << r_1) - 1); v <= m; ++v) {\n // every 16 bit value starting with the code yields the same result\n co[rev[v] >>> rvb] = sv;\n }\n }\n }\n }\n else {\n co = new u16(s);\n for (i = 0; i < s; ++i) {\n if (cd[i]) {\n co[i] = rev[le[cd[i] - 1]++] >>> (15 - cd[i]);\n }\n }\n }\n return co;\n});\n// fixed length tree\nvar flt = new u8(288);\nfor (var i = 0; i < 144; ++i)\n flt[i] = 8;\nfor (var i = 144; i < 256; ++i)\n flt[i] = 9;\nfor (var i = 256; i < 280; ++i)\n flt[i] = 7;\nfor (var i = 280; i < 288; ++i)\n flt[i] = 8;\n// fixed distance tree\nvar fdt = new u8(32);\nfor (var i = 0; i < 32; ++i)\n fdt[i] = 5;\n// fixed length map\nvar flm = /*#__PURE__*/ hMap(flt, 9, 0), flrm = /*#__PURE__*/ hMap(flt, 9, 1);\n// fixed distance map\nvar fdm = /*#__PURE__*/ hMap(fdt, 5, 0), fdrm = /*#__PURE__*/ hMap(fdt, 5, 1);\n// find max of array\nvar max = function (a) {\n var m = a[0];\n for (var i = 1; i < a.length; ++i) {\n if (a[i] > m)\n m = a[i];\n }\n return m;\n};\n// read d, starting at bit p and mask with m\nvar bits = function (d, p, m) {\n var o = (p / 8) | 0;\n return ((d[o] | (d[o + 1] << 8)) >> (p & 7)) & m;\n};\n// read d, starting at bit p continuing for at least 16 bits\nvar bits16 = function (d, p) {\n var o = (p / 8) | 0;\n return ((d[o] | (d[o + 1] << 8) | (d[o + 2] << 16)) >> (p & 7));\n};\n// get end of byte\nvar shft = function (p) { return ((p + 7) / 8) | 0; };\n// typed array slice - allows garbage collector to free original reference,\n// while being more compatible than .slice\nvar slc = function (v, s, e) {\n if (s == null || s < 0)\n s = 0;\n if (e == null || e > v.length)\n e = v.length;\n // can't use .constructor in case user-supplied\n var n = new (v.BYTES_PER_ELEMENT == 2 ? u16 : v.BYTES_PER_ELEMENT == 4 ? u32 : u8)(e - s);\n n.set(v.subarray(s, e));\n return n;\n};\n/**\n * Codes for errors generated within this library\n */\nexport var FlateErrorCode = {\n UnexpectedEOF: 0,\n InvalidBlockType: 1,\n InvalidLengthLiteral: 2,\n InvalidDistance: 3,\n StreamFinished: 4,\n NoStreamHandler: 5,\n InvalidHeader: 6,\n NoCallback: 7,\n InvalidUTF8: 8,\n ExtraFieldTooLong: 9,\n InvalidDate: 10,\n FilenameTooLong: 11,\n StreamFinishing: 12,\n InvalidZipData: 13,\n UnknownCompressionMethod: 14\n};\n// error codes\nvar ec = [\n 'unexpected EOF',\n 'invalid block type',\n 'invalid length/literal',\n 'invalid distance',\n 'stream finished',\n 'no stream handler',\n ,\n 'no callback',\n 'invalid UTF-8 data',\n 'extra field too long',\n 'date not in range 1980-2099',\n 'filename too long',\n 'stream finishing',\n 'invalid zip data'\n // determined by unknown compression method\n];\n;\nvar err = function (ind, msg, nt) {\n var e = new Error(msg || ec[ind]);\n e.code = ind;\n if (Error.captureStackTrace)\n Error.captureStackTrace(e, err);\n if (!nt)\n throw e;\n return e;\n};\n// expands raw DEFLATE data\nvar inflt = function (dat, buf, st) {\n // source length\n var sl = dat.length;\n if (!sl || (st && st.f && !st.l))\n return buf || new u8(0);\n // have to estimate size\n var noBuf = !buf || st;\n // no state\n var noSt = !st || st.i;\n if (!st)\n st = {};\n // Assumes roughly 33% compression ratio average\n if (!buf)\n buf = new u8(sl * 3);\n // ensure buffer can fit at least l elements\n var cbuf = function (l) {\n var bl = buf.length;\n // need to increase size to fit\n if (l > bl) {\n // Double or set to necessary, whichever is greater\n var nbuf = new u8(Math.max(bl * 2, l));\n nbuf.set(buf);\n buf = nbuf;\n }\n };\n // last chunk bitpos bytes\n var final = st.f || 0, pos = st.p || 0, bt = st.b || 0, lm = st.l, dm = st.d, lbt = st.m, dbt = st.n;\n // total bits\n var tbts = sl * 8;\n do {\n if (!lm) {\n // BFINAL - this is only 1 when last chunk is next\n final = bits(dat, pos, 1);\n // type: 0 = no compression, 1 = fixed huffman, 2 = dynamic huffman\n var type = bits(dat, pos + 1, 3);\n pos += 3;\n if (!type) {\n // go to end of byte boundary\n var s = shft(pos) + 4, l = dat[s - 4] | (dat[s - 3] << 8), t = s + l;\n if (t > sl) {\n if (noSt)\n err(0);\n break;\n }\n // ensure size\n if (noBuf)\n cbuf(bt + l);\n // Copy over uncompressed data\n buf.set(dat.subarray(s, t), bt);\n // Get new bitpos, update byte count\n st.b = bt += l, st.p = pos = t * 8, st.f = final;\n continue;\n }\n else if (type == 1)\n lm = flrm, dm = fdrm, lbt = 9, dbt = 5;\n else if (type == 2) {\n // literal lengths\n var hLit = bits(dat, pos, 31) + 257, hcLen = bits(dat, pos + 10, 15) + 4;\n var tl = hLit + bits(dat, pos + 5, 31) + 1;\n pos += 14;\n // length+distance tree\n var ldt = new u8(tl);\n // code length tree\n var clt = new u8(19);\n for (var i = 0; i < hcLen; ++i) {\n // use index map to get real code\n clt[clim[i]] = bits(dat, pos + i * 3, 7);\n }\n pos += hcLen * 3;\n // code lengths bits\n var clb = max(clt), clbmsk = (1 << clb) - 1;\n // code lengths map\n var clm = hMap(clt, clb, 1);\n for (var i = 0; i < tl;) {\n var r = clm[bits(dat, pos, clbmsk)];\n // bits read\n pos += r & 15;\n // symbol\n var s = r >>> 4;\n // code length to copy\n if (s < 16) {\n ldt[i++] = s;\n }\n else {\n // copy count\n var c = 0, n = 0;\n if (s == 16)\n n = 3 + bits(dat, pos, 3), pos += 2, c = ldt[i - 1];\n else if (s == 17)\n n = 3 + bits(dat, pos, 7), pos += 3;\n else if (s == 18)\n n = 11 + bits(dat, pos, 127), pos += 7;\n while (n--)\n ldt[i++] = c;\n }\n }\n // length tree distance tree\n var lt = ldt.subarray(0, hLit), dt = ldt.subarray(hLit);\n // max length bits\n lbt = max(lt);\n // max dist bits\n dbt = max(dt);\n lm = hMap(lt, lbt, 1);\n dm = hMap(dt, dbt, 1);\n }\n else\n err(1);\n if (pos > tbts) {\n if (noSt)\n err(0);\n break;\n }\n }\n // Make sure the buffer can hold this + the largest possible addition\n // Maximum chunk size (practically, theoretically infinite) is 2^17;\n if (noBuf)\n cbuf(bt + 131072);\n var lms = (1 << lbt) - 1, dms = (1 << dbt) - 1;\n var lpos = pos;\n for (;; lpos = pos) {\n // bits read, code\n var c = lm[bits16(dat, pos) & lms], sym = c >>> 4;\n pos += c & 15;\n if (pos > tbts) {\n if (noSt)\n err(0);\n break;\n }\n if (!c)\n err(2);\n if (sym < 256)\n buf[bt++] = sym;\n else if (sym == 256) {\n lpos = pos, lm = null;\n break;\n }\n else {\n var add = sym - 254;\n // no extra bits needed if less\n if (sym > 264) {\n // index\n var i = sym - 257, b = fleb[i];\n add = bits(dat, pos, (1 << b) - 1) + fl[i];\n pos += b;\n }\n // dist\n var d = dm[bits16(dat, pos) & dms], dsym = d >>> 4;\n if (!d)\n err(3);\n pos += d & 15;\n var dt = fd[dsym];\n if (dsym > 3) {\n var b = fdeb[dsym];\n dt += bits16(dat, pos) & ((1 << b) - 1), pos += b;\n }\n if (pos > tbts) {\n if (noSt)\n err(0);\n break;\n }\n if (noBuf)\n cbuf(bt + 131072);\n var end = bt + add;\n for (; bt < end; bt += 4) {\n buf[bt] = buf[bt - dt];\n buf[bt + 1] = buf[bt + 1 - dt];\n buf[bt + 2] = buf[bt + 2 - dt];\n buf[bt + 3] = buf[bt + 3 - dt];\n }\n bt = end;\n }\n }\n st.l = lm, st.p = lpos, st.b = bt, st.f = final;\n if (lm)\n final = 1, st.m = lbt, st.d = dm, st.n = dbt;\n } while (!final);\n return bt == buf.length ? buf : slc(buf, 0, bt);\n};\n// starting at p, write the minimum number of bits that can hold v to d\nvar wbits = function (d, p, v) {\n v <<= p & 7;\n var o = (p / 8) | 0;\n d[o] |= v;\n d[o + 1] |= v >>> 8;\n};\n// starting at p, write the minimum number of bits (>8) that can hold v to d\nvar wbits16 = function (d, p, v) {\n v <<= p & 7;\n var o = (p / 8) | 0;\n d[o] |= v;\n d[o + 1] |= v >>> 8;\n d[o + 2] |= v >>> 16;\n};\n// creates code lengths from a frequency table\nvar hTree = function (d, mb) {\n // Need extra info to make a tree\n var t = [];\n for (var i = 0; i < d.length; ++i) {\n if (d[i])\n t.push({ s: i, f: d[i] });\n }\n var s = t.length;\n var t2 = t.slice();\n if (!s)\n return [et, 0];\n if (s == 1) {\n var v = new u8(t[0].s + 1);\n v[t[0].s] = 1;\n return [v, 1];\n }\n t.sort(function (a, b) { return a.f - b.f; });\n // after i2 reaches last ind, will be stopped\n // freq must be greater than largest possible number of symbols\n t.push({ s: -1, f: 25001 });\n var l = t[0], r = t[1], i0 = 0, i1 = 1, i2 = 2;\n t[0] = { s: -1, f: l.f + r.f, l: l, r: r };\n // efficient algorithm from UZIP.js\n // i0 is lookbehind, i2 is lookahead - after processing two low-freq\n // symbols that combined have high freq, will start processing i2 (high-freq,\n // non-composite) symbols instead\n // see https://reddit.com/r/photopea/comments/ikekht/uzipjs_questions/\n while (i1 != s - 1) {\n l = t[t[i0].f < t[i2].f ? i0++ : i2++];\n r = t[i0 != i1 && t[i0].f < t[i2].f ? i0++ : i2++];\n t[i1++] = { s: -1, f: l.f + r.f, l: l, r: r };\n }\n var maxSym = t2[0].s;\n for (var i = 1; i < s; ++i) {\n if (t2[i].s > maxSym)\n maxSym = t2[i].s;\n }\n // code lengths\n var tr = new u16(maxSym + 1);\n // max bits in tree\n var mbt = ln(t[i1 - 1], tr, 0);\n if (mbt > mb) {\n // more algorithms from UZIP.js\n // TODO: find out how this code works (debt)\n // ind debt\n var i = 0, dt = 0;\n // left cost\n var lft = mbt - mb, cst = 1 << lft;\n t2.sort(function (a, b) { return tr[b.s] - tr[a.s] || a.f - b.f; });\n for (; i < s; ++i) {\n var i2_1 = t2[i].s;\n if (tr[i2_1] > mb) {\n dt += cst - (1 << (mbt - tr[i2_1]));\n tr[i2_1] = mb;\n }\n else\n break;\n }\n dt >>>= lft;\n while (dt > 0) {\n var i2_2 = t2[i].s;\n if (tr[i2_2] < mb)\n dt -= 1 << (mb - tr[i2_2]++ - 1);\n else\n ++i;\n }\n for (; i >= 0 && dt; --i) {\n var i2_3 = t2[i].s;\n if (tr[i2_3] == mb) {\n --tr[i2_3];\n ++dt;\n }\n }\n mbt = mb;\n }\n return [new u8(tr), mbt];\n};\n// get the max length and assign length codes\nvar ln = function (n, l, d) {\n return n.s == -1\n ? Math.max(ln(n.l, l, d + 1), ln(n.r, l, d + 1))\n : (l[n.s] = d);\n};\n// length codes generation\nvar lc = function (c) {\n var s = c.length;\n // Note that the semicolon was intentional\n while (s && !c[--s])\n ;\n var cl = new u16(++s);\n // ind num streak\n var cli = 0, cln = c[0], cls = 1;\n var w = function (v) { cl[cli++] = v; };\n for (var i = 1; i <= s; ++i) {\n if (c[i] == cln && i != s)\n ++cls;\n else {\n if (!cln && cls > 2) {\n for (; cls > 138; cls -= 138)\n w(32754);\n if (cls > 2) {\n w(cls > 10 ? ((cls - 11) << 5) | 28690 : ((cls - 3) << 5) | 12305);\n cls = 0;\n }\n }\n else if (cls > 3) {\n w(cln), --cls;\n for (; cls > 6; cls -= 6)\n w(8304);\n if (cls > 2)\n w(((cls - 3) << 5) | 8208), cls = 0;\n }\n while (cls--)\n w(cln);\n cls = 1;\n cln = c[i];\n }\n }\n return [cl.subarray(0, cli), s];\n};\n// calculate the length of output from tree, code lengths\nvar clen = function (cf, cl) {\n var l = 0;\n for (var i = 0; i < cl.length; ++i)\n l += cf[i] * cl[i];\n return l;\n};\n// writes a fixed block\n// returns the new bit pos\nvar wfblk = function (out, pos, dat) {\n // no need to write 00 as type: TypedArray defaults to 0\n var s = dat.length;\n var o = shft(pos + 2);\n out[o] = s & 255;\n out[o + 1] = s >>> 8;\n out[o + 2] = out[o] ^ 255;\n out[o + 3] = out[o + 1] ^ 255;\n for (var i = 0; i < s; ++i)\n out[o + i + 4] = dat[i];\n return (o + 4 + s) * 8;\n};\n// writes a block\nvar wblk = function (dat, out, final, syms, lf, df, eb, li, bs, bl, p) {\n wbits(out, p++, final);\n ++lf[256];\n var _a = hTree(lf, 15), dlt = _a[0], mlb = _a[1];\n var _b = hTree(df, 15), ddt = _b[0], mdb = _b[1];\n var _c = lc(dlt), lclt = _c[0], nlc = _c[1];\n var _d = lc(ddt), lcdt = _d[0], ndc = _d[1];\n var lcfreq = new u16(19);\n for (var i = 0; i < lclt.length; ++i)\n lcfreq[lclt[i] & 31]++;\n for (var i = 0; i < lcdt.length; ++i)\n lcfreq[lcdt[i] & 31]++;\n var _e = hTree(lcfreq, 7), lct = _e[0], mlcb = _e[1];\n var nlcc = 19;\n for (; nlcc > 4 && !lct[clim[nlcc - 1]]; --nlcc)\n ;\n var flen = (bl + 5) << 3;\n var ftlen = clen(lf, flt) + clen(df, fdt) + eb;\n var dtlen = clen(lf, dlt) + clen(df, ddt) + eb + 14 + 3 * nlcc + clen(lcfreq, lct) + (2 * lcfreq[16] + 3 * lcfreq[17] + 7 * lcfreq[18]);\n if (flen <= ftlen && flen <= dtlen)\n return wfblk(out, p, dat.subarray(bs, bs + bl));\n var lm, ll, dm, dl;\n wbits(out, p, 1 + (dtlen < ftlen)), p += 2;\n if (dtlen < ftlen) {\n lm = hMap(dlt, mlb, 0), ll = dlt, dm = hMap(ddt, mdb, 0), dl = ddt;\n var llm = hMap(lct, mlcb, 0);\n wbits(out, p, nlc - 257);\n wbits(out, p + 5, ndc - 1);\n wbits(out, p + 10, nlcc - 4);\n p += 14;\n for (var i = 0; i < nlcc; ++i)\n wbits(out, p + 3 * i, lct[clim[i]]);\n p += 3 * nlcc;\n var lcts = [lclt, lcdt];\n for (var it = 0; it < 2; ++it) {\n var clct = lcts[it];\n for (var i = 0; i < clct.length; ++i) {\n var len = clct[i] & 31;\n wbits(out, p, llm[len]), p += lct[len];\n if (len > 15)\n wbits(out, p, (clct[i] >>> 5) & 127), p += clct[i] >>> 12;\n }\n }\n }\n else {\n lm = flm, ll = flt, dm = fdm, dl = fdt;\n }\n for (var i = 0; i < li; ++i) {\n if (syms[i] > 255) {\n var len = (syms[i] >>> 18) & 31;\n wbits16(out, p, lm[len + 257]), p += ll[len + 257];\n if (len > 7)\n wbits(out, p, (syms[i] >>> 23) & 31), p += fleb[len];\n var dst = syms[i] & 31;\n wbits16(out, p, dm[dst]), p += dl[dst];\n if (dst > 3)\n wbits16(out, p, (syms[i] >>> 5) & 8191), p += fdeb[dst];\n }\n else {\n wbits16(out, p, lm[syms[i]]), p += ll[syms[i]];\n }\n }\n wbits16(out, p, lm[256]);\n return p + ll[256];\n};\n// deflate options (nice << 13) | chain\nvar deo = /*#__PURE__*/ new u32([65540, 131080, 131088, 131104, 262176, 1048704, 1048832, 2114560, 2117632]);\n// empty\nvar et = /*#__PURE__*/ new u8(0);\n// compresses data into a raw DEFLATE buffer\nvar dflt = function (dat, lvl, plvl, pre, post, lst) {\n var s = dat.length;\n var o = new u8(pre + s + 5 * (1 + Math.ceil(s / 7000)) + post);\n // writing to this writes to the output buffer\n var w = o.subarray(pre, o.length - post);\n var pos = 0;\n if (!lvl || s < 8) {\n for (var i = 0; i <= s; i += 65535) {\n // end\n var e = i + 65535;\n if (e >= s) {\n // write final block\n w[pos >> 3] = lst;\n }\n pos = wfblk(w, pos + 1, dat.subarray(i, e));\n }\n }\n else {\n var opt = deo[lvl - 1];\n var n = opt >>> 13, c = opt & 8191;\n var msk_1 = (1 << plvl) - 1;\n // prev 2-byte val map curr 2-byte val map\n var prev = new u16(32768), head = new u16(msk_1 + 1);\n var bs1_1 = Math.ceil(plvl / 3), bs2_1 = 2 * bs1_1;\n var hsh = function (i) { return (dat[i] ^ (dat[i + 1] << bs1_1) ^ (dat[i + 2] << bs2_1)) & msk_1; };\n // 24576 is an arbitrary number of maximum symbols per block\n // 424 buffer for last block\n var syms = new u32(25000);\n // length/literal freq distance freq\n var lf = new u16(288), df = new u16(32);\n // l/lcnt exbits index l/lind waitdx bitpos\n var lc_1 = 0, eb = 0, i = 0, li = 0, wi = 0, bs = 0;\n for (; i < s; ++i) {\n // hash value\n // deopt when i > s - 3 - at end, deopt acceptable\n var hv = hsh(i);\n // index mod 32768 previous index mod\n var imod = i & 32767, pimod = head[hv];\n prev[imod] = pimod;\n head[hv] = imod;\n // We always should modify head and prev, but only add symbols if\n // this data is not yet processed (\"wait\" for wait index)\n if (wi <= i) {\n // bytes remaining\n var rem = s - i;\n if ((lc_1 > 7000 || li > 24576) && rem > 423) {\n pos = wblk(dat, w, 0, syms, lf, df, eb, li, bs, i - bs, pos);\n li = lc_1 = eb = 0, bs = i;\n for (var j = 0; j < 286; ++j)\n lf[j] = 0;\n for (var j = 0; j < 30; ++j)\n df[j] = 0;\n }\n // len dist chain\n var l = 2, d = 0, ch_1 = c, dif = (imod - pimod) & 32767;\n if (rem > 2 && hv == hsh(i - dif)) {\n var maxn = Math.min(n, rem) - 1;\n var maxd = Math.min(32767, i);\n // max possible length\n // not capped at dif because decompressors implement \"rolling\" index population\n var ml = Math.min(258, rem);\n while (dif <= maxd && --ch_1 && imod != pimod) {\n if (dat[i + l] == dat[i + l - dif]) {\n var nl = 0;\n for (; nl < ml && dat[i + nl] == dat[i + nl - dif]; ++nl)\n ;\n if (nl > l) {\n l = nl, d = dif;\n // break out early when we reach \"nice\" (we are satisfied enough)\n if (nl > maxn)\n break;\n // now, find the rarest 2-byte sequence within this\n // length of literals and search for that instead.\n // Much faster than just using the start\n var mmd = Math.min(dif, nl - 2);\n var md = 0;\n for (var j = 0; j < mmd; ++j) {\n var ti = (i - dif + j + 32768) & 32767;\n var pti = prev[ti];\n var cd = (ti - pti + 32768) & 32767;\n if (cd > md)\n md = cd, pimod = ti;\n }\n }\n }\n // check the previous match\n imod = pimod, pimod = prev[imod];\n dif += (imod - pimod + 32768) & 32767;\n }\n }\n // d will be nonzero only when a match was found\n if (d) {\n // store both dist and len data in one Uint32\n // Make sure this is recognized as a len/dist with 28th bit (2^28)\n syms[li++] = 268435456 | (revfl[l] << 18) | revfd[d];\n var lin = revfl[l] & 31, din = revfd[d] & 31;\n eb += fleb[lin] + fdeb[din];\n ++lf[257 + lin];\n ++df[din];\n wi = i + l;\n ++lc_1;\n }\n else {\n syms[li++] = dat[i];\n ++lf[dat[i]];\n }\n }\n }\n pos = wblk(dat, w, lst, syms, lf, df, eb, li, bs, i - bs, pos);\n // this is the easiest way to avoid needing to maintain state\n if (!lst && pos & 7)\n pos = wfblk(w, pos + 1, et);\n }\n return slc(o, 0, pre + shft(pos) + post);\n};\n// CRC32 table\nvar crct = /*#__PURE__*/ (function () {\n var t = new Int32Array(256);\n for (var i = 0; i < 256; ++i) {\n var c = i, k = 9;\n while (--k)\n c = ((c & 1) && -306674912) ^ (c >>> 1);\n t[i] = c;\n }\n return t;\n})();\n// CRC32\nvar crc = function () {\n var c = -1;\n return {\n p: function (d) {\n // closures have awful performance\n var cr = c;\n for (var i = 0; i < d.length; ++i)\n cr = crct[(cr & 255) ^ d[i]] ^ (cr >>> 8);\n c = cr;\n },\n d: function () { return ~c; }\n };\n};\n// Alder32\nvar adler = function () {\n var a = 1, b = 0;\n return {\n p: function (d) {\n // closures have awful performance\n var n = a, m = b;\n var l = d.length | 0;\n for (var i = 0; i != l;) {\n var e = Math.min(i + 2655, l);\n for (; i < e; ++i)\n m += n += d[i];\n n = (n & 65535) + 15 * (n >> 16), m = (m & 65535) + 15 * (m >> 16);\n }\n a = n, b = m;\n },\n d: function () {\n a %= 65521, b %= 65521;\n return (a & 255) << 24 | (a >>> 8) << 16 | (b & 255) << 8 | (b >>> 8);\n }\n };\n};\n;\n// deflate with opts\nvar dopt = function (dat, opt, pre, post, st) {\n return dflt(dat, opt.level == null ? 6 : opt.level, opt.mem == null ? Math.ceil(Math.max(8, Math.min(13, Math.log(dat.length))) * 1.5) : (12 + opt.mem), pre, post, !st);\n};\n// Walmart object spread\nvar mrg = function (a, b) {\n var o = {};\n for (var k in a)\n o[k] = a[k];\n for (var k in b)\n o[k] = b[k];\n return o;\n};\n// worker clone\n// This is possibly the craziest part of the entire codebase, despite how simple it may seem.\n// The only parameter to this function is a closure that returns an array of variables outside of the function scope.\n// We're going to try to figure out the variable names used in the closure as strings because that is crucial for workerization.\n// We will return an object mapping of true variable name to value (basically, the current scope as a JS object).\n// The reason we can't just use the original variable names is minifiers mangling the toplevel scope.\n// This took me three weeks to figure out how to do.\nvar wcln = function (fn, fnStr, td) {\n var dt = fn();\n var st = fn.toString();\n var ks = st.slice(st.indexOf('[') + 1, st.lastIndexOf(']')).replace(/\\s+/g, '').split(',');\n for (var i = 0; i < dt.length; ++i) {\n var v = dt[i], k = ks[i];\n if (typeof v == 'function') {\n fnStr += ';' + k + '=';\n var st_1 = v.toString();\n if (v.prototype) {\n // for global objects\n if (st_1.indexOf('[native code]') != -1) {\n var spInd = st_1.indexOf(' ', 8) + 1;\n fnStr += st_1.slice(spInd, st_1.indexOf('(', spInd));\n }\n else {\n fnStr += st_1;\n for (var t in v.prototype)\n fnStr += ';' + k + '.prototype.' + t + '=' + v.prototype[t].toString();\n }\n }\n else\n fnStr += st_1;\n }\n else\n td[k] = v;\n }\n return [fnStr, td];\n};\nvar ch = [];\n// clone bufs\nvar cbfs = function (v) {\n var tl = [];\n for (var k in v) {\n if (v[k].buffer) {\n tl.push((v[k] = new v[k].constructor(v[k])).buffer);\n }\n }\n return tl;\n};\n// use a worker to execute code\nvar wrkr = function (fns, init, id, cb) {\n var _a;\n if (!ch[id]) {\n var fnStr = '', td_1 = {}, m = fns.length - 1;\n for (var i = 0; i < m; ++i)\n _a = wcln(fns[i], fnStr, td_1), fnStr = _a[0], td_1 = _a[1];\n ch[id] = wcln(fns[m], fnStr, td_1);\n }\n var td = mrg({}, ch[id][1]);\n return wk(ch[id][0] + ';onmessage=function(e){for(var k in e.data)self[k]=e.data[k];onmessage=' + init.toString() + '}', id, td, cbfs(td), cb);\n};\n// base async inflate fn\nvar bInflt = function () { return [u8, u16, u32, fleb, fdeb, clim, fl, fd, flrm, fdrm, rev, ec, hMap, max, bits, bits16, shft, slc, err, inflt, inflateSync, pbf, gu8]; };\nvar bDflt = function () { return [u8, u16, u32, fleb, fdeb, clim, revfl, revfd, flm, flt, fdm, fdt, rev, deo, et, hMap, wbits, wbits16, hTree, ln, lc, clen, wfblk, wblk, shft, slc, dflt, dopt, deflateSync, pbf]; };\n// gzip extra\nvar gze = function () { return [gzh, gzhl, wbytes, crc, crct]; };\n// gunzip extra\nvar guze = function () { return [gzs, gzl]; };\n// zlib extra\nvar zle = function () { return [zlh, wbytes, adler]; };\n// unzlib extra\nvar zule = function () { return [zlv]; };\n// post buf\nvar pbf = function (msg) { return postMessage(msg, [msg.buffer]); };\n// get u8\nvar gu8 = function (o) { return o && o.size && new u8(o.size); };\n// async helper\nvar cbify = function (dat, opts, fns, init, id, cb) {\n var w = wrkr(fns, init, id, function (err, dat) {\n w.terminate();\n cb(err, dat);\n });\n w.postMessage([dat, opts], opts.consume ? [dat.buffer] : []);\n return function () { w.terminate(); };\n};\n// auto stream\nvar astrm = function (strm) {\n strm.ondata = function (dat, final) { return postMessage([dat, final], [dat.buffer]); };\n return function (ev) { return strm.push(ev.data[0], ev.data[1]); };\n};\n// async stream attach\nvar astrmify = function (fns, strm, opts, init, id) {\n var t;\n var w = wrkr(fns, init, id, function (err, dat) {\n if (err)\n w.terminate(), strm.ondata.call(strm, err);\n else {\n if (dat[1])\n w.terminate();\n strm.ondata.call(strm, err, dat[0], dat[1]);\n }\n });\n w.postMessage(opts);\n strm.push = function (d, f) {\n if (!strm.ondata)\n err(5);\n if (t)\n strm.ondata(err(4, 0, 1), null, !!f);\n w.postMessage([d, t = f], [d.buffer]);\n };\n strm.terminate = function () { w.terminate(); };\n};\n// read 2 bytes\nvar b2 = function (d, b) { return d[b] | (d[b + 1] << 8); };\n// read 4 bytes\nvar b4 = function (d, b) { return (d[b] | (d[b + 1] << 8) | (d[b + 2] << 16) | (d[b + 3] << 24)) >>> 0; };\nvar b8 = function (d, b) { return b4(d, b) + (b4(d, b + 4) * 4294967296); };\n// write bytes\nvar wbytes = function (d, b, v) {\n for (; v; ++b)\n d[b] = v, v >>>= 8;\n};\n// gzip header\nvar gzh = function (c, o) {\n var fn = o.filename;\n c[0] = 31, c[1] = 139, c[2] = 8, c[8] = o.level < 2 ? 4 : o.level == 9 ? 2 : 0, c[9] = 3; // assume Unix\n if (o.mtime != 0)\n wbytes(c, 4, Math.floor(new Date(o.mtime || Date.now()) / 1000));\n if (fn) {\n c[3] = 8;\n for (var i = 0; i <= fn.length; ++i)\n c[i + 10] = fn.charCodeAt(i);\n }\n};\n// gzip footer: -8 to -4 = CRC, -4 to -0 is length\n// gzip start\nvar gzs = function (d) {\n if (d[0] != 31 || d[1] != 139 || d[2] != 8)\n err(6, 'invalid gzip data');\n var flg = d[3];\n var st = 10;\n if (flg & 4)\n st += d[10] | (d[11] << 8) + 2;\n for (var zs = (flg >> 3 & 1) + (flg >> 4 & 1); zs > 0; zs -= !d[st++])\n ;\n return st + (flg & 2);\n};\n// gzip length\nvar gzl = function (d) {\n var l = d.length;\n return ((d[l - 4] | d[l - 3] << 8 | d[l - 2] << 16) | (d[l - 1] << 24)) >>> 0;\n};\n// gzip header length\nvar gzhl = function (o) { return 10 + ((o.filename && (o.filename.length + 1)) || 0); };\n// zlib header\nvar zlh = function (c, o) {\n var lv = o.level, fl = lv == 0 ? 0 : lv < 6 ? 1 : lv == 9 ? 3 : 2;\n c[0] = 120, c[1] = (fl << 6) | (fl ? (32 - 2 * fl) : 1);\n};\n// zlib valid\nvar zlv = function (d) {\n if ((d[0] & 15) != 8 || (d[0] >>> 4) > 7 || ((d[0] << 8 | d[1]) % 31))\n err(6, 'invalid zlib data');\n if (d[1] & 32)\n err(6, 'invalid zlib data: preset dictionaries not supported');\n};\nfunction AsyncCmpStrm(opts, cb) {\n if (!cb && typeof opts == 'function')\n cb = opts, opts = {};\n this.ondata = cb;\n return opts;\n}\n// zlib footer: -4 to -0 is Adler32\n/**\n * Streaming DEFLATE compression\n */\nvar Deflate = /*#__PURE__*/ (function () {\n function Deflate(opts, cb) {\n if (!cb && typeof opts == 'function')\n cb = opts, opts = {};\n this.ondata = cb;\n this.o = opts || {};\n }\n Deflate.prototype.p = function (c, f) {\n this.ondata(dopt(c, this.o, 0, 0, !f), f);\n };\n /**\n * Pushes a chunk to be deflated\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Deflate.prototype.push = function (chunk, final) {\n if (!this.ondata)\n err(5);\n if (this.d)\n err(4);\n this.d = final;\n this.p(chunk, final || false);\n };\n return Deflate;\n}());\nexport { Deflate };\n/**\n * Asynchronous streaming DEFLATE compression\n */\nvar AsyncDeflate = /*#__PURE__*/ (function () {\n function AsyncDeflate(opts, cb) {\n astrmify([\n bDflt,\n function () { return [astrm, Deflate]; }\n ], this, AsyncCmpStrm.call(this, opts, cb), function (ev) {\n var strm = new Deflate(ev.data);\n onmessage = astrm(strm);\n }, 6);\n }\n return AsyncDeflate;\n}());\nexport { AsyncDeflate };\nexport function deflate(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n err(7);\n return cbify(data, opts, [\n bDflt,\n ], function (ev) { return pbf(deflateSync(ev.data[0], ev.data[1])); }, 0, cb);\n}\n/**\n * Compresses data with DEFLATE without any wrapper\n * @param data The data to compress\n * @param opts The compression options\n * @returns The deflated version of the data\n */\nexport function deflateSync(data, opts) {\n return dopt(data, opts || {}, 0, 0);\n}\n/**\n * Streaming DEFLATE decompression\n */\nvar Inflate = /*#__PURE__*/ (function () {\n /**\n * Creates an inflation stream\n * @param cb The callback to call whenever data is inflated\n */\n function Inflate(cb) {\n this.s = {};\n this.p = new u8(0);\n this.ondata = cb;\n }\n Inflate.prototype.e = function (c) {\n if (!this.ondata)\n err(5);\n if (this.d)\n err(4);\n var l = this.p.length;\n var n = new u8(l + c.length);\n n.set(this.p), n.set(c, l), this.p = n;\n };\n Inflate.prototype.c = function (final) {\n this.d = this.s.i = final || false;\n var bts = this.s.b;\n var dt = inflt(this.p, this.o, this.s);\n this.ondata(slc(dt, bts, this.s.b), this.d);\n this.o = slc(dt, this.s.b - 32768), this.s.b = this.o.length;\n this.p = slc(this.p, (this.s.p / 8) | 0), this.s.p &= 7;\n };\n /**\n * Pushes a chunk to be inflated\n * @param chunk The chunk to push\n * @param final Whether this is the final chunk\n */\n Inflate.prototype.push = function (chunk, final) {\n this.e(chunk), this.c(final);\n };\n return Inflate;\n}());\nexport { Inflate };\n/**\n * Asynchronous streaming DEFLATE decompression\n */\nvar AsyncInflate = /*#__PURE__*/ (function () {\n /**\n * Creates an asynchronous inflation stream\n * @param cb The callback to call whenever data is deflated\n */\n function AsyncInflate(cb) {\n this.ondata = cb;\n astrmify([\n bInflt,\n function () { return [astrm, Inflate]; }\n ], this, 0, function () {\n var strm = new Inflate();\n onmessage = astrm(strm);\n }, 7);\n }\n return AsyncInflate;\n}());\nexport { AsyncInflate };\nexport function inflate(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n err(7);\n return cbify(data, opts, [\n bInflt\n ], function (ev) { return pbf(inflateSync(ev.data[0], gu8(ev.data[1]))); }, 1, cb);\n}\n/**\n * Expands DEFLATE data with no wrapper\n * @param data The data to decompress\n * @param out Where to write the data. Saves memory if you know the decompressed size and provide an output buffer of that length.\n * @returns The decompressed version of the data\n */\nexport function inflateSync(data, out) {\n return inflt(data, out);\n}\n// before you yell at me for not just using extends, my reason is that TS inheritance is hard to workerize.\n/**\n * Streaming GZIP compression\n */\nvar Gzip = /*#__PURE__*/ (function () {\n function Gzip(opts, cb) {\n this.c = crc();\n this.l = 0;\n this.v = 1;\n Deflate.call(this, opts, cb);\n }\n /**\n * Pushes a chunk to be GZIPped\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Gzip.prototype.push = function (chunk, final) {\n Deflate.prototype.push.call(this, chunk, final);\n };\n Gzip.prototype.p = function (c, f) {\n this.c.p(c);\n this.l += c.length;\n var raw = dopt(c, this.o, this.v && gzhl(this.o), f && 8, !f);\n if (this.v)\n gzh(raw, this.o), this.v = 0;\n if (f)\n wbytes(raw, raw.length - 8, this.c.d()), wbytes(raw, raw.length - 4, this.l);\n this.ondata(raw, f);\n };\n return Gzip;\n}());\nexport { Gzip };\n/**\n * Asynchronous streaming GZIP compression\n */\nvar AsyncGzip = /*#__PURE__*/ (function () {\n function AsyncGzip(opts, cb) {\n astrmify([\n bDflt,\n gze,\n function () { return [astrm, Deflate, Gzip]; }\n ], this, AsyncCmpStrm.call(this, opts, cb), function (ev) {\n var strm = new Gzip(ev.data);\n onmessage = astrm(strm);\n }, 8);\n }\n return AsyncGzip;\n}());\nexport { AsyncGzip };\nexport function gzip(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n err(7);\n return cbify(data, opts, [\n bDflt,\n gze,\n function () { return [gzipSync]; }\n ], function (ev) { return pbf(gzipSync(ev.data[0], ev.data[1])); }, 2, cb);\n}\n/**\n * Compresses data with GZIP\n * @param data The data to compress\n * @param opts The compression options\n * @returns The gzipped version of the data\n */\nexport function gzipSync(data, opts) {\n if (!opts)\n opts = {};\n var c = crc(), l = data.length;\n c.p(data);\n var d = dopt(data, opts, gzhl(opts), 8), s = d.length;\n return gzh(d, opts), wbytes(d, s - 8, c.d()), wbytes(d, s - 4, l), d;\n}\n/**\n * Streaming GZIP decompression\n */\nvar Gunzip = /*#__PURE__*/ (function () {\n /**\n * Creates a GUNZIP stream\n * @param cb The callback to call whenever data is inflated\n */\n function Gunzip(cb) {\n this.v = 1;\n Inflate.call(this, cb);\n }\n /**\n * Pushes a chunk to be GUNZIPped\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Gunzip.prototype.push = function (chunk, final) {\n Inflate.prototype.e.call(this, chunk);\n if (this.v) {\n var s = this.p.length > 3 ? gzs(this.p) : 4;\n if (s >= this.p.length && !final)\n return;\n this.p = this.p.subarray(s), this.v = 0;\n }\n if (final) {\n if (this.p.length < 8)\n err(6, 'invalid gzip data');\n this.p = this.p.subarray(0, -8);\n }\n // necessary to prevent TS from using the closure value\n // This allows for workerization to function correctly\n Inflate.prototype.c.call(this, final);\n };\n return Gunzip;\n}());\nexport { Gunzip };\n/**\n * Asynchronous streaming GZIP decompression\n */\nvar AsyncGunzip = /*#__PURE__*/ (function () {\n /**\n * Creates an asynchronous GUNZIP stream\n * @param cb The callback to call whenever data is deflated\n */\n function AsyncGunzip(cb) {\n this.ondata = cb;\n astrmify([\n bInflt,\n guze,\n function () { return [astrm, Inflate, Gunzip]; }\n ], this, 0, function () {\n var strm = new Gunzip();\n onmessage = astrm(strm);\n }, 9);\n }\n return AsyncGunzip;\n}());\nexport { AsyncGunzip };\nexport function gunzip(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n err(7);\n return cbify(data, opts, [\n bInflt,\n guze,\n function () { return [gunzipSync]; }\n ], function (ev) { return pbf(gunzipSync(ev.data[0])); }, 3, cb);\n}\n/**\n * Expands GZIP data\n * @param data The data to decompress\n * @param out Where to write the data. GZIP already encodes the output size, so providing this doesn't save memory.\n * @returns The decompressed version of the data\n */\nexport function gunzipSync(data, out) {\n return inflt(data.subarray(gzs(data), -8), out || new u8(gzl(data)));\n}\n/**\n * Streaming Zlib compression\n */\nvar Zlib = /*#__PURE__*/ (function () {\n function Zlib(opts, cb) {\n this.c = adler();\n this.v = 1;\n Deflate.call(this, opts, cb);\n }\n /**\n * Pushes a chunk to be zlibbed\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Zlib.prototype.push = function (chunk, final) {\n Deflate.prototype.push.call(this, chunk, final);\n };\n Zlib.prototype.p = function (c, f) {\n this.c.p(c);\n var raw = dopt(c, this.o, this.v && 2, f && 4, !f);\n if (this.v)\n zlh(raw, this.o), this.v = 0;\n if (f)\n wbytes(raw, raw.length - 4, this.c.d());\n this.ondata(raw, f);\n };\n return Zlib;\n}());\nexport { Zlib };\n/**\n * Asynchronous streaming Zlib compression\n */\nvar AsyncZlib = /*#__PURE__*/ (function () {\n function AsyncZlib(opts, cb) {\n astrmify([\n bDflt,\n zle,\n function () { return [astrm, Deflate, Zlib]; }\n ], this, AsyncCmpStrm.call(this, opts, cb), function (ev) {\n var strm = new Zlib(ev.data);\n onmessage = astrm(strm);\n }, 10);\n }\n return AsyncZlib;\n}());\nexport { AsyncZlib };\nexport function zlib(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n err(7);\n return cbify(data, opts, [\n bDflt,\n zle,\n function () { return [zlibSync]; }\n ], function (ev) { return pbf(zlibSync(ev.data[0], ev.data[1])); }, 4, cb);\n}\n/**\n * Compress data with Zlib\n * @param data The data to compress\n * @param opts The compression options\n * @returns The zlib-compressed version of the data\n */\nexport function zlibSync(data, opts) {\n if (!opts)\n opts = {};\n var a = adler();\n a.p(data);\n var d = dopt(data, opts, 2, 4);\n return zlh(d, opts), wbytes(d, d.length - 4, a.d()), d;\n}\n/**\n * Streaming Zlib decompression\n */\nvar Unzlib = /*#__PURE__*/ (function () {\n /**\n * Creates a Zlib decompression stream\n * @param cb The callback to call whenever data is inflated\n */\n function Unzlib(cb) {\n this.v = 1;\n Inflate.call(this, cb);\n }\n /**\n * Pushes a chunk to be unzlibbed\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Unzlib.prototype.push = function (chunk, final) {\n Inflate.prototype.e.call(this, chunk);\n if (this.v) {\n if (this.p.length < 2 && !final)\n return;\n this.p = this.p.subarray(2), this.v = 0;\n }\n if (final) {\n if (this.p.length < 4)\n err(6, 'invalid zlib data');\n this.p = this.p.subarray(0, -4);\n }\n // necessary to prevent TS from using the closure value\n // This allows for workerization to function correctly\n Inflate.prototype.c.call(this, final);\n };\n return Unzlib;\n}());\nexport { Unzlib };\n/**\n * Asynchronous streaming Zlib decompression\n */\nvar AsyncUnzlib = /*#__PURE__*/ (function () {\n /**\n * Creates an asynchronous Zlib decompression stream\n * @param cb The callback to call whenever data is deflated\n */\n function AsyncUnzlib(cb) {\n this.ondata = cb;\n astrmify([\n bInflt,\n zule,\n function () { return [astrm, Inflate, Unzlib]; }\n ], this, 0, function () {\n var strm = new Unzlib();\n onmessage = astrm(strm);\n }, 11);\n }\n return AsyncUnzlib;\n}());\nexport { AsyncUnzlib };\nexport function unzlib(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n err(7);\n return cbify(data, opts, [\n bInflt,\n zule,\n function () { return [unzlibSync]; }\n ], function (ev) { return pbf(unzlibSync(ev.data[0], gu8(ev.data[1]))); }, 5, cb);\n}\n/**\n * Expands Zlib data\n * @param data The data to decompress\n * @param out Where to write the data. Saves memory if you know the decompressed size and provide an output buffer of that length.\n * @returns The decompressed version of the data\n */\nexport function unzlibSync(data, out) {\n return inflt((zlv(data), data.subarray(2, -4)), out);\n}\n// Default algorithm for compression (used because having a known output size allows faster decompression)\nexport { gzip as compress, AsyncGzip as AsyncCompress };\n// Default algorithm for compression (used because having a known output size allows faster decompression)\nexport { gzipSync as compressSync, Gzip as Compress };\n/**\n * Streaming GZIP, Zlib, or raw DEFLATE decompression\n */\nvar Decompress = /*#__PURE__*/ (function () {\n /**\n * Creates a decompression stream\n * @param cb The callback to call whenever data is decompressed\n */\n function Decompress(cb) {\n this.G = Gunzip;\n this.I = Inflate;\n this.Z = Unzlib;\n this.ondata = cb;\n }\n /**\n * Pushes a chunk to be decompressed\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Decompress.prototype.push = function (chunk, final) {\n if (!this.ondata)\n err(5);\n if (!this.s) {\n if (this.p && this.p.length) {\n var n = new u8(this.p.length + chunk.length);\n n.set(this.p), n.set(chunk, this.p.length);\n }\n else\n this.p = chunk;\n if (this.p.length > 2) {\n var _this_1 = this;\n var cb = function () { _this_1.ondata.apply(_this_1, arguments); };\n this.s = (this.p[0] == 31 && this.p[1] == 139 && this.p[2] == 8)\n ? new this.G(cb)\n : ((this.p[0] & 15) != 8 || (this.p[0] >> 4) > 7 || ((this.p[0] << 8 | this.p[1]) % 31))\n ? new this.I(cb)\n : new this.Z(cb);\n this.s.push(this.p, final);\n this.p = null;\n }\n }\n else\n this.s.push(chunk, final);\n };\n return Decompress;\n}());\nexport { Decompress };\n/**\n * Asynchronous streaming GZIP, Zlib, or raw DEFLATE decompression\n */\nvar AsyncDecompress = /*#__PURE__*/ (function () {\n /**\n * Creates an asynchronous decompression stream\n * @param cb The callback to call whenever data is decompressed\n */\n function AsyncDecompress(cb) {\n this.G = AsyncGunzip;\n this.I = AsyncInflate;\n this.Z = AsyncUnzlib;\n this.ondata = cb;\n }\n /**\n * Pushes a chunk to be decompressed\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n AsyncDecompress.prototype.push = function (chunk, final) {\n Decompress.prototype.push.call(this, chunk, final);\n };\n return AsyncDecompress;\n}());\nexport { AsyncDecompress };\nexport function decompress(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n err(7);\n return (data[0] == 31 && data[1] == 139 && data[2] == 8)\n ? gunzip(data, opts, cb)\n : ((data[0] & 15) != 8 || (data[0] >> 4) > 7 || ((data[0] << 8 | data[1]) % 31))\n ? inflate(data, opts, cb)\n : unzlib(data, opts, cb);\n}\n/**\n * Expands compressed GZIP, Zlib, or raw DEFLATE data, automatically detecting the format\n * @param data The data to decompress\n * @param out Where to write the data. Saves memory if you know the decompressed size and provide an output buffer of that length.\n * @returns The decompressed version of the data\n */\nexport function decompressSync(data, out) {\n return (data[0] == 31 && data[1] == 139 && data[2] == 8)\n ? gunzipSync(data, out)\n : ((data[0] & 15) != 8 || (data[0] >> 4) > 7 || ((data[0] << 8 | data[1]) % 31))\n ? inflateSync(data, out)\n : unzlibSync(data, out);\n}\n// flatten a directory structure\nvar fltn = function (d, p, t, o) {\n for (var k in d) {\n var val = d[k], n = p + k, op = o;\n if (Array.isArray(val))\n op = mrg(o, val[1]), val = val[0];\n if (val instanceof u8)\n t[n] = [val, op];\n else {\n t[n += '/'] = [new u8(0), op];\n fltn(val, n, t, o);\n }\n }\n};\n// text encoder\nvar te = typeof TextEncoder != 'undefined' && /*#__PURE__*/ new TextEncoder();\n// text decoder\nvar td = typeof TextDecoder != 'undefined' && /*#__PURE__*/ new TextDecoder();\n// text decoder stream\nvar tds = 0;\ntry {\n td.decode(et, { stream: true });\n tds = 1;\n}\ncatch (e) { }\n// decode UTF8\nvar dutf8 = function (d) {\n for (var r = '', i = 0;;) {\n var c = d[i++];\n var eb = (c > 127) + (c > 223) + (c > 239);\n if (i + eb > d.length)\n return [r, slc(d, i - 1)];\n if (!eb)\n r += String.fromCharCode(c);\n else if (eb == 3) {\n c = ((c & 15) << 18 | (d[i++] & 63) << 12 | (d[i++] & 63) << 6 | (d[i++] & 63)) - 65536,\n r += String.fromCharCode(55296 | (c >> 10), 56320 | (c & 1023));\n }\n else if (eb & 1)\n r += String.fromCharCode((c & 31) << 6 | (d[i++] & 63));\n else\n r += String.fromCharCode((c & 15) << 12 | (d[i++] & 63) << 6 | (d[i++] & 63));\n }\n};\n/**\n * Streaming UTF-8 decoding\n */\nvar DecodeUTF8 = /*#__PURE__*/ (function () {\n /**\n * Creates a UTF-8 decoding stream\n * @param cb The callback to call whenever data is decoded\n */\n function DecodeUTF8(cb) {\n this.ondata = cb;\n if (tds)\n this.t = new TextDecoder();\n else\n this.p = et;\n }\n /**\n * Pushes a chunk to be decoded from UTF-8 binary\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n DecodeUTF8.prototype.push = function (chunk, final) {\n if (!this.ondata)\n err(5);\n final = !!final;\n if (this.t) {\n this.ondata(this.t.decode(chunk, { stream: true }), final);\n if (final) {\n if (this.t.decode().length)\n err(8);\n this.t = null;\n }\n return;\n }\n if (!this.p)\n err(4);\n var dat = new u8(this.p.length + chunk.length);\n dat.set(this.p);\n dat.set(chunk, this.p.length);\n var _a = dutf8(dat), ch = _a[0], np = _a[1];\n if (final) {\n if (np.length)\n err(8);\n this.p = null;\n }\n else\n this.p = np;\n this.ondata(ch, final);\n };\n return DecodeUTF8;\n}());\nexport { DecodeUTF8 };\n/**\n * Streaming UTF-8 encoding\n */\nvar EncodeUTF8 = /*#__PURE__*/ (function () {\n /**\n * Creates a UTF-8 decoding stream\n * @param cb The callback to call whenever data is encoded\n */\n function EncodeUTF8(cb) {\n this.ondata = cb;\n }\n /**\n * Pushes a chunk to be encoded to UTF-8\n * @param chunk The string data to push\n * @param final Whether this is the last chunk\n */\n EncodeUTF8.prototype.push = function (chunk, final) {\n if (!this.ondata)\n err(5);\n if (this.d)\n err(4);\n this.ondata(strToU8(chunk), this.d = final || false);\n };\n return EncodeUTF8;\n}());\nexport { EncodeUTF8 };\n/**\n * Converts a string into a Uint8Array for use with compression/decompression methods\n * @param str The string to encode\n * @param latin1 Whether or not to interpret the data as Latin-1. This should\n * not need to be true unless decoding a binary string.\n * @returns The string encoded in UTF-8/Latin-1 binary\n */\nexport function strToU8(str, latin1) {\n if (latin1) {\n var ar_1 = new u8(str.length);\n for (var i = 0; i < str.length; ++i)\n ar_1[i] = str.charCodeAt(i);\n return ar_1;\n }\n if (te)\n return te.encode(str);\n var l = str.length;\n var ar = new u8(str.length + (str.length >> 1));\n var ai = 0;\n var w = function (v) { ar[ai++] = v; };\n for (var i = 0; i < l; ++i) {\n if (ai + 5 > ar.length) {\n var n = new u8(ai + 8 + ((l - i) << 1));\n n.set(ar);\n ar = n;\n }\n var c = str.charCodeAt(i);\n if (c < 128 || latin1)\n w(c);\n else if (c < 2048)\n w(192 | (c >> 6)), w(128 | (c & 63));\n else if (c > 55295 && c < 57344)\n c = 65536 + (c & 1023 << 10) | (str.charCodeAt(++i) & 1023),\n w(240 | (c >> 18)), w(128 | ((c >> 12) & 63)), w(128 | ((c >> 6) & 63)), w(128 | (c & 63));\n else\n w(224 | (c >> 12)), w(128 | ((c >> 6) & 63)), w(128 | (c & 63));\n }\n return slc(ar, 0, ai);\n}\n/**\n * Converts a Uint8Array to a string\n * @param dat The data to decode to string\n * @param latin1 Whether or not to interpret the data as Latin-1. This should\n * not need to be true unless encoding to binary string.\n * @returns The original UTF-8/Latin-1 string\n */\nexport function strFromU8(dat, latin1) {\n if (latin1) {\n var r = '';\n for (var i = 0; i < dat.length; i += 16384)\n r += String.fromCharCode.apply(null, dat.subarray(i, i + 16384));\n return r;\n }\n else if (td)\n return td.decode(dat);\n else {\n var _a = dutf8(dat), out = _a[0], ext = _a[1];\n if (ext.length)\n err(8);\n return out;\n }\n}\n;\n// deflate bit flag\nvar dbf = function (l) { return l == 1 ? 3 : l < 6 ? 2 : l == 9 ? 1 : 0; };\n// skip local zip header\nvar slzh = function (d, b) { return b + 30 + b2(d, b + 26) + b2(d, b + 28); };\n// read zip header\nvar zh = function (d, b, z) {\n var fnl = b2(d, b + 28), fn = strFromU8(d.subarray(b + 46, b + 46 + fnl), !(b2(d, b + 8) & 2048)), es = b + 46 + fnl, bs = b4(d, b + 20);\n var _a = z && bs == 4294967295 ? z64e(d, es) : [bs, b4(d, b + 24), b4(d, b + 42)], sc = _a[0], su = _a[1], off = _a[2];\n return [b2(d, b + 10), sc, su, fn, es + b2(d, b + 30) + b2(d, b + 32), off];\n};\n// read zip64 extra field\nvar z64e = function (d, b) {\n for (; b2(d, b) != 1; b += 4 + b2(d, b + 2))\n ;\n return [b8(d, b + 12), b8(d, b + 4), b8(d, b + 20)];\n};\n// extra field length\nvar exfl = function (ex) {\n var le = 0;\n if (ex) {\n for (var k in ex) {\n var l = ex[k].length;\n if (l > 65535)\n err(9);\n le += l + 4;\n }\n }\n return le;\n};\n// write zip header\nvar wzh = function (d, b, f, fn, u, c, ce, co) {\n var fl = fn.length, ex = f.extra, col = co && co.length;\n var exl = exfl(ex);\n wbytes(d, b, ce != null ? 0x2014B50 : 0x4034B50), b += 4;\n if (ce != null)\n d[b++] = 20, d[b++] = f.os;\n d[b] = 20, b += 2; // spec compliance? what's that?\n d[b++] = (f.flag << 1) | (c < 0 && 8), d[b++] = u && 8;\n d[b++] = f.compression & 255, d[b++] = f.compression >> 8;\n var dt = new Date(f.mtime == null ? Date.now() : f.mtime), y = dt.getFullYear() - 1980;\n if (y < 0 || y > 119)\n err(10);\n wbytes(d, b, (y << 25) | ((dt.getMonth() + 1) << 21) | (dt.getDate() << 16) | (dt.getHours() << 11) | (dt.getMinutes() << 5) | (dt.getSeconds() >>> 1)), b += 4;\n if (c != -1) {\n wbytes(d, b, f.crc);\n wbytes(d, b + 4, c < 0 ? -c - 2 : c);\n wbytes(d, b + 8, f.size);\n }\n wbytes(d, b + 12, fl);\n wbytes(d, b + 14, exl), b += 16;\n if (ce != null) {\n wbytes(d, b, col);\n wbytes(d, b + 6, f.attrs);\n wbytes(d, b + 10, ce), b += 14;\n }\n d.set(fn, b);\n b += fl;\n if (exl) {\n for (var k in ex) {\n var exf = ex[k], l = exf.length;\n wbytes(d, b, +k);\n wbytes(d, b + 2, l);\n d.set(exf, b + 4), b += 4 + l;\n }\n }\n if (col)\n d.set(co, b), b += col;\n return b;\n};\n// write zip footer (end of central directory)\nvar wzf = function (o, b, c, d, e) {\n wbytes(o, b, 0x6054B50); // skip disk\n wbytes(o, b + 8, c);\n wbytes(o, b + 10, c);\n wbytes(o, b + 12, d);\n wbytes(o, b + 16, e);\n};\n/**\n * A pass-through stream to keep data uncompressed in a ZIP archive.\n */\nvar ZipPassThrough = /*#__PURE__*/ (function () {\n /**\n * Creates a pass-through stream that can be added to ZIP archives\n * @param filename The filename to associate with this data stream\n */\n function ZipPassThrough(filename) {\n this.filename = filename;\n this.c = crc();\n this.size = 0;\n this.compression = 0;\n }\n /**\n * Processes a chunk and pushes to the output stream. You can override this\n * method in a subclass for custom behavior, but by default this passes\n * the data through. You must call this.ondata(err, chunk, final) at some\n * point in this method.\n * @param chunk The chunk to process\n * @param final Whether this is the last chunk\n */\n ZipPassThrough.prototype.process = function (chunk, final) {\n this.ondata(null, chunk, final);\n };\n /**\n * Pushes a chunk to be added. If you are subclassing this with a custom\n * compression algorithm, note that you must push data from the source\n * file only, pre-compression.\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n ZipPassThrough.prototype.push = function (chunk, final) {\n if (!this.ondata)\n err(5);\n this.c.p(chunk);\n this.size += chunk.length;\n if (final)\n this.crc = this.c.d();\n this.process(chunk, final || false);\n };\n return ZipPassThrough;\n}());\nexport { ZipPassThrough };\n// I don't extend because TypeScript extension adds 1kB of runtime bloat\n/**\n * Streaming DEFLATE compression for ZIP archives. Prefer using AsyncZipDeflate\n * for better performance\n */\nvar ZipDeflate = /*#__PURE__*/ (function () {\n /**\n * Creates a DEFLATE stream that can be added to ZIP archives\n * @param filename The filename to associate with this data stream\n * @param opts The compression options\n */\n function ZipDeflate(filename, opts) {\n var _this_1 = this;\n if (!opts)\n opts = {};\n ZipPassThrough.call(this, filename);\n this.d = new Deflate(opts, function (dat, final) {\n _this_1.ondata(null, dat, final);\n });\n this.compression = 8;\n this.flag = dbf(opts.level);\n }\n ZipDeflate.prototype.process = function (chunk, final) {\n try {\n this.d.push(chunk, final);\n }\n catch (e) {\n this.ondata(e, null, final);\n }\n };\n /**\n * Pushes a chunk to be deflated\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n ZipDeflate.prototype.push = function (chunk, final) {\n ZipPassThrough.prototype.push.call(this, chunk, final);\n };\n return ZipDeflate;\n}());\nexport { ZipDeflate };\n/**\n * Asynchronous streaming DEFLATE compression for ZIP archives\n */\nvar AsyncZipDeflate = /*#__PURE__*/ (function () {\n /**\n * Creates a DEFLATE stream that can be added to ZIP archives\n * @param filename The filename to associate with this data stream\n * @param opts The compression options\n */\n function AsyncZipDeflate(filename, opts) {\n var _this_1 = this;\n if (!opts)\n opts = {};\n ZipPassThrough.call(this, filename);\n this.d = new AsyncDeflate(opts, function (err, dat, final) {\n _this_1.ondata(err, dat, final);\n });\n this.compression = 8;\n this.flag = dbf(opts.level);\n this.terminate = this.d.terminate;\n }\n AsyncZipDeflate.prototype.process = function (chunk, final) {\n this.d.push(chunk, final);\n };\n /**\n * Pushes a chunk to be deflated\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n AsyncZipDeflate.prototype.push = function (chunk, final) {\n ZipPassThrough.prototype.push.call(this, chunk, final);\n };\n return AsyncZipDeflate;\n}());\nexport { AsyncZipDeflate };\n// TODO: Better tree shaking\n/**\n * A zippable archive to which files can incrementally be added\n */\nvar Zip = /*#__PURE__*/ (function () {\n /**\n * Creates an empty ZIP archive to which files can be added\n * @param cb The callback to call whenever data for the generated ZIP archive\n * is available\n */\n function Zip(cb) {\n this.ondata = cb;\n this.u = [];\n this.d = 1;\n }\n /**\n * Adds a file to the ZIP archive\n * @param file The file stream to add\n */\n Zip.prototype.add = function (file) {\n var _this_1 = this;\n if (!this.ondata)\n err(5);\n // finishing or finished\n if (this.d & 2)\n this.ondata(err(4 + (this.d & 1) * 8, 0, 1), null, false);\n else {\n var f = strToU8(file.filename), fl_1 = f.length;\n var com = file.comment, o = com && strToU8(com);\n var u = fl_1 != file.filename.length || (o && (com.length != o.length));\n var hl_1 = fl_1 + exfl(file.extra) + 30;\n if (fl_1 > 65535)\n this.ondata(err(11, 0, 1), null, false);\n var header = new u8(hl_1);\n wzh(header, 0, file, f, u, -1);\n var chks_1 = [header];\n var pAll_1 = function () {\n for (var _i = 0, chks_2 = chks_1; _i < chks_2.length; _i++) {\n var chk = chks_2[_i];\n _this_1.ondata(null, chk, false);\n }\n chks_1 = [];\n };\n var tr_1 = this.d;\n this.d = 0;\n var ind_1 = this.u.length;\n var uf_1 = mrg(file, {\n f: f,\n u: u,\n o: o,\n t: function () {\n if (file.terminate)\n file.terminate();\n },\n r: function () {\n pAll_1();\n if (tr_1) {\n var nxt = _this_1.u[ind_1 + 1];\n if (nxt)\n nxt.r();\n else\n _this_1.d = 1;\n }\n tr_1 = 1;\n }\n });\n var cl_1 = 0;\n file.ondata = function (err, dat, final) {\n if (err) {\n _this_1.ondata(err, dat, final);\n _this_1.terminate();\n }\n else {\n cl_1 += dat.length;\n chks_1.push(dat);\n if (final) {\n var dd = new u8(16);\n wbytes(dd, 0, 0x8074B50);\n wbytes(dd, 4, file.crc);\n wbytes(dd, 8, cl_1);\n wbytes(dd, 12, file.size);\n chks_1.push(dd);\n uf_1.c = cl_1, uf_1.b = hl_1 + cl_1 + 16, uf_1.crc = file.crc, uf_1.size = file.size;\n if (tr_1)\n uf_1.r();\n tr_1 = 1;\n }\n else if (tr_1)\n pAll_1();\n }\n };\n this.u.push(uf_1);\n }\n };\n /**\n * Ends the process of adding files and prepares to emit the final chunks.\n * This *must* be called after adding all desired files for the resulting\n * ZIP file to work properly.\n */\n Zip.prototype.end = function () {\n var _this_1 = this;\n if (this.d & 2) {\n this.ondata(err(4 + (this.d & 1) * 8, 0, 1), null, true);\n return;\n }\n if (this.d)\n this.e();\n else\n this.u.push({\n r: function () {\n if (!(_this_1.d & 1))\n return;\n _this_1.u.splice(-1, 1);\n _this_1.e();\n },\n t: function () { }\n });\n this.d = 3;\n };\n Zip.prototype.e = function () {\n var bt = 0, l = 0, tl = 0;\n for (var _i = 0, _a = this.u; _i < _a.length; _i++) {\n var f = _a[_i];\n tl += 46 + f.f.length + exfl(f.extra) + (f.o ? f.o.length : 0);\n }\n var out = new u8(tl + 22);\n for (var _b = 0, _c = this.u; _b < _c.length; _b++) {\n var f = _c[_b];\n wzh(out, bt, f, f.f, f.u, -f.c - 2, l, f.o);\n bt += 46 + f.f.length + exfl(f.extra) + (f.o ? f.o.length : 0), l += f.b;\n }\n wzf(out, bt, this.u.length, tl, l);\n this.ondata(null, out, true);\n this.d = 2;\n };\n /**\n * A method to terminate any internal workers used by the stream. Subsequent\n * calls to add() will fail.\n */\n Zip.prototype.terminate = function () {\n for (var _i = 0, _a = this.u; _i < _a.length; _i++) {\n var f = _a[_i];\n f.t();\n }\n this.d = 2;\n };\n return Zip;\n}());\nexport { Zip };\nexport function zip(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n err(7);\n var r = {};\n fltn(data, '', r, opts);\n var k = Object.keys(r);\n var lft = k.length, o = 0, tot = 0;\n var slft = lft, files = new Array(lft);\n var term = [];\n var tAll = function () {\n for (var i = 0; i < term.length; ++i)\n term[i]();\n };\n var cbd = function (a, b) {\n mt(function () { cb(a, b); });\n };\n mt(function () { cbd = cb; });\n var cbf = function () {\n var out = new u8(tot + 22), oe = o, cdl = tot - o;\n tot = 0;\n for (var i = 0; i < slft; ++i) {\n var f = files[i];\n try {\n var l = f.c.length;\n wzh(out, tot, f, f.f, f.u, l);\n var badd = 30 + f.f.length + exfl(f.extra);\n var loc = tot + badd;\n out.set(f.c, loc);\n wzh(out, o, f, f.f, f.u, l, tot, f.m), o += 16 + badd + (f.m ? f.m.length : 0), tot = loc + l;\n }\n catch (e) {\n return cbd(e, null);\n }\n }\n wzf(out, o, files.length, cdl, oe);\n cbd(null, out);\n };\n if (!lft)\n cbf();\n var _loop_1 = function (i) {\n var fn = k[i];\n var _a = r[fn], file = _a[0], p = _a[1];\n var c = crc(), size = file.length;\n c.p(file);\n var f = strToU8(fn), s = f.length;\n var com = p.comment, m = com && strToU8(com), ms = m && m.length;\n var exl = exfl(p.extra);\n var compression = p.level == 0 ? 0 : 8;\n var cbl = function (e, d) {\n if (e) {\n tAll();\n cbd(e, null);\n }\n else {\n var l = d.length;\n files[i] = mrg(p, {\n size: size,\n crc: c.d(),\n c: d,\n f: f,\n m: m,\n u: s != fn.length || (m && (com.length != ms)),\n compression: compression\n });\n o += 30 + s + exl + l;\n tot += 76 + 2 * (s + exl) + (ms || 0) + l;\n if (!--lft)\n cbf();\n }\n };\n if (s > 65535)\n cbl(err(11, 0, 1), null);\n if (!compression)\n cbl(null, file);\n else if (size < 160000) {\n try {\n cbl(null, deflateSync(file, p));\n }\n catch (e) {\n cbl(e, null);\n }\n }\n else\n term.push(deflate(file, p, cbl));\n };\n // Cannot use lft because it can decrease\n for (var i = 0; i < slft; ++i) {\n _loop_1(i);\n }\n return tAll;\n}\n/**\n * Synchronously creates a ZIP file. Prefer using `zip` for better performance\n * with more than one file.\n * @param data The directory structure for the ZIP archive\n * @param opts The main options, merged with per-file options\n * @returns The generated ZIP archive\n */\nexport function zipSync(data, opts) {\n if (!opts)\n opts = {};\n var r = {};\n var files = [];\n fltn(data, '', r, opts);\n var o = 0;\n var tot = 0;\n for (var fn in r) {\n var _a = r[fn], file = _a[0], p = _a[1];\n var compression = p.level == 0 ? 0 : 8;\n var f = strToU8(fn), s = f.length;\n var com = p.comment, m = com && strToU8(com), ms = m && m.length;\n var exl = exfl(p.extra);\n if (s > 65535)\n err(11);\n var d = compression ? deflateSync(file, p) : file, l = d.length;\n var c = crc();\n c.p(file);\n files.push(mrg(p, {\n size: file.length,\n crc: c.d(),\n c: d,\n f: f,\n m: m,\n u: s != fn.length || (m && (com.length != ms)),\n o: o,\n compression: compression\n }));\n o += 30 + s + exl + l;\n tot += 76 + 2 * (s + exl) + (ms || 0) + l;\n }\n var out = new u8(tot + 22), oe = o, cdl = tot - o;\n for (var i = 0; i < files.length; ++i) {\n var f = files[i];\n wzh(out, f.o, f, f.f, f.u, f.c.length);\n var badd = 30 + f.f.length + exfl(f.extra);\n out.set(f.c, f.o + badd);\n wzh(out, o, f, f.f, f.u, f.c.length, f.o, f.m), o += 16 + badd + (f.m ? f.m.length : 0);\n }\n wzf(out, o, files.length, cdl, oe);\n return out;\n}\n/**\n * Streaming pass-through decompression for ZIP archives\n */\nvar UnzipPassThrough = /*#__PURE__*/ (function () {\n function UnzipPassThrough() {\n }\n UnzipPassThrough.prototype.push = function (data, final) {\n this.ondata(null, data, final);\n };\n UnzipPassThrough.compression = 0;\n return UnzipPassThrough;\n}());\nexport { UnzipPassThrough };\n/**\n * Streaming DEFLATE decompression for ZIP archives. Prefer AsyncZipInflate for\n * better performance.\n */\nvar UnzipInflate = /*#__PURE__*/ (function () {\n /**\n * Creates a DEFLATE decompression that can be used in ZIP archives\n */\n function UnzipInflate() {\n var _this_1 = this;\n this.i = new Inflate(function (dat, final) {\n _this_1.ondata(null, dat, final);\n });\n }\n UnzipInflate.prototype.push = function (data, final) {\n try {\n this.i.push(data, final);\n }\n catch (e) {\n this.ondata(e, null, final);\n }\n };\n UnzipInflate.compression = 8;\n return UnzipInflate;\n}());\nexport { UnzipInflate };\n/**\n * Asynchronous streaming DEFLATE decompression for ZIP archives\n */\nvar AsyncUnzipInflate = /*#__PURE__*/ (function () {\n /**\n * Creates a DEFLATE decompression that can be used in ZIP archives\n */\n function AsyncUnzipInflate(_, sz) {\n var _this_1 = this;\n if (sz < 320000) {\n this.i = new Inflate(function (dat, final) {\n _this_1.ondata(null, dat, final);\n });\n }\n else {\n this.i = new AsyncInflate(function (err, dat, final) {\n _this_1.ondata(err, dat, final);\n });\n this.terminate = this.i.terminate;\n }\n }\n AsyncUnzipInflate.prototype.push = function (data, final) {\n if (this.i.terminate)\n data = slc(data, 0);\n this.i.push(data, final);\n };\n AsyncUnzipInflate.compression = 8;\n return AsyncUnzipInflate;\n}());\nexport { AsyncUnzipInflate };\n/**\n * A ZIP archive decompression stream that emits files as they are discovered\n */\nvar Unzip = /*#__PURE__*/ (function () {\n /**\n * Creates a ZIP decompression stream\n * @param cb The callback to call whenever a file in the ZIP archive is found\n */\n function Unzip(cb) {\n this.onfile = cb;\n this.k = [];\n this.o = {\n 0: UnzipPassThrough\n };\n this.p = et;\n }\n /**\n * Pushes a chunk to be unzipped\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Unzip.prototype.push = function (chunk, final) {\n var _this_1 = this;\n if (!this.onfile)\n err(5);\n if (!this.p)\n err(4);\n if (this.c > 0) {\n var len = Math.min(this.c, chunk.length);\n var toAdd = chunk.subarray(0, len);\n this.c -= len;\n if (this.d)\n this.d.push(toAdd, !this.c);\n else\n this.k[0].push(toAdd);\n chunk = chunk.subarray(len);\n if (chunk.length)\n return this.push(chunk, final);\n }\n else {\n var f = 0, i = 0, is = void 0, buf = void 0;\n if (!this.p.length)\n buf = chunk;\n else if (!chunk.length)\n buf = this.p;\n else {\n buf = new u8(this.p.length + chunk.length);\n buf.set(this.p), buf.set(chunk, this.p.length);\n }\n var l = buf.length, oc = this.c, add = oc && this.d;\n var _loop_2 = function () {\n var _a;\n var sig = b4(buf, i);\n if (sig == 0x4034B50) {\n f = 1, is = i;\n this_1.d = null;\n this_1.c = 0;\n var bf = b2(buf, i + 6), cmp_1 = b2(buf, i + 8), u = bf & 2048, dd = bf & 8, fnl = b2(buf, i + 26), es = b2(buf, i + 28);\n if (l > i + 30 + fnl + es) {\n var chks_3 = [];\n this_1.k.unshift(chks_3);\n f = 2;\n var sc_1 = b4(buf, i + 18), su_1 = b4(buf, i + 22);\n var fn_1 = strFromU8(buf.subarray(i + 30, i += 30 + fnl), !u);\n if (sc_1 == 4294967295) {\n _a = dd ? [-2] : z64e(buf, i), sc_1 = _a[0], su_1 = _a[1];\n }\n else if (dd)\n sc_1 = -1;\n i += es;\n this_1.c = sc_1;\n var d_1;\n var file_1 = {\n name: fn_1,\n compression: cmp_1,\n start: function () {\n if (!file_1.ondata)\n err(5);\n if (!sc_1)\n file_1.ondata(null, et, true);\n else {\n var ctr = _this_1.o[cmp_1];\n if (!ctr)\n file_1.ondata(err(14, 'unknown compression type ' + cmp_1, 1), null, false);\n d_1 = sc_1 < 0 ? new ctr(fn_1) : new ctr(fn_1, sc_1, su_1);\n d_1.ondata = function (err, dat, final) { file_1.ondata(err, dat, final); };\n for (var _i = 0, chks_4 = chks_3; _i < chks_4.length; _i++) {\n var dat = chks_4[_i];\n d_1.push(dat, false);\n }\n if (_this_1.k[0] == chks_3 && _this_1.c)\n _this_1.d = d_1;\n else\n d_1.push(et, true);\n }\n },\n terminate: function () {\n if (d_1 && d_1.terminate)\n d_1.terminate();\n }\n };\n if (sc_1 >= 0)\n file_1.size = sc_1, file_1.originalSize = su_1;\n this_1.onfile(file_1);\n }\n return \"break\";\n }\n else if (oc) {\n if (sig == 0x8074B50) {\n is = i += 12 + (oc == -2 && 8), f = 3, this_1.c = 0;\n return \"break\";\n }\n else if (sig == 0x2014B50) {\n is = i -= 4, f = 3, this_1.c = 0;\n return \"break\";\n }\n }\n };\n var this_1 = this;\n for (; i < l - 4; ++i) {\n var state_1 = _loop_2();\n if (state_1 === \"break\")\n break;\n }\n this.p = et;\n if (oc < 0) {\n var dat = f ? buf.subarray(0, is - 12 - (oc == -2 && 8) - (b4(buf, is - 16) == 0x8074B50 && 4)) : buf.subarray(0, i);\n if (add)\n add.push(dat, !!f);\n else\n this.k[+(f == 2)].push(dat);\n }\n if (f & 2)\n return this.push(buf.subarray(i), final);\n this.p = buf.subarray(i);\n }\n if (final) {\n if (this.c)\n err(13);\n this.p = null;\n }\n };\n /**\n * Registers a decoder with the stream, allowing for files compressed with\n * the compression type provided to be expanded correctly\n * @param decoder The decoder constructor\n */\n Unzip.prototype.register = function (decoder) {\n this.o[decoder.compression] = decoder;\n };\n return Unzip;\n}());\nexport { Unzip };\nvar mt = typeof queueMicrotask == 'function' ? queueMicrotask : typeof setTimeout == 'function' ? setTimeout : function (fn) { fn(); };\nexport function unzip(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n err(7);\n var term = [];\n var tAll = function () {\n for (var i = 0; i < term.length; ++i)\n term[i]();\n };\n var files = {};\n var cbd = function (a, b) {\n mt(function () { cb(a, b); });\n };\n mt(function () { cbd = cb; });\n var e = data.length - 22;\n for (; b4(data, e) != 0x6054B50; --e) {\n if (!e || data.length - e > 65558) {\n cbd(err(13, 0, 1), null);\n return tAll;\n }\n }\n ;\n var lft = b2(data, e + 8);\n if (lft) {\n var c = lft;\n var o = b4(data, e + 16);\n var z = o == 4294967295 || c == 65535;\n if (z) {\n var ze = b4(data, e - 12);\n z = b4(data, ze) == 0x6064B50;\n if (z) {\n c = lft = b4(data, ze + 32);\n o = b4(data, ze + 48);\n }\n }\n var fltr = opts && opts.filter;\n var _loop_3 = function (i) {\n var _a = zh(data, o, z), c_1 = _a[0], sc = _a[1], su = _a[2], fn = _a[3], no = _a[4], off = _a[5], b = slzh(data, off);\n o = no;\n var cbl = function (e, d) {\n if (e) {\n tAll();\n cbd(e, null);\n }\n else {\n if (d)\n files[fn] = d;\n if (!--lft)\n cbd(null, files);\n }\n };\n if (!fltr || fltr({\n name: fn,\n size: sc,\n originalSize: su,\n compression: c_1\n })) {\n if (!c_1)\n cbl(null, slc(data, b, b + sc));\n else if (c_1 == 8) {\n var infl = data.subarray(b, b + sc);\n if (sc < 320000) {\n try {\n cbl(null, inflateSync(infl, new u8(su)));\n }\n catch (e) {\n cbl(e, null);\n }\n }\n else\n term.push(inflate(infl, { size: su }, cbl));\n }\n else\n cbl(err(14, 'unknown compression type ' + c_1, 1), null);\n }\n else\n cbl(null, null);\n };\n for (var i = 0; i < c; ++i) {\n _loop_3(i);\n }\n }\n else\n cbd(null, {});\n return tAll;\n}\n/**\n * Synchronously decompresses a ZIP archive. Prefer using `unzip` for better\n * performance with more than one file.\n * @param data The raw compressed ZIP file\n * @param opts The ZIP extraction options\n * @returns The decompressed files\n */\nexport function unzipSync(data, opts) {\n var files = {};\n var e = data.length - 22;\n for (; b4(data, e) != 0x6054B50; --e) {\n if (!e || data.length - e > 65558)\n err(13);\n }\n ;\n var c = b2(data, e + 8);\n if (!c)\n return {};\n var o = b4(data, e + 16);\n var z = o == 4294967295 || c == 65535;\n if (z) {\n var ze = b4(data, e - 12);\n z = b4(data, ze) == 0x6064B50;\n if (z) {\n c = b4(data, ze + 32);\n o = b4(data, ze + 48);\n }\n }\n var fltr = opts && opts.filter;\n for (var i = 0; i < c; ++i) {\n var _a = zh(data, o, z), c_2 = _a[0], sc = _a[1], su = _a[2], fn = _a[3], no = _a[4], off = _a[5], b = slzh(data, off);\n o = no;\n if (!fltr || fltr({\n name: fn,\n size: sc,\n originalSize: su,\n compression: c_2\n })) {\n if (!c_2)\n files[fn] = slc(data, b, b + sc);\n else if (c_2 == 8)\n files[fn] = inflateSync(data.subarray(b, b + sc), new u8(su));\n else\n err(14, 'unknown compression type ' + c_2);\n }\n }\n return files;\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport * as DataStore from \"@api/DataStore\";\nimport { showNotification } from \"@api/Notifications\";\nimport { Settings } from \"@api/Settings\";\nimport { OAuth2AuthorizeModal, UserStore } from \"@webpack/common\";\n\nimport { Logger } from \"./Logger\";\nimport { openModal } from \"./modal\";\n\nexport const cloudLogger = new Logger(\"Cloud\", \"#39b7e0\");\nexport const getCloudUrl = () => new URL(Settings.cloud.url);\n\nconst cloudUrlOrigin = () => getCloudUrl().origin;\nconst getUserId = () => {\n const id = UserStore.getCurrentUser()?.id;\n if (!id) throw new Error(\"User not yet logged in\");\n return id;\n};\n\nexport async function getAuthorization() {\n const secrets = await DataStore.get<Record<string, string>>(\"Vencord_cloudSecret\") ?? {};\n\n const origin = cloudUrlOrigin();\n\n // we need to migrate from the old format here\n if (secrets[origin]) {\n await DataStore.update<Record<string, string>>(\"Vencord_cloudSecret\", secrets => {\n secrets ??= {};\n // use the current user ID\n secrets[`${origin}:${getUserId()}`] = secrets[origin];\n delete secrets[origin];\n return secrets;\n });\n\n // since this doesn't update the original object, we'll early return the existing authorization\n return secrets[origin];\n }\n\n return secrets[`${origin}:${getUserId()}`];\n}\n\nasync function setAuthorization(secret: string) {\n await DataStore.update<Record<string, string>>(\"Vencord_cloudSecret\", secrets => {\n secrets ??= {};\n secrets[`${cloudUrlOrigin()}:${getUserId()}`] = secret;\n return secrets;\n });\n}\n\nexport async function deauthorizeCloud() {\n await DataStore.update<Record<string, string>>(\"Vencord_cloudSecret\", secrets => {\n secrets ??= {};\n delete secrets[`${cloudUrlOrigin()}:${getUserId()}`];\n return secrets;\n });\n}\n\nexport async function authorizeCloud() {\n if (await getAuthorization() !== undefined) {\n Settings.cloud.authenticated = true;\n return;\n }\n\n try {\n const oauthConfiguration = await fetch(new URL(\"/v1/oauth/settings\", getCloudUrl()));\n var { clientId, redirectUri } = await oauthConfiguration.json();\n } catch {\n showNotification({\n title: \"Cloud Integration\",\n body: \"Setup failed (couldn't retrieve OAuth configuration).\"\n });\n Settings.cloud.authenticated = false;\n return;\n }\n\n openModal((props: any) => <OAuth2AuthorizeModal\n {...props}\n scopes={[\"identify\"]}\n responseType=\"code\"\n redirectUri={redirectUri}\n permissions={0n}\n clientId={clientId}\n cancelCompletesFlow={false}\n callback={async ({ location }: any) => {\n if (!location) {\n Settings.cloud.authenticated = false;\n return;\n }\n\n try {\n const res = await fetch(location, {\n headers: new Headers({ Accept: \"application/json\" })\n });\n const { secret } = await res.json();\n if (secret) {\n cloudLogger.info(\"Authorized with secret\");\n await setAuthorization(secret);\n showNotification({\n title: \"Cloud Integration\",\n body: \"Cloud integrations enabled!\"\n });\n Settings.cloud.authenticated = true;\n } else {\n showNotification({\n title: \"Cloud Integration\",\n body: \"Setup failed (no secret returned?).\"\n });\n Settings.cloud.authenticated = false;\n }\n } catch (e: any) {\n cloudLogger.error(\"Failed to authorize\", e);\n showNotification({\n title: \"Cloud Integration\",\n body: `Setup failed (${e.toString()}).`\n });\n Settings.cloud.authenticated = false;\n }\n }\n }\n />);\n}\n\nexport async function getCloudAuth() {\n const secret = await getAuthorization();\n\n return window.btoa(`${secret}:${getUserId()}`);\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nexport function relaunch() {\n if (IS_DISCORD_DESKTOP)\n window.DiscordNative.app.relaunch();\n else\n window.VesktopNative.app.relaunch();\n}\n\nexport function showItemInFolder(path: string) {\n if (IS_DISCORD_DESKTOP)\n window.DiscordNative.fileManager.showItemInFolder(path);\n else\n window.VesktopNative.fileManager.showItemInFolder(path);\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\n/**\n * Prompts the user to save a file to their system\n * @param file The file to save\n */\nexport function saveFile(file: File) {\n const a = document.createElement(\"a\");\n a.href = URL.createObjectURL(file);\n a.download = file.name;\n\n document.body.appendChild(a);\n a.click();\n setImmediate(() => {\n URL.revokeObjectURL(a.href);\n document.body.removeChild(a);\n });\n}\n\n/**\n * Prompts the user to choose a file from their system\n * @param mimeTypes A comma separated list of mime types to accept, see https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/accept#unique_file_type_specifiers\n * @returns A promise that resolves to the chosen file or null if the user cancels\n */\nexport function chooseFile(mimeTypes: string) {\n return new Promise<File | null>(resolve => {\n const input = document.createElement(\"input\");\n input.type = \"file\";\n input.style.display = \"none\";\n input.accept = mimeTypes;\n input.onchange = async () => {\n resolve(input.files?.[0] ?? null);\n };\n\n document.body.appendChild(input);\n input.click();\n setImmediate(() => document.body.removeChild(input));\n });\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { showNotification } from \"@api/Notifications\";\nimport { PlainSettings, Settings } from \"@api/Settings\";\nimport { Toasts } from \"@webpack/common\";\nimport { deflateSync, inflateSync } from \"fflate\";\n\nimport { getCloudAuth, getCloudUrl } from \"./cloud\";\nimport { Logger } from \"./Logger\";\nimport { relaunch } from \"./native\";\nimport { chooseFile, saveFile } from \"./web\";\n\nexport async function importSettings(data: string) {\n try {\n var parsed = JSON.parse(data);\n } catch (err) {\n console.log(data);\n throw new Error(\"Failed to parse JSON: \" + String(err));\n }\n\n if (\"settings\" in parsed && \"quickCss\" in parsed) {\n Object.assign(PlainSettings, parsed.settings);\n await VencordNative.settings.set(JSON.stringify(parsed.settings, null, 4));\n await VencordNative.quickCss.set(parsed.quickCss);\n } else\n throw new Error(\"Invalid Settings. Is this even a Vencord Settings file?\");\n}\n\nexport async function exportSettings({ minify }: { minify?: boolean; } = {}) {\n const settings = JSON.parse(VencordNative.settings.get());\n const quickCss = await VencordNative.quickCss.get();\n return JSON.stringify({ settings, quickCss }, null, minify ? undefined : 4);\n}\n\nexport async function downloadSettingsBackup() {\n const filename = \"vencord-settings-backup.json\";\n const backup = await exportSettings();\n const data = new TextEncoder().encode(backup);\n\n if (IS_DISCORD_DESKTOP) {\n DiscordNative.fileManager.saveWithDialog(data, filename);\n } else {\n saveFile(new File([data], filename, { type: \"application/json\" }));\n }\n}\n\nconst toast = (type: number, message: string) =>\n Toasts.show({\n type,\n message,\n id: Toasts.genId()\n });\n\nconst toastSuccess = () =>\n toast(Toasts.Type.SUCCESS, \"Settings successfully imported. Restart to apply changes!\");\n\nconst toastFailure = (err: any) =>\n toast(Toasts.Type.FAILURE, `Failed to import settings: ${String(err)}`);\n\nexport async function uploadSettingsBackup(showToast = true): Promise<void> {\n if (IS_DISCORD_DESKTOP) {\n const [file] = await DiscordNative.fileManager.openFiles({\n filters: [\n { name: \"Vencord Settings Backup\", extensions: [\"json\"] },\n { name: \"all\", extensions: [\"*\"] }\n ]\n });\n\n if (file) {\n try {\n await importSettings(new TextDecoder().decode(file.data));\n if (showToast) toastSuccess();\n } catch (err) {\n new Logger(\"SettingsSync\").error(err);\n if (showToast) toastFailure(err);\n }\n }\n } else {\n const file = await chooseFile(\"application/json\");\n if (!file) return;\n\n const reader = new FileReader();\n reader.onload = async () => {\n try {\n await importSettings(reader.result as string);\n if (showToast) toastSuccess();\n } catch (err) {\n new Logger(\"SettingsSync\").error(err);\n if (showToast) toastFailure(err);\n }\n };\n reader.readAsText(file);\n }\n}\n\n// Cloud settings\nconst cloudSettingsLogger = new Logger(\"Cloud:Settings\", \"#39b7e0\");\n\nexport async function putCloudSettings(manual?: boolean) {\n const settings = await exportSettings({ minify: true });\n\n try {\n const res = await fetch(new URL(\"/v1/settings\", getCloudUrl()), {\n method: \"PUT\",\n headers: new Headers({\n Authorization: await getCloudAuth(),\n \"Content-Type\": \"application/octet-stream\"\n }),\n body: deflateSync(new TextEncoder().encode(settings))\n });\n\n if (!res.ok) {\n cloudSettingsLogger.error(`Failed to sync up, API returned ${res.status}`);\n showNotification({\n title: \"Cloud Settings\",\n body: `Could not synchronize settings to cloud (API returned ${res.status}).`,\n color: \"var(--red-360)\"\n });\n return;\n }\n\n const { written } = await res.json();\n PlainSettings.cloud.settingsSyncVersion = written;\n VencordNative.settings.set(JSON.stringify(PlainSettings, null, 4));\n\n cloudSettingsLogger.info(\"Settings uploaded to cloud successfully\");\n\n if (manual) {\n showNotification({\n title: \"Cloud Settings\",\n body: \"Synchronized settings to the cloud!\",\n noPersist: true,\n });\n }\n } catch (e: any) {\n cloudSettingsLogger.error(\"Failed to sync up\", e);\n showNotification({\n title: \"Cloud Settings\",\n body: `Could not synchronize settings to the cloud (${e.toString()}).`,\n color: \"var(--red-360)\"\n });\n }\n}\n\nexport async function getCloudSettings(shouldNotify = true, force = false) {\n try {\n const res = await fetch(new URL(\"/v1/settings\", getCloudUrl()), {\n method: \"GET\",\n headers: new Headers({\n Authorization: await getCloudAuth(),\n Accept: \"application/octet-stream\",\n \"If-None-Match\": Settings.cloud.settingsSyncVersion.toString()\n }),\n });\n\n if (res.status === 404) {\n cloudSettingsLogger.info(\"No settings on the cloud\");\n if (shouldNotify)\n showNotification({\n title: \"Cloud Settings\",\n body: \"There are no settings in the cloud.\",\n noPersist: true\n });\n return false;\n }\n\n if (res.status === 304) {\n cloudSettingsLogger.info(\"Settings up to date\");\n if (shouldNotify)\n showNotification({\n title: \"Cloud Settings\",\n body: \"Your settings are up to date.\",\n noPersist: true\n });\n return false;\n }\n\n if (!res.ok) {\n cloudSettingsLogger.error(`Failed to sync down, API returned ${res.status}`);\n showNotification({\n title: \"Cloud Settings\",\n body: `Could not synchronize settings from the cloud (API returned ${res.status}).`,\n color: \"var(--red-360)\"\n });\n return false;\n }\n\n const written = Number(res.headers.get(\"etag\")!);\n const localWritten = Settings.cloud.settingsSyncVersion;\n\n // don't need to check for written > localWritten because the server will return 304 due to if-none-match\n if (!force && written < localWritten) {\n if (shouldNotify)\n showNotification({\n title: \"Cloud Settings\",\n body: \"Your local settings are newer than the cloud ones.\",\n noPersist: true,\n });\n return;\n }\n\n const data = await res.arrayBuffer();\n\n const settings = new TextDecoder().decode(inflateSync(new Uint8Array(data)));\n await importSettings(settings);\n\n // sync with server timestamp instead of local one\n PlainSettings.cloud.settingsSyncVersion = written;\n VencordNative.settings.set(JSON.stringify(PlainSettings, null, 4));\n\n cloudSettingsLogger.info(\"Settings loaded from cloud successfully\");\n if (shouldNotify)\n showNotification({\n title: \"Cloud Settings\",\n body: \"Your settings have been updated! Click here to restart to fully apply changes!\",\n color: \"var(--green-360)\",\n onClick: IS_WEB ? () => location.reload() : relaunch,\n noPersist: true\n });\n\n return true;\n } catch (e: any) {\n cloudSettingsLogger.error(\"Failed to sync down\", e);\n showNotification({\n title: \"Cloud Settings\",\n body: `Could not synchronize settings from the cloud (${e.toString()}).`,\n color: \"var(--red-360)\"\n });\n\n return false;\n }\n}\n\nexport async function deleteCloudSettings() {\n try {\n const res = await fetch(new URL(\"/v1/settings\", getCloudUrl()), {\n method: \"DELETE\",\n headers: new Headers({\n Authorization: await getCloudAuth()\n }),\n });\n\n if (!res.ok) {\n cloudSettingsLogger.error(`Failed to delete, API returned ${res.status}`);\n showNotification({\n title: \"Cloud Settings\",\n body: `Could not delete settings (API returned ${res.status}).`,\n color: \"var(--red-360)\"\n });\n return;\n }\n\n cloudSettingsLogger.info(\"Settings deleted from cloud successfully\");\n showNotification({\n title: \"Cloud Settings\",\n body: \"Settings deleted from cloud!\",\n color: \"var(--green-360)\"\n });\n } catch (e: any) {\n cloudSettingsLogger.error(\"Failed to delete\", e);\n showNotification({\n title: \"Cloud Settings\",\n body: `Could not delete settings (${e.toString()}).`,\n color: \"var(--red-360)\"\n });\n }\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { debounce } from \"@utils/debounce\";\nimport { localStorage } from \"@utils/localStorage\";\nimport { Logger } from \"@utils/Logger\";\nimport { mergeDefaults } from \"@utils/misc\";\nimport { putCloudSettings } from \"@utils/settingsSync\";\nimport { DefinedSettings, OptionType, SettingsChecks, SettingsDefinition } from \"@utils/types\";\nimport { React } from \"@webpack/common\";\n\nimport plugins from \"~plugins\";\n\nconst logger = new Logger(\"Settings\");\nexport interface Settings {\n notifyAboutUpdates: boolean;\n autoUpdate: boolean;\n autoUpdateNotification: boolean,\n useQuickCss: boolean;\n enableReactDevtools: boolean;\n themeLinks: string[];\n enabledThemes: string[];\n frameless: boolean;\n transparent: boolean;\n winCtrlQ: boolean;\n macosVibrancyStyle:\n | \"content\"\n | \"fullscreen-ui\"\n | \"header\"\n | \"hud\"\n | \"menu\"\n | \"popover\"\n | \"selection\"\n | \"sidebar\"\n | \"titlebar\"\n | \"tooltip\"\n | \"under-page\"\n | \"window\"\n | undefined;\n macosTranslucency: boolean | undefined;\n disableMinSize: boolean;\n winNativeTitleBar: boolean;\n plugins: {\n [plugin: string]: {\n enabled: boolean;\n [setting: string]: any;\n };\n };\n\n notifications: {\n timeout: number;\n position: \"top-right\" | \"bottom-right\";\n useNative: \"always\" | \"never\" | \"not-focused\";\n logLimit: number;\n };\n\n cloud: {\n authenticated: boolean;\n url: string;\n settingsSync: boolean;\n settingsSyncVersion: number;\n };\n}\n\nconst DefaultSettings: Settings = {\n notifyAboutUpdates: true,\n autoUpdate: false,\n autoUpdateNotification: true,\n useQuickCss: true,\n themeLinks: [],\n enabledThemes: [],\n enableReactDevtools: false,\n frameless: false,\n transparent: false,\n winCtrlQ: false,\n // Replaced by macosVibrancyStyle\n macosTranslucency: undefined,\n macosVibrancyStyle: undefined,\n disableMinSize: false,\n winNativeTitleBar: false,\n plugins: {},\n\n notifications: {\n timeout: 5000,\n position: \"bottom-right\",\n useNative: \"not-focused\",\n logLimit: 50\n },\n\n cloud: {\n authenticated: false,\n url: \"https://api.vencord.dev/\",\n settingsSync: false,\n settingsSyncVersion: 0\n }\n};\n\ntry {\n var settings = JSON.parse(VencordNative.settings.get()) as Settings;\n mergeDefaults(settings, DefaultSettings);\n} catch (err) {\n var settings = mergeDefaults({} as Settings, DefaultSettings);\n logger.error(\"An error occurred while loading the settings. Corrupt settings file?\\n\", err);\n}\n\nconst saveSettingsOnFrequentAction = debounce(async () => {\n if (Settings.cloud.settingsSync && Settings.cloud.authenticated) {\n await putCloudSettings();\n delete localStorage.Vencord_settingsDirty;\n }\n}, 60_000);\n\ntype SubscriptionCallback = ((newValue: any, path: string) => void) & { _paths?: Array<string>; };\nconst subscriptions = new Set<SubscriptionCallback>();\n\nconst proxyCache = {} as Record<string, any>;\n\n// Wraps the passed settings object in a Proxy to nicely handle change listeners and default values\nfunction makeProxy(settings: any, root = settings, path = \"\"): Settings {\n return proxyCache[path] ??= new Proxy(settings, {\n get(target, p: string) {\n const v = target[p];\n\n // using \"in\" is important in the following cases to properly handle falsy or nullish values\n if (!(p in target)) {\n // Return empty for plugins with no settings\n if (path === \"plugins\" && p in plugins)\n return target[p] = makeProxy({\n enabled: plugins[p].required ?? plugins[p].enabledByDefault ?? false\n }, root, `plugins.${p}`);\n\n // Since the property is not set, check if this is a plugin's setting and if so, try to resolve\n // the default value.\n if (path.startsWith(\"plugins.\")) {\n const plugin = path.slice(\"plugins.\".length);\n if (plugin in plugins) {\n const setting = plugins[plugin].options?.[p];\n if (!setting) return v;\n if (\"default\" in setting)\n // normal setting with a default value\n return (target[p] = setting.default);\n if (setting.type === OptionType.SELECT) {\n const def = setting.options.find(o => o.default);\n if (def)\n target[p] = def.value;\n return def?.value;\n }\n }\n }\n return v;\n }\n\n // Recursively proxy Objects with the updated property path\n if (typeof v === \"object\" && !Array.isArray(v) && v !== null)\n return makeProxy(v, root, `${path}${path && \".\"}${p}`);\n\n // primitive or similar, no need to proxy further\n return v;\n },\n\n set(target, p: string, v) {\n // avoid unnecessary updates to React Components and other listeners\n if (target[p] === v) return true;\n\n target[p] = v;\n // Call any listeners that are listening to a setting of this path\n const setPath = `${path}${path && \".\"}${p}`;\n delete proxyCache[setPath];\n for (const subscription of subscriptions) {\n if (!subscription._paths || subscription._paths.includes(setPath)) {\n subscription(v, setPath);\n }\n }\n // And don't forget to persist the settings!\n PlainSettings.cloud.settingsSyncVersion = Date.now();\n localStorage.Vencord_settingsDirty = true;\n saveSettingsOnFrequentAction();\n VencordNative.settings.set(JSON.stringify(root, null, 4));\n return true;\n }\n });\n}\n\n/**\n * Same as {@link Settings} but unproxied. You should treat this as readonly,\n * as modifying properties on this will not save to disk or call settings\n * listeners.\n * WARNING: default values specified in plugin.options will not be ensured here. In other words,\n * settings for which you specified a default value may be uninitialised. If you need proper\n * handling for default values, use {@link Settings}\n */\nexport const PlainSettings = settings;\n/**\n * A smart settings object. Altering props automagically saves\n * the updated settings to disk.\n * This recursively proxies objects. If you need the object non proxied, use {@link PlainSettings}\n */\nexport const Settings = makeProxy(settings);\n\n/**\n * Settings hook for React components. Returns a smart settings\n * object that automagically triggers a rerender if any properties\n * are altered\n * @param paths An optional list of paths to whitelist for rerenders\n * @returns Settings\n */\n// TODO: Representing paths as essentially \"string[].join('.')\" wont allow dots in paths, change to \"paths?: string[][]\" later\nexport function useSettings(paths?: UseSettings<Settings>[]) {\n const [, forceUpdate] = React.useReducer(() => ({}), {});\n\n const onUpdate: SubscriptionCallback = paths\n ? (value, path) => paths.includes(path as UseSettings<Settings>) && forceUpdate()\n : forceUpdate;\n\n React.useEffect(() => {\n subscriptions.add(onUpdate);\n return () => void subscriptions.delete(onUpdate);\n }, []);\n\n return Settings;\n}\n\n// Resolves a possibly nested prop in the form of \"some.nested.prop\" to type of T.some.nested.prop\ntype ResolvePropDeep<T, P> = P extends \"\" ? T :\n P extends `${infer Pre}.${infer Suf}` ?\n Pre extends keyof T ? ResolvePropDeep<T[Pre], Suf> : never : P extends keyof T ? T[P] : never;\n\n/**\n * Add a settings listener that will be invoked whenever the desired setting is updated\n * @param path Path to the setting that you want to watch, for example \"plugins.Unindent.enabled\" will fire your callback\n * whenever Unindent is toggled. Pass an empty string to get notified for all changes\n * @param onUpdate Callback function whenever a setting matching path is updated. It gets passed the new value and the path\n * to the updated setting. This path will be the same as your path argument, unless it was an empty string.\n *\n * @example addSettingsListener(\"\", (newValue, path) => console.log(`${path} is now ${newValue}`))\n * addSettingsListener(\"plugins.Unindent.enabled\", v => console.log(\"Unindent is now\", v ? \"enabled\" : \"disabled\"))\n */\nexport function addSettingsListener<Path extends keyof Settings>(path: Path, onUpdate: (newValue: Settings[Path], path: Path) => void): void;\nexport function addSettingsListener<Path extends string>(path: Path, onUpdate: (newValue: Path extends \"\" ? any : ResolvePropDeep<Settings, Path>, path: Path extends \"\" ? string : Path) => void): void;\nexport function addSettingsListener(path: string, onUpdate: (newValue: any, path: string) => void) {\n if (path)\n ((onUpdate as SubscriptionCallback)._paths ??= []).push(path);\n subscriptions.add(onUpdate);\n}\n\nexport function migratePluginSettings(name: string, ...oldNames: string[]) {\n const { plugins } = settings;\n if (name in plugins) return;\n\n for (const oldName of oldNames) {\n if (oldName in plugins) {\n logger.info(`Migrating settings from old name ${oldName} to ${name}`);\n plugins[name] = plugins[oldName];\n delete plugins[oldName];\n VencordNative.settings.set(JSON.stringify(settings, null, 4));\n break;\n }\n }\n}\n\nexport function definePluginSettings<\n Def extends SettingsDefinition,\n Checks extends SettingsChecks<Def>,\n PrivateSettings extends object = {}\n>(def: Def, checks?: Checks) {\n const definedSettings: DefinedSettings<Def, Checks, PrivateSettings> = {\n get store() {\n if (!definedSettings.pluginName) throw new Error(\"Cannot access settings before plugin is initialized\");\n return Settings.plugins[definedSettings.pluginName] as any;\n },\n use: settings => useSettings(\n settings?.map(name => `plugins.${definedSettings.pluginName}.${name}`) as UseSettings<Settings>[]\n ).plugins[definedSettings.pluginName] as any,\n def,\n checks: checks ?? {} as any,\n pluginName: \"\",\n\n withPrivateSettings<T extends object>() {\n return this as DefinedSettings<Def, Checks, T>;\n }\n };\n\n return definedSettings;\n}\n\ntype UseSettings<T extends object> = ResolveUseSettings<T>[keyof T];\n\ntype ResolveUseSettings<T extends object> = {\n [Key in keyof T]:\n Key extends string\n ? T[Key] extends Record<string, unknown>\n // @ts-ignore \"Type instantiation is excessively deep and possibly infinite\"\n ? UseSettings<T[Key]> extends string ? `${Key}.${UseSettings<T[Key]>}` : never\n : Key\n : never;\n};\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport gitHash from \"~git-hash\";\n\nimport { Logger } from \"./Logger\";\nimport { relaunch } from \"./native\";\nimport { IpcRes } from \"./types\";\n\nexport const UpdateLogger = /* #__PURE__*/ new Logger(\"Updater\", \"white\");\nexport let isOutdated = false;\nexport let isNewer = false;\nexport let updateError: any;\nexport let changes: Record<\"hash\" | \"author\" | \"message\", string>[];\n\nasync function Unwrap<T>(p: Promise<IpcRes<T>>) {\n const res = await p;\n\n if (res.ok) return res.value;\n\n updateError = res.error;\n throw res.error;\n}\n\nexport async function checkForUpdates() {\n changes = await Unwrap(VencordNative.updater.getUpdates());\n if (changes.some(c => c.hash === gitHash)) {\n isNewer = true;\n return (isOutdated = false);\n }\n return (isOutdated = changes.length > 0);\n}\n\nexport async function update() {\n if (!isOutdated) return true;\n\n const res = await Unwrap(VencordNative.updater.update());\n\n if (res) {\n isOutdated = false;\n if (!await Unwrap(VencordNative.updater.rebuild()))\n throw new Error(\"The Build failed. Please try manually building the new update\");\n }\n\n return res;\n}\n\nexport const getRepo = () => Unwrap(VencordNative.updater.getRepo());\n\nexport async function maybePromptToUpdate(confirmMessage: string, checkForDev = false) {\n if (IS_WEB || IS_UPDATER_DISABLED) return;\n if (checkForDev && IS_DEV) return;\n\n try {\n const isOutdated = await checkForUpdates();\n if (isOutdated) {\n const wantsUpdate = confirm(confirmMessage);\n if (wantsUpdate && isNewer) return alert(\"Your local copy has more recent commits. Please stash or reset them.\");\n if (wantsUpdate) {\n await update();\n relaunch();\n }\n }\n } catch (err) {\n UpdateLogger.error(err);\n alert(\"That also failed :( Try updating or re-installing with the installer!\");\n }\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { maybePromptToUpdate } from \"@utils/updater\";\n\nexport function handleComponentFailed() {\n maybePromptToUpdate(\n \"Uh Oh! Failed to render this Page.\" +\n \" However, there is an update available that might fix it.\" +\n \" Would you like to update and restart now?\"\n );\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nexport function onlyOnce<F extends Function>(f: F): F {\n let called = false;\n let result: any;\n return function onlyOnceWrapper(this: unknown) {\n if (called) return result;\n\n called = true;\n\n return (result = f.apply(this, arguments));\n } as unknown as F;\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport \"./settingsStyles.css\";\nimport \"./themesStyles.css\";\n\nimport ErrorBoundary from \"@components/ErrorBoundary\";\nimport { handleComponentFailed } from \"@components/handleComponentFailed\";\nimport { Margins } from \"@utils/margins\";\nimport { onlyOnce } from \"@utils/onlyOnce\";\nimport { Forms, Text } from \"@webpack/common\";\nimport type { ComponentType, PropsWithChildren } from \"react\";\n\nexport function SettingsTab({ title, children }: PropsWithChildren<{ title: string; }>) {\n return (\n <Forms.FormSection>\n <Text\n variant=\"heading-lg/semibold\"\n tag=\"h2\"\n className={Margins.bottom16}\n >\n {title}\n </Text>\n\n {children}\n </Forms.FormSection>\n );\n}\n\nconst onError = onlyOnce(handleComponentFailed);\n\nexport function wrapTab(component: ComponentType, tab: string) {\n return ErrorBoundary.wrap(component, {\n message: `Failed to render the ${tab} tab. If this issue persists, try using the installer to reinstall!`,\n onError,\n });\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { openNotificationLogModal } from \"@api/Notifications/notificationLog\";\nimport { Settings, useSettings } from \"@api/Settings\";\nimport { classNameFactory } from \"@api/Styles\";\nimport DonateButton from \"@components/DonateButton\";\nimport { ErrorCard } from \"@components/ErrorCard\";\nimport { Margins } from \"@utils/margins\";\nimport { identity } from \"@utils/misc\";\nimport { relaunch, showItemInFolder } from \"@utils/native\";\nimport { useAwaiter } from \"@utils/react\";\nimport { Button, Card, Forms, React, Select, Slider, Switch } from \"@webpack/common\";\n\nimport { SettingsTab, wrapTab } from \"./shared\";\n\nconst cl = classNameFactory(\"vc-settings-\");\n\nconst DEFAULT_DONATE_IMAGE = \"https://cdn.discordapp.com/emojis/1026533090627174460.png\";\nconst SHIGGY_DONATE_IMAGE = \"https://media.discordapp.net/stickers/1039992459209490513.png\";\n\ntype KeysOfType<Object, Type> = {\n [K in keyof Object]: Object[K] extends Type ? K : never;\n}[keyof Object];\n\nfunction VencordSettings() {\n const [settingsDir, , settingsDirPending] = useAwaiter(VencordNative.settings.getSettingsDir, {\n fallbackValue: \"Loading...\"\n });\n const settings = useSettings();\n\n const donateImage = React.useMemo(() => Math.random() > 0.5 ? DEFAULT_DONATE_IMAGE : SHIGGY_DONATE_IMAGE, []);\n\n const isWindows = navigator.platform.toLowerCase().startsWith(\"win\");\n const isMac = navigator.platform.toLowerCase().startsWith(\"mac\");\n const needsVibrancySettings = IS_DISCORD_DESKTOP && isMac;\n\n // One-time migration of the old setting to the new one if necessary.\n React.useEffect(() => {\n if (settings.macosTranslucency === true && !settings.macosVibrancyStyle) {\n settings.macosVibrancyStyle = \"sidebar\";\n settings.macosTranslucency = undefined;\n }\n }, []);\n\n const Switches: Array<false | {\n key: KeysOfType<typeof settings, boolean>;\n title: string;\n note: string;\n }> =\n [\n {\n key: \"useQuickCss\",\n title: \"Enable Custom CSS\",\n note: \"Loads your Custom CSS\"\n },\n !IS_WEB && {\n key: \"enableReactDevtools\",\n title: \"Enable React Developer Tools\",\n note: \"Requires a full restart\"\n },\n !IS_WEB && (!IS_DISCORD_DESKTOP || !isWindows ? {\n key: \"frameless\",\n title: \"Disable the window frame\",\n note: \"Requires a full restart\"\n } : {\n key: \"winNativeTitleBar\",\n title: \"Use Windows' native title bar instead of Discord's custom one\",\n note: \"Requires a full restart\"\n }),\n !IS_WEB && false /* This causes electron to freeze / white screen for some people */ && {\n key: \"transparent\",\n title: \"Enable window transparency\",\n note: \"Requires a full restart\"\n },\n !IS_WEB && isWindows && {\n key: \"winCtrlQ\",\n title: \"Register Ctrl+Q as shortcut to close Discord (Alternative to Alt+F4)\",\n note: \"Requires a full restart\"\n },\n IS_DISCORD_DESKTOP && {\n key: \"disableMinSize\",\n title: \"Disable minimum window size\",\n note: \"Requires a full restart\"\n },\n ];\n\n return (\n <SettingsTab title=\"Vencord Settings\">\n <DonateCard image={donateImage} />\n <Forms.FormSection title=\"Quick Actions\">\n <Card className={cl(\"quick-actions-card\")}>\n <React.Fragment>\n {!IS_WEB && (\n <Button\n onClick={relaunch}\n size={Button.Sizes.SMALL}>\n Restart Client\n </Button>\n )}\n <Button\n onClick={() => VencordNative.quickCss.openEditor()}\n size={Button.Sizes.SMALL}\n disabled={settingsDir === \"Loading...\"}>\n Open QuickCSS File\n </Button>\n {!IS_WEB && (\n <Button\n onClick={() => showItemInFolder(settingsDir)}\n size={Button.Sizes.SMALL}\n disabled={settingsDirPending}>\n Open Settings Folder\n </Button>\n )}\n <Button\n onClick={() => VencordNative.native.openExternal(\"https://github.com/Vendicated/Vencord\")}\n size={Button.Sizes.SMALL}\n disabled={settingsDirPending}>\n Open in GitHub\n </Button>\n </React.Fragment>\n </Card>\n </Forms.FormSection>\n\n <Forms.FormDivider />\n\n <Forms.FormSection className={Margins.top16} title=\"Settings\" tag=\"h5\">\n <Forms.FormText className={Margins.bottom20}>\n Hint: You can change the position of this settings section in the settings of the \"Settings\" plugin!\n </Forms.FormText>\n {Switches.map(s => s && (\n <Switch\n key={s.key}\n value={settings[s.key]}\n onChange={v => settings[s.key] = v}\n note={s.note}\n >\n {s.title}\n </Switch>\n ))}\n </Forms.FormSection>\n\n\n {needsVibrancySettings && <>\n <Forms.FormTitle tag=\"h5\">Window vibrancy style (requires restart)</Forms.FormTitle>\n <Select\n className={Margins.bottom20}\n placeholder=\"Window vibrancy style\"\n options={[\n // Sorted from most opaque to most transparent\n {\n label: \"No vibrancy\", default: !settings.macosTranslucency, value: undefined\n },\n {\n label: \"Under Page (window tinting)\",\n value: \"under-page\"\n },\n {\n label: \"Content\",\n value: \"content\"\n },\n {\n label: \"Window\",\n value: \"window\"\n },\n {\n label: \"Selection\",\n value: \"selection\"\n },\n {\n label: \"Titlebar\",\n value: \"titlebar\"\n },\n {\n label: \"Header\",\n value: \"header\"\n },\n {\n label: \"Sidebar (old value for transparent windows)\",\n value: \"sidebar\",\n default: settings.macosTranslucency\n },\n {\n label: \"Tooltip\",\n value: \"tooltip\"\n },\n {\n label: \"Menu\",\n value: \"menu\"\n },\n {\n label: \"Popover\",\n value: \"popover\"\n },\n {\n label: \"Fullscreen UI (transparent but slightly muted)\",\n value: \"fullscreen-ui\"\n },\n {\n label: \"HUD (Most transparent)\",\n value: \"hud\"\n },\n ]}\n select={v => settings.macosVibrancyStyle = v}\n isSelected={v => settings.macosVibrancyStyle === v}\n serialize={identity} />\n </>}\n\n {typeof Notification !== \"undefined\" && <NotificationSection settings={settings.notifications} />}\n </SettingsTab>\n );\n}\n\nfunction NotificationSection({ settings }: { settings: typeof Settings[\"notifications\"]; }) {\n return (\n <>\n <Forms.FormTitle tag=\"h5\">Notification Style</Forms.FormTitle>\n {settings.useNative !== \"never\" && Notification?.permission === \"denied\" && (\n <ErrorCard style={{ padding: \"1em\" }} className={Margins.bottom8}>\n <Forms.FormTitle tag=\"h5\">Desktop Notification Permission denied</Forms.FormTitle>\n <Forms.FormText>You have denied Notification Permissions. Thus, Desktop notifications will not work!</Forms.FormText>\n </ErrorCard>\n )}\n <Forms.FormText className={Margins.bottom8}>\n Some plugins may show you notifications. These come in two styles:\n <ul>\n <li><strong>Vencord Notifications</strong>: These are in-app notifications</li>\n <li><strong>Desktop Notifications</strong>: Native Desktop notifications (like when you get a ping)</li>\n </ul>\n </Forms.FormText>\n <Select\n placeholder=\"Notification Style\"\n options={[\n { label: \"Only use Desktop notifications when Discord is not focused\", value: \"not-focused\", default: true },\n { label: \"Always use Desktop notifications\", value: \"always\" },\n { label: \"Always use Vencord notifications\", value: \"never\" },\n ] satisfies Array<{ value: typeof settings[\"useNative\"]; } & Record<string, any>>}\n closeOnSelect={true}\n select={v => settings.useNative = v}\n isSelected={v => v === settings.useNative}\n serialize={identity}\n />\n\n <Forms.FormTitle tag=\"h5\" className={Margins.top16 + \" \" + Margins.bottom8}>Notification Position</Forms.FormTitle>\n <Select\n isDisabled={settings.useNative === \"always\"}\n placeholder=\"Notification Position\"\n options={[\n { label: \"Bottom Right\", value: \"bottom-right\", default: true },\n { label: \"Top Right\", value: \"top-right\" },\n ] satisfies Array<{ value: typeof settings[\"position\"]; } & Record<string, any>>}\n select={v => settings.position = v}\n isSelected={v => v === settings.position}\n serialize={identity}\n />\n\n <Forms.FormTitle tag=\"h5\" className={Margins.top16 + \" \" + Margins.bottom8}>Notification Timeout</Forms.FormTitle>\n <Forms.FormText className={Margins.bottom16}>Set to 0s to never automatically time out</Forms.FormText>\n <Slider\n disabled={settings.useNative === \"always\"}\n markers={[0, 1000, 2500, 5000, 10_000, 20_000]}\n minValue={0}\n maxValue={20_000}\n initialValue={settings.timeout}\n onValueChange={v => settings.timeout = v}\n onValueRender={v => (v / 1000).toFixed(2) + \"s\"}\n onMarkerRender={v => (v / 1000) + \"s\"}\n stickToMarkers={false}\n />\n\n <Forms.FormTitle tag=\"h5\" className={Margins.top16 + \" \" + Margins.bottom8}>Notification Log Limit</Forms.FormTitle>\n <Forms.FormText className={Margins.bottom16}>\n The amount of notifications to save in the log until old ones are removed.\n Set to <code>0</code> to disable Notification log and <code>\u221E</code> to never automatically remove old Notifications\n </Forms.FormText>\n <Slider\n markers={[0, 25, 50, 75, 100, 200]}\n minValue={0}\n maxValue={200}\n stickToMarkers={true}\n initialValue={settings.logLimit}\n onValueChange={v => settings.logLimit = v}\n onValueRender={v => v === 200 ? \"\u221E\" : v}\n onMarkerRender={v => v === 200 ? \"\u221E\" : v}\n />\n\n <Button\n onClick={openNotificationLogModal}\n disabled={settings.logLimit === 0}\n >\n Open Notification Log\n </Button>\n </>\n );\n}\n\ninterface DonateCardProps {\n image: string;\n}\n\nfunction DonateCard({ image }: DonateCardProps) {\n return (\n <Card className={cl(\"card\", \"donate\")}>\n <div>\n <Forms.FormTitle tag=\"h5\">Support the Project</Forms.FormTitle>\n <Forms.FormText>Please consider supporting the development of Vencord by donating!</Forms.FormText>\n <DonateButton style={{ transform: \"translateX(-1em)\" }} />\n </div>\n <img\n role=\"presentation\"\n src={image}\n alt=\"\"\n height={128}\n style={{\n imageRendering: image === SHIGGY_DONATE_IMAGE ? \"pixelated\" : void 0,\n marginLeft: \"auto\",\n transform: image === DEFAULT_DONATE_IMAGE ? \"rotate(10deg)\" : void 0\n }}\n />\n </Card>\n );\n}\n\nexport default wrapTab(VencordSettings, \"Vencord Settings\");\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { waitFor } from \"@webpack\";\n\nlet NoticesModule: any;\nwaitFor(m => m.show && m.dismiss && !m.suppressAll, m => NoticesModule = m);\n\nexport const noticesQueue = [] as any[];\nexport let currentNotice: any = null;\n\nexport function popNotice() {\n NoticesModule.dismiss();\n}\n\nexport function nextNotice() {\n currentNotice = noticesQueue.shift();\n\n if (currentNotice) {\n NoticesModule.show(...currentNotice, \"VencordNotice\");\n }\n}\n\nexport function showNotice(message: string, buttonText: string, onOkClick: () => void) {\n noticesQueue.push([\"GENERIC\", message, buttonText, onOkClick]);\n if (!currentNotice) nextNotice();\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport \"./iconStyles.css\";\n\nimport { classes } from \"@utils/misc\";\nimport { i18n } from \"@webpack/common\";\nimport type { PropsWithChildren, SVGProps } from \"react\";\n\ninterface BaseIconProps extends IconProps {\n viewBox: string;\n}\n\ninterface IconProps extends SVGProps<SVGSVGElement> {\n className?: string;\n height?: string | number;\n width?: string | number;\n}\n\nfunction Icon({ height = 24, width = 24, className, children, viewBox, ...svgProps }: PropsWithChildren<BaseIconProps>) {\n return (\n <svg\n className={classes(className, \"vc-icon\")}\n role=\"img\"\n width={width}\n height={height}\n viewBox={viewBox}\n {...svgProps}\n >\n {children}\n </svg>\n );\n}\n\n/**\n * Discord's link icon, as seen in the Message context menu \"Copy Message Link\" option\n */\nexport function LinkIcon({ height = 24, width = 24, className }: IconProps) {\n return (\n <Icon\n height={height}\n width={width}\n className={classes(className, \"vc-link-icon\")}\n viewBox=\"0 0 24 24\"\n >\n <g fill=\"none\" fill-rule=\"evenodd\">\n <path fill=\"currentColor\" d=\"M10.59 13.41c.41.39.41 1.03 0 1.42-.39.39-1.03.39-1.42 0a5.003 5.003 0 0 1 0-7.07l3.54-3.54a5.003 5.003 0 0 1 7.07 0 5.003 5.003 0 0 1 0 7.07l-1.49 1.49c.01-.82-.12-1.64-.4-2.42l.47-.48a2.982 2.982 0 0 0 0-4.24 2.982 2.982 0 0 0-4.24 0l-3.53 3.53a2.982 2.982 0 0 0 0 4.24zm2.82-4.24c.39-.39 1.03-.39 1.42 0a5.003 5.003 0 0 1 0 7.07l-3.54 3.54a5.003 5.003 0 0 1-7.07 0 5.003 5.003 0 0 1 0-7.07l1.49-1.49c-.01.82.12 1.64.4 2.43l-.47.47a2.982 2.982 0 0 0 0 4.24 2.982 2.982 0 0 0 4.24 0l3.53-3.53a2.982 2.982 0 0 0 0-4.24.973.973 0 0 1 0-1.42z\" />\n <rect width={width} height={height} />\n </g>\n </Icon>\n );\n}\n\n/**\n * Discord's copy icon, as seen in the user popout right of the username when clicking\n * your own username in the bottom left user panel\n */\nexport function CopyIcon(props: IconProps) {\n return (\n <Icon\n {...props}\n className={classes(props.className, \"vc-copy-icon\")}\n viewBox=\"0 0 24 24\"\n >\n <g fill=\"currentColor\">\n <path d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1z\" />\n <path d=\"M15 5H8c-1.1 0-1.99.9-1.99 2L6 21c0 1.1.89 2 1.99 2H19c1.1 0 2-.9 2-2V11l-6-6zM8 21V7h6v5h5v9H8z\" />\n </g>\n </Icon>\n );\n}\n\n/**\n * Discord's open external icon, as seen in the user profile connections\n */\nexport function OpenExternalIcon(props: IconProps) {\n return (\n <Icon\n {...props}\n className={classes(props.className, \"vc-open-external-icon\")}\n viewBox=\"0 0 24 24\"\n >\n <polygon\n fill=\"currentColor\"\n fillRule=\"nonzero\"\n points=\"13 20 11 20 11 8 5.5 13.5 4.08 12.08 12 4.16 19.92 12.08 18.5 13.5 13 8\"\n />\n </Icon>\n );\n}\n\nexport function ImageIcon(props: IconProps) {\n return (\n <Icon\n {...props}\n className={classes(props.className, \"vc-image-icon\")}\n viewBox=\"0 0 24 24\"\n >\n <path fill=\"currentColor\" d=\"M21,19V5c0,-1.1 -0.9,-2 -2,-2H5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2zM8.5,13.5l2.5,3.01L14.5,12l4.5,6H5l3.5,-4.5z\" />\n </Icon>\n );\n}\n\nexport function InfoIcon(props: IconProps) {\n return (\n <Icon\n {...props}\n className={classes(props.className, \"vc-info-icon\")}\n viewBox=\"0 0 24 24\"\n >\n <path\n fill=\"currentColor\"\n transform=\"translate(2 2)\"\n d=\"M9,7 L11,7 L11,5 L9,5 L9,7 Z M10,18 C5.59,18 2,14.41 2,10 C2,5.59 5.59,2 10,2 C14.41,2 18,5.59 18,10 C18,14.41 14.41,18 10,18 L10,18 Z M10,4.4408921e-16 C4.4771525,-1.77635684e-15 4.4408921e-16,4.4771525 0,10 C-1.33226763e-15,12.6521649 1.0535684,15.195704 2.92893219,17.0710678 C4.80429597,18.9464316 7.3478351,20 10,20 C12.6521649,20 15.195704,18.9464316 17.0710678,17.0710678 C18.9464316,15.195704 20,12.6521649 20,10 C20,7.3478351 18.9464316,4.80429597 17.0710678,2.92893219 C15.195704,1.0535684 12.6521649,2.22044605e-16 10,0 L10,4.4408921e-16 Z M9,15 L11,15 L11,9 L9,9 L9,15 L9,15 Z\"\n />\n </Icon>\n );\n}\n\nexport function OwnerCrownIcon(props: IconProps) {\n return (\n <Icon\n aria-label={i18n.Messages.GUILD_OWNER}\n {...props}\n className={classes(props.className, \"vc-owner-crown-icon\")}\n role=\"img\"\n viewBox=\"0 0 16 16\"\n >\n <path\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M13.6572 5.42868C13.8879 5.29002 14.1806 5.30402 14.3973 5.46468C14.6133 5.62602 14.7119 5.90068 14.6473 6.16202L13.3139 11.4954C13.2393 11.7927 12.9726 12.0007 12.6666 12.0007H3.33325C3.02725 12.0007 2.76058 11.792 2.68592 11.4954L1.35258 6.16202C1.28792 5.90068 1.38658 5.62602 1.60258 5.46468C1.81992 5.30468 2.11192 5.29068 2.34325 5.42868L5.13192 7.10202L7.44592 3.63068C7.46173 3.60697 7.48377 3.5913 7.50588 3.57559C7.5192 3.56612 7.53255 3.55663 7.54458 3.54535L6.90258 2.90268C6.77325 2.77335 6.77325 2.56068 6.90258 2.43135L7.76458 1.56935C7.89392 1.44002 8.10658 1.44002 8.23592 1.56935L9.09792 2.43135C9.22725 2.56068 9.22725 2.77335 9.09792 2.90268L8.45592 3.54535C8.46794 3.55686 8.48154 3.56651 8.49516 3.57618C8.51703 3.5917 8.53897 3.60727 8.55458 3.63068L10.8686 7.10202L13.6572 5.42868ZM2.66667 12.6673H13.3333V14.0007H2.66667V12.6673Z\"\n />\n </Icon>\n );\n}\n\n/**\n * Discord's screenshare icon, as seen in the connection panel\n */\nexport function ScreenshareIcon(props: IconProps) {\n return (\n <Icon\n {...props}\n className={classes(props.className, \"vc-screenshare-icon\")}\n viewBox=\"0 0 24 24\"\n >\n <path\n fill=\"currentColor\"\n d=\"M2 4.5C2 3.397 2.897 2.5 4 2.5H20C21.103 2.5 22 3.397 22 4.5V15.5C22 16.604 21.103 17.5 20 17.5H13V19.5H17V21.5H7V19.5H11V17.5H4C2.897 17.5 2 16.604 2 15.5V4.5ZM13.2 14.3375V11.6C9.864 11.6 7.668 12.6625 6 15C6.672 11.6625 8.532 8.3375 13.2 7.6625V5L18 9.6625L13.2 14.3375Z\"\n />\n </Icon>\n );\n}\n\nexport function ImageVisible(props: IconProps) {\n return (\n <Icon\n {...props}\n className={classes(props.className, \"vc-image-visible\")}\n viewBox=\"0 0 24 24\"\n >\n <path fill=\"currentColor\" d=\"M5 21q-.825 0-1.413-.587Q3 19.825 3 19V5q0-.825.587-1.413Q4.175 3 5 3h14q.825 0 1.413.587Q21 4.175 21 5v14q0 .825-.587 1.413Q19.825 21 19 21Zm0-2h14V5H5v14Zm1-2h12l-3.75-5-3 4L9 13Zm-1 2V5v14Z\" />\n </Icon>\n );\n}\n\nexport function ImageInvisible(props: IconProps) {\n return (\n <Icon\n {...props}\n className={classes(props.className, \"vc-image-invisible\")}\n viewBox=\"0 0 24 24\"\n >\n <path fill=\"currentColor\" d=\"m21 18.15-2-2V5H7.85l-2-2H19q.825 0 1.413.587Q21 4.175 21 5Zm-1.2 4.45L18.2 21H5q-.825 0-1.413-.587Q3 19.825 3 19V5.8L1.4 4.2l1.4-1.4 18.4 18.4ZM6 17l3-4 2.25 3 .825-1.1L5 7.825V19h11.175l-2-2Zm7.425-6.425ZM10.6 13.4Z\" />\n </Icon>\n );\n}\n\nexport function Microphone(props: IconProps) {\n return (\n <Icon\n {...props}\n className={classes(props.className, \"vc-microphone\")}\n viewBox=\"0 0 24 24\"\n >\n <path fillRule=\"evenodd\" clipRule=\"evenodd\" d=\"M14.99 11C14.99 12.66 13.66 14 12 14C10.34 14 9 12.66 9 11V5C9 3.34 10.34 2 12 2C13.66 2 15 3.34 15 5L14.99 11ZM12 16.1C14.76 16.1 17.3 14 17.3 11H19C19 14.42 16.28 17.24 13 17.72V21H11V17.72C7.72 17.23 5 14.41 5 11H6.7C6.7 14 9.24 16.1 12 16.1ZM12 4C11.2 4 11 4.66667 11 5V11C11 11.3333 11.2 12 12 12C12.8 12 13 11.3333 13 11V5C13 4.66667 12.8 4 12 4Z\" fill=\"currentColor\" />\n <path fillRule=\"evenodd\" clipRule=\"evenodd\" d=\"M14.99 11C14.99 12.66 13.66 14 12 14C10.34 14 9 12.66 9 11V5C9 3.34 10.34 2 12 2C13.66 2 15 3.34 15 5L14.99 11ZM12 16.1C14.76 16.1 17.3 14 17.3 11H19C19 14.42 16.28 17.24 13 17.72V22H11V17.72C7.72 17.23 5 14.41 5 11H6.7C6.7 14 9.24 16.1 12 16.1Z\" fill=\"currentColor\" />\n </Icon >\n );\n}\n\nexport function CogWheel(props: IconProps) {\n return (\n <Icon\n {...props}\n className={classes(props.className, \"vc-cog-wheel\")}\n viewBox=\"0 0 24 24\"\n >\n <path\n clipRule=\"evenodd\"\n fill=\"currentColor\"\n d=\"M19.738 10H22V14H19.739C19.498 14.931 19.1 15.798 18.565 16.564L20 18L18 20L16.565 18.564C15.797 19.099 14.932 19.498 14 19.738V22H10V19.738C9.069 19.498 8.203 19.099 7.436 18.564L6 20L4 18L5.436 16.564C4.901 15.799 4.502 14.932 4.262 14H2V10H4.262C4.502 9.068 4.9 8.202 5.436 7.436L4 6L6 4L7.436 5.436C8.202 4.9 9.068 4.502 10 4.262V2H14V4.261C14.932 4.502 15.797 4.9 16.565 5.435L18 3.999L20 5.999L18.564 7.436C19.099 8.202 19.498 9.069 19.738 10ZM12 16C14.2091 16 16 14.2091 16 12C16 9.79086 14.2091 8 12 8C9.79086 8 8 9.79086 8 12C8 14.2091 9.79086 16 12 16Z\"\n />\n </Icon>\n );\n}\n\nexport function ReplyIcon(props: IconProps) {\n return (\n <Icon\n {...props}\n className={classes(props.className, \"vc-reply-icon\")}\n viewBox=\"0 0 24 24\"\n >\n <path\n fill=\"currentColor\"\n d=\"M10 8.26667V4L3 11.4667L10 18.9333V14.56C15 14.56 18.5 16.2667 21 20C20 14.6667 17 9.33333 10 8.26667Z\"\n />\n </Icon>\n );\n}\n\nexport function DeleteIcon(props: IconProps) {\n return (\n <Icon\n {...props}\n className={classes(props.className, \"vc-delete-icon\")}\n viewBox=\"0 0 24 24\"\n >\n <path\n fill=\"currentColor\"\n d=\"M15 3.999V2H9V3.999H3V5.999H21V3.999H15Z\"\n />\n <path\n fill=\"currentColor\"\n d=\"M5 6.99902V18.999C5 20.101 5.897 20.999 7 20.999H17C18.103 20.999 19 20.101 19 18.999V6.99902H5ZM11 17H9V11H11V17ZM15 17H13V11H15V17Z\"\n />\n </Icon>\n );\n}\n\nexport function PlusIcon(props: IconProps) {\n return (\n <Icon\n {...props}\n className={classes(props.className, \"vc-plus-icon\")}\n viewBox=\"0 0 18 18\"\n >\n <polygon\n fill-rule=\"nonzero\"\n fill=\"currentColor\"\n points=\"15 10 10 10 10 15 8 15 8 10 3 10 3 8 8 8 8 3 10 3 10 8 15 8\"\n />\n </Icon>\n );\n}\n\nexport function NoEntrySignIcon(props: IconProps) {\n return (\n <Icon\n {...props}\n className={classes(props.className, \"vc-no-entry-sign-icon\")}\n viewBox=\"0 0 24 24\"\n >\n <path\n d=\"M0 0h24v24H0z\"\n fill=\"none\"\n />\n <path\n fill=\"currentColor\"\n d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8 0-1.85.63-3.55 1.69-4.9L16.9 18.31C15.55 19.37 13.85 20 12 20zm6.31-3.1L7.1 5.69C8.45 4.63 10.15 4 12 4c4.42 0 8 3.58 8 8 0 1.85-.63 3.55-1.69 4.9z\"\n />\n </Icon>\n );\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { moment } from \"@webpack/common\";\n\n// Utils for readable text transformations eg: `toTitle(fromKebab())`\n\n// Case style to words\nexport const wordsFromCamel = (text: string) => text.split(/(?=[A-Z])/).map(w => w.toLowerCase());\nexport const wordsFromSnake = (text: string) => text.toLowerCase().split(\"_\");\nexport const wordsFromKebab = (text: string) => text.toLowerCase().split(\"-\");\nexport const wordsFromPascal = (text: string) => text.split(/(?=[A-Z])/).map(w => w.toLowerCase());\nexport const wordsFromTitle = (text: string) => text.toLowerCase().split(\" \");\n\n// Words to case style\nexport const wordsToCamel = (words: string[]) =>\n words.map((w, i) => (i ? w[0].toUpperCase() + w.slice(1) : w)).join(\"\");\nexport const wordsToSnake = (words: string[]) => words.join(\"_\").toUpperCase();\nexport const wordsToKebab = (words: string[]) => words.join(\"-\").toLowerCase();\nexport const wordsToPascal = (words: string[]) =>\n words.map(w => w[0].toUpperCase() + w.slice(1)).join(\"\");\nexport const wordsToTitle = (words: string[]) =>\n words.map(w => w[0].toUpperCase() + w.slice(1)).join(\" \");\n\nconst units = [\"years\", \"months\", \"weeks\", \"days\", \"hours\", \"minutes\", \"seconds\"] as const;\ntype Units = typeof units[number];\n\nfunction getUnitStr(unit: Units, isOne: boolean, short: boolean) {\n if (short === false) return isOne ? unit.slice(0, -1) : unit;\n\n return unit[0];\n}\n\n/**\n * Forms time into a human readable string link \"1 day, 2 hours, 3 minutes and 4 seconds\"\n * @param time The time on the specified unit\n * @param unit The unit the time is on\n * @param short Whether to use short units like \"d\" instead of \"days\"\n */\nexport function formatDuration(time: number, unit: Units, short: boolean = false) {\n const dur = moment.duration(time, unit);\n\n let unitsAmounts = units.map(unit => ({ amount: dur[unit](), unit }));\n\n let amountsToBeRemoved = 0;\n\n outer:\n for (let i = 0; i < unitsAmounts.length; i++) {\n if (unitsAmounts[i].amount === 0 || !(i + 1 < unitsAmounts.length)) continue;\n for (let v = i + 1; v < unitsAmounts.length; v++) {\n if (unitsAmounts[v].amount !== 0) continue outer;\n }\n\n amountsToBeRemoved = unitsAmounts.length - (i + 1);\n }\n unitsAmounts = amountsToBeRemoved === 0 ? unitsAmounts : unitsAmounts.slice(0, -amountsToBeRemoved);\n\n const daysAmountIndex = unitsAmounts.findIndex(({ unit }) => unit === \"days\");\n if (daysAmountIndex !== -1) {\n const daysAmount = unitsAmounts[daysAmountIndex];\n\n const daysMod = daysAmount.amount % 7;\n if (daysMod === 0) unitsAmounts.splice(daysAmountIndex, 1);\n else daysAmount.amount = daysMod;\n }\n\n let res: string = \"\";\n while (unitsAmounts.length) {\n const { amount, unit } = unitsAmounts.shift()!;\n\n if (res.length) res += unitsAmounts.length ? \", \" : \" and \";\n\n if (amount > 0 || res.length) {\n res += `${amount} ${getUnitStr(unit, amount === 1, short)}`;\n }\n }\n\n return res.length ? res : `0 ${getUnitStr(unit, false, short)}`;\n}\n\n/**\n * Join an array of strings in a human readable way (1, 2 and 3)\n * @param elements Elements\n */\nexport function humanFriendlyJoin(elements: string[]): string;\n/**\n * Join an array of strings in a human readable way (1, 2 and 3)\n * @param elements Elements\n * @param mapper Function that converts elements to a string\n */\nexport function humanFriendlyJoin<T>(elements: T[], mapper: (e: T) => string): string;\nexport function humanFriendlyJoin(elements: any[], mapper: (e: any) => string = s => s): string {\n const { length } = elements;\n if (length === 0)\n return \"\";\n if (length === 1)\n return mapper(elements[0]);\n\n let s = \"\";\n\n for (let i = 0; i < length; i++) {\n s += mapper(elements[i]);\n if (length - i > 2)\n s += \", \";\n else if (length - i > 1)\n s += \" and \";\n }\n\n return s;\n}\n\n/**\n * Wrap the text in ``` with an optional language\n */\nexport function makeCodeblock(text: string, language?: string) {\n const chars = \"```\";\n return `${chars}${language || \"\"}\\n${text.replaceAll(\"```\", \"\\\\`\\\\`\\\\`\")}\\n${chars}`;\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { mergeDefaults } from \"@utils/misc\";\nimport { findByPropsLazy } from \"@webpack\";\nimport { MessageActions, SnowflakeUtils } from \"@webpack/common\";\nimport { Message } from \"discord-types/general\";\nimport type { PartialDeep } from \"type-fest\";\n\nimport { Argument } from \"./types\";\n\nconst MessageCreator = findByPropsLazy(\"createBotMessage\");\n\nexport function generateId() {\n return `-${SnowflakeUtils.fromTimestamp(Date.now())}`;\n}\n\n/**\n * Send a message as Clyde\n * @param {string} channelId ID of channel to send message to\n * @param {Message} message Message to send\n * @returns {Message}\n */\nexport function sendBotMessage(channelId: string, message: PartialDeep<Message>): Message {\n const botMessage = MessageCreator.createBotMessage({ channelId, content: \"\", embeds: [] });\n\n MessageActions.receiveMessage(channelId, mergeDefaults(message, botMessage));\n\n return message as Message;\n}\n\n/**\n * Get the value of an option by name\n * @param args Arguments array (first argument passed to execute)\n * @param name Name of the argument\n * @param fallbackValue Fallback value in case this option wasn't passed\n * @returns Value\n */\nexport function findOption<T>(args: Argument[], name: string): T & {} | undefined;\nexport function findOption<T>(args: Argument[], name: string, fallbackValue: T): T & {};\nexport function findOption(args: Argument[], name: string, fallbackValue?: any) {\n return (args.find(a => a.name === name)?.value || fallbackValue) as any;\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Channel, Guild } from \"discord-types/general\";\nimport { Promisable } from \"type-fest\";\n\nexport interface CommandContext {\n channel: Channel;\n guild?: Guild;\n}\n\nexport const enum ApplicationCommandOptionType {\n SUB_COMMAND = 1,\n SUB_COMMAND_GROUP = 2,\n STRING = 3,\n INTEGER = 4,\n BOOLEAN = 5,\n USER = 6,\n CHANNEL = 7,\n ROLE = 8,\n MENTIONABLE = 9,\n NUMBER = 10,\n ATTACHMENT = 11,\n}\n\nexport const enum ApplicationCommandInputType {\n BUILT_IN = 0,\n BUILT_IN_TEXT = 1,\n BUILT_IN_INTEGRATION = 2,\n BOT = 3,\n PLACEHOLDER = 4,\n}\n\nexport interface Option {\n name: string;\n displayName?: string;\n type: ApplicationCommandOptionType;\n description: string;\n displayDescription?: string;\n required?: boolean;\n options?: Option[];\n choices?: Array<ChoicesOption>;\n}\n\nexport interface ChoicesOption {\n label: string;\n value: string;\n name: string;\n displayName?: string;\n}\n\nexport const enum ApplicationCommandType {\n CHAT_INPUT = 1,\n USER = 2,\n MESSAGE = 3,\n}\n\nexport interface CommandReturnValue {\n content: string;\n /** TODO: implement */\n cancel?: boolean;\n}\n\nexport interface Argument {\n type: ApplicationCommandOptionType;\n name: string;\n value: string;\n focused: undefined;\n options: Argument[];\n}\n\nexport interface Command {\n id?: string;\n applicationId?: string;\n type?: ApplicationCommandType;\n inputType?: ApplicationCommandInputType;\n plugin?: string;\n isVencordCommand?: boolean;\n\n name: string;\n displayName?: string;\n description: string;\n displayDescription?: string;\n\n options?: Option[];\n predicate?(ctx: CommandContext): boolean;\n\n execute(args: Argument[], ctx: CommandContext): Promisable<void | CommandReturnValue>;\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { makeCodeblock } from \"@utils/text\";\n\nimport { sendBotMessage } from \"./commandHelpers\";\nimport { ApplicationCommandInputType, ApplicationCommandOptionType, ApplicationCommandType, Argument, Command, CommandContext, Option } from \"./types\";\n\nexport * from \"./commandHelpers\";\nexport * from \"./types\";\n\nexport let BUILT_IN: Command[];\nexport const commands = {} as Record<string, Command>;\n\n// hack for plugins being evaluated before we can grab these from webpack\nconst OptPlaceholder = Symbol(\"OptionalMessageOption\") as any as Option;\nconst ReqPlaceholder = Symbol(\"RequiredMessageOption\") as any as Option;\n/**\n * Optional message option named \"message\" you can use in commands.\n * Used in \"tableflip\" or \"shrug\"\n * @see {@link RequiredMessageOption}\n */\nexport let OptionalMessageOption: Option = OptPlaceholder;\n/**\n * Required message option named \"message\" you can use in commands.\n * Used in \"me\"\n * @see {@link OptionalMessageOption}\n */\nexport let RequiredMessageOption: Option = ReqPlaceholder;\n\nexport const _init = function (cmds: Command[]) {\n try {\n BUILT_IN = cmds;\n OptionalMessageOption = cmds.find(c => c.name === \"shrug\")!.options![0];\n RequiredMessageOption = cmds.find(c => c.name === \"me\")!.options![0];\n } catch (e) {\n console.error(\"Failed to load CommandsApi\");\n }\n return cmds;\n} as never;\n\nexport const _handleCommand = function (cmd: Command, args: Argument[], ctx: CommandContext) {\n if (!cmd.isVencordCommand)\n return cmd.execute(args, ctx);\n\n const handleError = (err: any) => {\n // TODO: cancel send if cmd.inputType === BUILT_IN_TEXT\n const msg = `An Error occurred while executing command \"${cmd.name}\"`;\n const reason = err instanceof Error ? err.stack || err.message : String(err);\n\n console.error(msg, err);\n sendBotMessage(ctx.channel.id, {\n content: `${msg}:\\n${makeCodeblock(reason)}`,\n author: {\n username: \"Vencord\"\n }\n });\n };\n\n try {\n const res = cmd.execute(args, ctx);\n return res instanceof Promise ? res.catch(handleError) : res;\n } catch (err) {\n return handleError(err);\n }\n} as never;\n\n\n/**\n * Prepare a Command Option for Discord by filling missing fields\n * @param opt\n */\nexport function prepareOption<O extends Option | Command>(opt: O): O {\n opt.displayName ||= opt.name;\n opt.displayDescription ||= opt.description;\n opt.options?.forEach((opt, i, opts) => {\n // See comment above Placeholders\n if (opt === OptPlaceholder) opts[i] = OptionalMessageOption;\n else if (opt === ReqPlaceholder) opts[i] = RequiredMessageOption;\n opt.choices?.forEach(x => x.displayName ||= x.name);\n\n prepareOption(opts[i]);\n });\n return opt;\n}\n\n// Yes, Discord registers individual commands for each subcommand\n// TODO: This probably doesn't support nested subcommands. If that is ever needed,\n// investigate\nfunction registerSubCommands(cmd: Command, plugin: string) {\n cmd.options?.forEach(o => {\n if (o.type !== ApplicationCommandOptionType.SUB_COMMAND)\n throw new Error(\"When specifying sub-command options, all options must be sub-commands.\");\n const subCmd = {\n ...cmd,\n ...o,\n type: ApplicationCommandType.CHAT_INPUT,\n name: `${cmd.name} ${o.name}`,\n id: `${o.name}-${cmd.id}`,\n displayName: `${cmd.name} ${o.name}`,\n subCommandPath: [{\n name: o.name,\n type: o.type,\n displayName: o.name\n }],\n rootCommand: cmd\n };\n registerCommand(subCmd as any, plugin);\n });\n}\n\nexport function registerCommand<C extends Command>(command: C, plugin: string) {\n if (!BUILT_IN) {\n console.warn(\n \"[CommandsAPI]\",\n `Not registering ${command.name} as the CommandsAPI hasn't been initialised.`,\n \"Please restart to use commands\"\n );\n return;\n }\n\n if (BUILT_IN.some(c => c.name === command.name))\n throw new Error(`Command '${command.name}' already exists.`);\n\n command.isVencordCommand = true;\n command.id ??= `-${BUILT_IN.length + 1}`;\n command.applicationId ??= \"-1\"; // BUILT_IN;\n command.type ??= ApplicationCommandType.CHAT_INPUT;\n command.inputType ??= ApplicationCommandInputType.BUILT_IN_TEXT;\n command.plugin ||= plugin;\n\n prepareOption(command);\n\n if (command.options?.[0]?.type === ApplicationCommandOptionType.SUB_COMMAND) {\n registerSubCommands(command, plugin);\n return;\n }\n\n commands[command.name] = command;\n BUILT_IN.push(command);\n}\n\nexport function unregisterCommand(name: string) {\n const idx = BUILT_IN.findIndex(c => c.name === name);\n if (idx === -1)\n return false;\n\n BUILT_IN.splice(idx, 1);\n delete commands[name];\n\n return true;\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nexport function Badge({ text, color }): JSX.Element {\n return (\n <div className=\"vc-plugins-badge\" style={{\n backgroundColor: color,\n justifySelf: \"flex-end\",\n marginLeft: \"auto\"\n }}>\n {text}\n </div>\n );\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { wordsFromCamel, wordsToTitle } from \"@utils/text\";\nimport { PluginOptionBoolean } from \"@utils/types\";\nimport { Forms, React, Switch } from \"@webpack/common\";\n\nimport { ISettingElementProps } from \".\";\n\nexport function SettingBooleanComponent({ option, pluginSettings, definedSettings, id, onChange, onError }: ISettingElementProps<PluginOptionBoolean>) {\n const def = pluginSettings[id] ?? option.default;\n\n const [state, setState] = React.useState(def ?? false);\n const [error, setError] = React.useState<string | null>(null);\n\n React.useEffect(() => {\n onError(error !== null);\n }, [error]);\n\n function handleChange(newValue: boolean): void {\n const isValid = option.isValid?.call(definedSettings, newValue) ?? true;\n if (typeof isValid === \"string\") setError(isValid);\n else if (!isValid) setError(\"Invalid input provided.\");\n else {\n setError(null);\n setState(newValue);\n onChange(newValue);\n }\n }\n\n return (\n <Forms.FormSection>\n <Switch\n value={state}\n onChange={handleChange}\n note={option.description}\n disabled={option.disabled?.call(definedSettings) ?? false}\n {...option.componentProps}\n hideBorder\n style={{ marginBottom: \"0.5em\" }}\n >\n {wordsToTitle(wordsFromCamel(id))}\n </Switch>\n {error && <Forms.FormText style={{ color: \"var(--text-danger)\" }}>{error}</Forms.FormText>}\n </Forms.FormSection>\n );\n}\n\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { PluginOptionComponent } from \"@utils/types\";\n\nimport { ISettingElementProps } from \".\";\n\nexport function SettingCustomComponent({ option, onChange, onError }: ISettingElementProps<PluginOptionComponent>) {\n return option.component({ setValue: onChange, setError: onError, option });\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { OptionType, PluginOptionNumber } from \"@utils/types\";\nimport { Forms, React, TextInput } from \"@webpack/common\";\n\nimport { ISettingElementProps } from \".\";\n\nconst MAX_SAFE_NUMBER = BigInt(Number.MAX_SAFE_INTEGER);\n\nexport function SettingNumericComponent({ option, pluginSettings, definedSettings, id, onChange, onError }: ISettingElementProps<PluginOptionNumber>) {\n function serialize(value: any) {\n if (option.type === OptionType.BIGINT) return BigInt(value);\n return Number(value);\n }\n\n const [state, setState] = React.useState<any>(`${pluginSettings[id] ?? option.default ?? 0}`);\n const [error, setError] = React.useState<string | null>(null);\n\n React.useEffect(() => {\n onError(error !== null);\n }, [error]);\n\n function handleChange(newValue) {\n const isValid = option.isValid?.call(definedSettings, newValue) ?? true;\n\n setError(null);\n if (typeof isValid === \"string\") setError(isValid);\n else if (!isValid) setError(\"Invalid input provided.\");\n\n if (option.type === OptionType.NUMBER && BigInt(newValue) >= MAX_SAFE_NUMBER) {\n setState(`${Number.MAX_SAFE_INTEGER}`);\n onChange(serialize(newValue));\n } else {\n setState(newValue);\n onChange(serialize(newValue));\n }\n }\n\n return (\n <Forms.FormSection>\n <Forms.FormTitle>{option.description}</Forms.FormTitle>\n <TextInput\n type=\"number\"\n pattern=\"-?[0-9]+\"\n value={state}\n onChange={handleChange}\n placeholder={option.placeholder ?? \"Enter a number\"}\n disabled={option.disabled?.call(definedSettings) ?? false}\n {...option.componentProps}\n />\n {error && <Forms.FormText style={{ color: \"var(--text-danger)\" }}>{error}</Forms.FormText>}\n </Forms.FormSection>\n );\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { PluginOptionSelect } from \"@utils/types\";\nimport { Forms, React, Select } from \"@webpack/common\";\n\nimport { ISettingElementProps } from \".\";\n\nexport function SettingSelectComponent({ option, pluginSettings, definedSettings, onChange, onError, id }: ISettingElementProps<PluginOptionSelect>) {\n const def = pluginSettings[id] ?? option.options?.find(o => o.default)?.value;\n\n const [state, setState] = React.useState<any>(def ?? null);\n const [error, setError] = React.useState<string | null>(null);\n\n React.useEffect(() => {\n onError(error !== null);\n }, [error]);\n\n function handleChange(newValue) {\n const isValid = option.isValid?.call(definedSettings, newValue) ?? true;\n if (typeof isValid === \"string\") setError(isValid);\n else if (!isValid) setError(\"Invalid input provided.\");\n else {\n setError(null);\n setState(newValue);\n onChange(newValue);\n }\n }\n\n return (\n <Forms.FormSection>\n <Forms.FormTitle>{option.description}</Forms.FormTitle>\n <Select\n isDisabled={option.disabled?.call(definedSettings) ?? false}\n options={option.options}\n placeholder={option.placeholder ?? \"Select an option\"}\n maxVisibleItems={5}\n closeOnSelect={true}\n select={handleChange}\n isSelected={v => v === state}\n serialize={v => String(v)}\n {...option.componentProps}\n />\n {error && <Forms.FormText style={{ color: \"var(--text-danger)\" }}>{error}</Forms.FormText>}\n </Forms.FormSection>\n );\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { PluginOptionSlider } from \"@utils/types\";\nimport { Forms, React, Slider } from \"@webpack/common\";\n\nimport { ISettingElementProps } from \".\";\n\nexport function makeRange(start: number, end: number, step = 1) {\n const ranges: number[] = [];\n for (let value = start; value <= end; value += step) {\n ranges.push(Math.round(value * 100) / 100);\n }\n return ranges;\n}\n\nexport function SettingSliderComponent({ option, pluginSettings, definedSettings, id, onChange, onError }: ISettingElementProps<PluginOptionSlider>) {\n const def = pluginSettings[id] ?? option.default;\n\n const [error, setError] = React.useState<string | null>(null);\n\n React.useEffect(() => {\n onError(error !== null);\n }, [error]);\n\n function handleChange(newValue: number): void {\n const isValid = option.isValid?.call(definedSettings, newValue) ?? true;\n if (typeof isValid === \"string\") setError(isValid);\n else if (!isValid) setError(\"Invalid input provided.\");\n else {\n setError(null);\n onChange(newValue);\n }\n }\n\n return (\n <Forms.FormSection>\n <Forms.FormTitle>{option.description}</Forms.FormTitle>\n <Slider\n disabled={option.disabled?.call(definedSettings) ?? false}\n markers={option.markers}\n minValue={option.markers[0]}\n maxValue={option.markers[option.markers.length - 1]}\n initialValue={def}\n onValueChange={handleChange}\n onValueRender={(v: number) => String(v.toFixed(2))}\n stickToMarkers={option.stickToMarkers ?? true}\n {...option.componentProps}\n />\n </Forms.FormSection>\n );\n}\n\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { PluginOptionString } from \"@utils/types\";\nimport { Forms, React, TextInput } from \"@webpack/common\";\n\nimport { ISettingElementProps } from \".\";\n\nexport function SettingTextComponent({ option, pluginSettings, definedSettings, id, onChange, onError }: ISettingElementProps<PluginOptionString>) {\n const [state, setState] = React.useState(pluginSettings[id] ?? option.default ?? null);\n const [error, setError] = React.useState<string | null>(null);\n\n React.useEffect(() => {\n onError(error !== null);\n }, [error]);\n\n function handleChange(newValue) {\n const isValid = option.isValid?.call(definedSettings, newValue) ?? true;\n if (typeof isValid === \"string\") setError(isValid);\n else if (!isValid) setError(\"Invalid input provided.\");\n else setError(null);\n\n setState(newValue);\n onChange(newValue);\n }\n\n return (\n <Forms.FormSection>\n <Forms.FormTitle>{option.description}</Forms.FormTitle>\n <TextInput\n type=\"text\"\n value={state}\n onChange={handleChange}\n placeholder={option.placeholder ?? \"Enter a value\"}\n disabled={option.disabled?.call(definedSettings) ?? false}\n {...option.componentProps}\n />\n {error && <Forms.FormText style={{ color: \"var(--text-danger)\" }}>{error}</Forms.FormText>}\n </Forms.FormSection>\n );\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { DefinedSettings, PluginOptionBase } from \"@utils/types\";\n\nexport interface ISettingElementProps<T extends PluginOptionBase> {\n option: T;\n onChange(newValue: any): void;\n pluginSettings: {\n [setting: string]: any;\n enabled: boolean;\n };\n id: string;\n onError(hasError: boolean): void;\n definedSettings?: DefinedSettings;\n}\n\nexport * from \"../../Badge\";\nexport * from \"./SettingBooleanComponent\";\nexport * from \"./SettingCustomComponent\";\nexport * from \"./SettingNumericComponent\";\nexport * from \"./SettingSelectComponent\";\nexport * from \"./SettingSliderComponent\";\nexport * from \"./SettingTextComponent\";\n\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { MessageObject } from \"@api/MessageEvents\";\nimport { ChannelStore, ComponentDispatch, FluxDispatcher, GuildStore, InviteActions, MaskedLink, MessageActions, ModalImageClasses, PrivateChannelsStore, RestAPI, SelectedChannelStore, SelectedGuildStore, UserProfileActions, UserProfileStore, UserSettingsActionCreators, UserUtils } from \"@webpack/common\";\nimport { Guild, Message, User } from \"discord-types/general\";\n\nimport { ImageModal, ModalRoot, ModalSize, openModal } from \"./modal\";\n\n/**\n * Open the invite modal\n * @param code The invite code\n * @returns Whether the invite was accepted\n */\nexport async function openInviteModal(code: string) {\n const { invite } = await InviteActions.resolveInvite(code, \"Desktop Modal\");\n if (!invite) throw new Error(\"Invalid invite: \" + code);\n\n FluxDispatcher.dispatch({\n type: \"INVITE_MODAL_OPEN\",\n invite,\n code,\n context: \"APP\"\n });\n\n return new Promise<boolean>(r => {\n let onClose: () => void, onAccept: () => void;\n let inviteAccepted = false;\n\n FluxDispatcher.subscribe(\"INVITE_ACCEPT\", onAccept = () => {\n inviteAccepted = true;\n });\n\n FluxDispatcher.subscribe(\"INVITE_MODAL_CLOSE\", onClose = () => {\n FluxDispatcher.unsubscribe(\"INVITE_MODAL_CLOSE\", onClose);\n FluxDispatcher.unsubscribe(\"INVITE_ACCEPT\", onAccept);\n r(inviteAccepted);\n });\n });\n}\n\nexport function getCurrentChannel() {\n return ChannelStore.getChannel(SelectedChannelStore.getChannelId());\n}\n\nexport function getCurrentGuild(): Guild | undefined {\n return GuildStore.getGuild(getCurrentChannel()?.guild_id);\n}\n\nexport function openPrivateChannel(userId: string) {\n PrivateChannelsStore.openPrivateChannel(userId);\n}\n\nexport const enum Theme {\n Dark = 1,\n Light = 2\n}\n\nexport function getTheme(): Theme {\n return UserSettingsActionCreators.PreloadedUserSettingsActionCreators.getCurrentValue()?.appearance?.theme;\n}\n\nexport function insertTextIntoChatInputBox(text: string) {\n ComponentDispatch.dispatchToLastSubscribed(\"INSERT_TEXT\", {\n rawText: text,\n plainText: text\n });\n}\n\ninterface MessageExtra {\n messageReference: Message[\"messageReference\"];\n allowedMentions: {\n parse: string[];\n replied_user: boolean;\n };\n stickerIds: string[];\n}\n\nexport function sendMessage(\n channelId: string,\n data: Partial<MessageObject>,\n waitForChannelReady?: boolean,\n extra?: Partial<MessageExtra>\n) {\n const messageData = {\n content: \"\",\n invalidEmojis: [],\n tts: false,\n validNonShortcutEmojis: [],\n ...data\n };\n\n return MessageActions.sendMessage(channelId, messageData, waitForChannelReady, extra);\n}\n\nexport function openImageModal(url: string, props?: Partial<React.ComponentProps<ImageModal>>): string {\n return openModal(modalProps => (\n <ModalRoot\n {...modalProps}\n className={ModalImageClasses.modal}\n size={ModalSize.DYNAMIC}>\n <ImageModal\n className={ModalImageClasses.image}\n original={url}\n placeholder={url}\n src={url}\n renderLinkComponent={props => <MaskedLink {...props} />}\n shouldHideMediaOptions={false}\n shouldAnimate\n {...props}\n />\n </ModalRoot>\n ));\n}\n\nexport async function openUserProfile(id: string) {\n const user = await UserUtils.getUser(id);\n if (!user) throw new Error(\"No such user: \" + id);\n\n const guildId = SelectedGuildStore.getGuildId();\n UserProfileActions.openUserProfileModal({\n userId: id,\n guildId,\n channelId: SelectedChannelStore.getChannelId(),\n analyticsLocation: {\n page: guildId ? \"Guild Channel\" : \"DM Channel\",\n section: \"Profile Popout\"\n }\n });\n}\n\ninterface FetchUserProfileOptions {\n friend_token?: string;\n connections_role_id?: string;\n guild_id?: string;\n with_mutual_guilds?: boolean;\n with_mutual_friends_count?: boolean;\n}\n\n/**\n * Fetch a user's profile\n */\nexport async function fetchUserProfile(id: string, options?: FetchUserProfileOptions) {\n const cached = UserProfileStore.getUserProfile(id);\n if (cached) return cached;\n\n FluxDispatcher.dispatch({ type: \"USER_PROFILE_FETCH_START\", userId: id });\n\n const { body } = await RestAPI.get({\n url: `/users/${id}/profile`,\n query: {\n with_mutual_guilds: false,\n with_mutual_friends_count: false,\n ...options\n },\n oldFormErrors: true,\n });\n\n FluxDispatcher.dispatch({ type: \"USER_UPDATE\", user: body.user });\n await FluxDispatcher.dispatch({ type: \"USER_PROFILE_FETCH_SUCCESS\", ...body });\n if (options?.guild_id && body.guild_member)\n FluxDispatcher.dispatch({ type: \"GUILD_MEMBER_PROFILE_UPDATE\", guildId: options.guild_id, guildMember: body.guild_member });\n\n return UserProfileStore.getUserProfile(id);\n}\n\n/**\n * Get the unique username for a user. Returns user.username for pomelo people, user.tag otherwise\n */\nexport function getUniqueUsername(user: User) {\n return user.discriminator === \"0\" ? user.username : user.tag;\n}\n", "/*\n * Vencord, a Discord client mod\n * Copyright (c) 2023 Vendicated and contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport \"./contributorModal.css\";\n\nimport { useSettings } from \"@api/Settings\";\nimport { classNameFactory } from \"@api/Styles\";\nimport ErrorBoundary from \"@components/ErrorBoundary\";\nimport { DevsById } from \"@utils/constants\";\nimport { fetchUserProfile, getTheme, Theme } from \"@utils/discord\";\nimport { ModalContent, ModalRoot, openModal } from \"@utils/modal\";\nimport { Forms, MaskedLink, showToast, useEffect, useMemo, UserProfileStore, useStateFromStores } from \"@webpack/common\";\nimport { User } from \"discord-types/general\";\n\nimport Plugins from \"~plugins\";\n\nimport { PluginCard } from \".\";\n\nconst WebsiteIconDark = \"/assets/e1e96d89e192de1997f73730db26e94f.svg\";\nconst WebsiteIconLight = \"/assets/730f58bcfd5a57a5e22460c445a0c6cf.svg\";\nconst GithubIconLight = \"/assets/3ff98ad75ac94fa883af5ed62d17c459.svg\";\nconst GithubIconDark = \"/assets/6a853b4c87fce386cbfef4a2efbacb09.svg\";\n\nconst cl = classNameFactory(\"vc-author-modal-\");\n\nexport function openContributorModal(user: User) {\n openModal(modalProps =>\n <ModalRoot {...modalProps}>\n <ErrorBoundary>\n <ModalContent className={cl(\"root\")}>\n <ContributorModal user={user} />\n </ModalContent>\n </ErrorBoundary>\n </ModalRoot>\n );\n}\n\nfunction GithubIcon() {\n const src = getTheme() === Theme.Light ? GithubIconLight : GithubIconDark;\n return <img src={src} alt=\"GitHub\" />;\n}\n\nfunction WebsiteIcon() {\n const src = getTheme() === Theme.Light ? WebsiteIconLight : WebsiteIconDark;\n return <img src={src} alt=\"Website\" />;\n}\n\nfunction ContributorModal({ user }: { user: User; }) {\n useSettings();\n\n const profile = useStateFromStores([UserProfileStore], () => UserProfileStore.getUserProfile(user.id));\n\n useEffect(() => {\n if (!profile && !user.bot && user.id)\n fetchUserProfile(user.id);\n }, [user.id]);\n\n const githubName = profile?.connectedAccounts?.find(a => a.type === \"github\")?.name;\n const website = profile?.connectedAccounts?.find(a => a.type === \"domain\")?.name;\n\n const plugins = useMemo(() => {\n const allPlugins = Object.values(Plugins);\n const pluginsByAuthor = DevsById[user.id]\n ? allPlugins.filter(p => p.authors.includes(DevsById[user.id]))\n : allPlugins.filter(p => p.authors.some(a => a.name === user.username));\n\n return pluginsByAuthor\n .filter(p => !p.name.endsWith(\"API\"))\n .sort((a, b) => Number(a.required ?? false) - Number(b.required ?? false));\n }, [user.id, user.username]);\n\n return (\n <>\n <div className={cl(\"header\")}>\n <img\n className={cl(\"avatar\")}\n src={user.getAvatarURL(void 0, 512, true)}\n alt=\"\"\n />\n <Forms.FormTitle tag=\"h2\" className={cl(\"name\")}>{user.username}</Forms.FormTitle>\n\n <div className={cl(\"links\")}>\n {website && (\n <MaskedLink\n href={\"https://\" + website}\n >\n <WebsiteIcon />\n </MaskedLink>\n )}\n {githubName && (\n <MaskedLink href={`https://github.com/${githubName}`}>\n <GithubIcon />\n </MaskedLink>\n )}\n </div>\n </div>\n\n <div className={cl(\"plugins\")}>\n {plugins.map(p =>\n <PluginCard\n key={p.name}\n plugin={p}\n disabled={p.required ?? false}\n onRestartNeeded={() => showToast(\"Restart to apply changes!\")}\n />\n )}\n </div>\n </>\n );\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { generateId } from \"@api/Commands\";\nimport { useSettings } from \"@api/Settings\";\nimport ErrorBoundary from \"@components/ErrorBoundary\";\nimport { Flex } from \"@components/Flex\";\nimport { proxyLazy } from \"@utils/lazy\";\nimport { Margins } from \"@utils/margins\";\nimport { classes, isObjectEmpty } from \"@utils/misc\";\nimport { ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize } from \"@utils/modal\";\nimport { OptionType, Plugin } from \"@utils/types\";\nimport { findByPropsLazy, findComponentByCodeLazy } from \"@webpack\";\nimport { Button, Clickable, FluxDispatcher, Forms, React, Text, Tooltip, UserStore, UserUtils } from \"@webpack/common\";\nimport { User } from \"discord-types/general\";\nimport { Constructor } from \"type-fest\";\n\nimport {\n ISettingElementProps,\n SettingBooleanComponent,\n SettingCustomComponent,\n SettingNumericComponent,\n SettingSelectComponent,\n SettingSliderComponent,\n SettingTextComponent\n} from \"./components\";\nimport { openContributorModal } from \"./ContributorModal\";\n\nconst UserSummaryItem = findComponentByCodeLazy(\"defaultRenderUser\", \"showDefaultAvatarsForNullUsers\");\nconst AvatarStyles = findByPropsLazy(\"moreUsers\", \"emptyUser\", \"avatarContainer\", \"clickableAvatar\");\nconst UserRecord: Constructor<Partial<User>> = proxyLazy(() => UserStore.getCurrentUser().constructor) as any;\n\ninterface PluginModalProps extends ModalProps {\n plugin: Plugin;\n onRestartNeeded(): void;\n}\n\nfunction makeDummyUser(user: { username: string; id?: string; avatar?: string; }) {\n const newUser = new UserRecord({\n username: user.username,\n id: user.id ?? generateId(),\n avatar: user.avatar,\n /** To stop discord making unwanted requests... */\n bot: true,\n });\n FluxDispatcher.dispatch({\n type: \"USER_UPDATE\",\n user: newUser,\n });\n return newUser;\n}\n\nconst Components: Record<OptionType, React.ComponentType<ISettingElementProps<any>>> = {\n [OptionType.STRING]: SettingTextComponent,\n [OptionType.NUMBER]: SettingNumericComponent,\n [OptionType.BIGINT]: SettingNumericComponent,\n [OptionType.BOOLEAN]: SettingBooleanComponent,\n [OptionType.SELECT]: SettingSelectComponent,\n [OptionType.SLIDER]: SettingSliderComponent,\n [OptionType.COMPONENT]: SettingCustomComponent\n};\n\nexport default function PluginModal({ plugin, onRestartNeeded, onClose, transitionState }: PluginModalProps) {\n const [authors, setAuthors] = React.useState<Partial<User>[]>([]);\n\n const pluginSettings = useSettings().plugins[plugin.name];\n\n const [tempSettings, setTempSettings] = React.useState<Record<string, any>>({});\n\n const [errors, setErrors] = React.useState<Record<string, boolean>>({});\n const [saveError, setSaveError] = React.useState<string | null>(null);\n\n const canSubmit = () => Object.values(errors).every(e => !e);\n\n const hasSettings = Boolean(pluginSettings && plugin.options && !isObjectEmpty(plugin.options));\n\n React.useEffect(() => {\n (async () => {\n for (const user of plugin.authors.slice(0, 6)) {\n const author = user.id\n ? await UserUtils.getUser(`${user.id}`)\n .catch(() => makeDummyUser({ username: user.name }))\n : makeDummyUser({ username: user.name });\n\n setAuthors(a => [...a, author]);\n }\n })();\n }, []);\n\n async function saveAndClose() {\n if (!plugin.options) {\n onClose();\n return;\n }\n\n if (plugin.beforeSave) {\n const result = await Promise.resolve(plugin.beforeSave(tempSettings));\n if (result !== true) {\n setSaveError(result);\n return;\n }\n }\n\n let restartNeeded = false;\n for (const [key, value] of Object.entries(tempSettings)) {\n const option = plugin.options[key];\n pluginSettings[key] = value;\n option?.onChange?.(value);\n if (option?.restartNeeded) restartNeeded = true;\n }\n if (restartNeeded) onRestartNeeded();\n onClose();\n }\n\n function renderSettings() {\n if (!hasSettings || !plugin.options) {\n return <Forms.FormText>There are no settings for this plugin.</Forms.FormText>;\n } else {\n const options = Object.entries(plugin.options).map(([key, setting]) => {\n if (setting.hidden) return null;\n\n function onChange(newValue: any) {\n setTempSettings(s => ({ ...s, [key]: newValue }));\n }\n\n function onError(hasError: boolean) {\n setErrors(e => ({ ...e, [key]: hasError }));\n }\n\n const Component = Components[setting.type];\n return (\n <Component\n id={key}\n key={key}\n option={setting}\n onChange={onChange}\n onError={onError}\n pluginSettings={pluginSettings}\n definedSettings={plugin.settings}\n />\n );\n });\n\n return <Flex flexDirection=\"column\" style={{ gap: 12, marginBottom: 16 }}>{options}</Flex>;\n }\n }\n\n function renderMoreUsers(_label: string, count: number) {\n const sliceCount = plugin.authors.length - count;\n const sliceStart = plugin.authors.length - sliceCount;\n const sliceEnd = sliceStart + plugin.authors.length - count;\n\n return (\n <Tooltip text={plugin.authors.slice(sliceStart, sliceEnd).map(u => u.name).join(\", \")}>\n {({ onMouseEnter, onMouseLeave }) => (\n <div\n className={AvatarStyles.moreUsers}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n >\n +{sliceCount}\n </div>\n )}\n </Tooltip>\n );\n }\n\n return (\n <ModalRoot transitionState={transitionState} size={ModalSize.MEDIUM} className=\"vc-text-selectable\">\n <ModalHeader separator={false}>\n <Text variant=\"heading-lg/semibold\" style={{ flexGrow: 1 }}>{plugin.name}</Text>\n <ModalCloseButton onClick={onClose} />\n </ModalHeader>\n <ModalContent>\n <Forms.FormSection>\n <Forms.FormTitle tag=\"h3\">About {plugin.name}</Forms.FormTitle>\n <Forms.FormText>{plugin.description}</Forms.FormText>\n <Forms.FormTitle tag=\"h3\" style={{ marginTop: 8, marginBottom: 0 }}>Authors</Forms.FormTitle>\n <div style={{ width: \"fit-content\", marginBottom: 8 }}>\n <UserSummaryItem\n users={authors}\n count={plugin.authors.length}\n guildId={undefined}\n renderIcon={false}\n max={6}\n showDefaultAvatarsForNullUsers\n showUserPopout\n renderMoreUsers={renderMoreUsers}\n renderUser={(user: User) => (\n <Clickable\n className={AvatarStyles.clickableAvatar}\n onClick={() => openContributorModal(user)}\n >\n <img\n className={AvatarStyles.avatar}\n src={user.getAvatarURL(void 0, 80, true)}\n alt={user.username}\n title={user.username}\n />\n </Clickable>\n )}\n />\n </div>\n </Forms.FormSection>\n {!!plugin.settingsAboutComponent && (\n <div className={classes(Margins.bottom8, \"vc-text-selectable\")}>\n <Forms.FormSection>\n <ErrorBoundary message=\"An error occurred while rendering this plugin's custom InfoComponent\">\n <plugin.settingsAboutComponent tempSettings={tempSettings} />\n </ErrorBoundary>\n </Forms.FormSection>\n </div>\n )}\n <Forms.FormSection className={Margins.bottom16}>\n <Forms.FormTitle tag=\"h3\">Settings</Forms.FormTitle>\n {renderSettings()}\n </Forms.FormSection>\n </ModalContent>\n {hasSettings && <ModalFooter>\n <Flex flexDirection=\"column\" style={{ width: \"100%\" }}>\n <Flex style={{ marginLeft: \"auto\" }}>\n <Button\n onClick={onClose}\n size={Button.Sizes.SMALL}\n color={Button.Colors.PRIMARY}\n look={Button.Looks.LINK}\n >\n Cancel\n </Button>\n <Tooltip text=\"You must fix all errors before saving\" shouldShow={!canSubmit()}>\n {({ onMouseEnter, onMouseLeave }) => (\n <Button\n size={Button.Sizes.SMALL}\n color={Button.Colors.BRAND}\n onClick={saveAndClose}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n disabled={!canSubmit()}\n >\n Save & Close\n </Button>\n )}\n </Tooltip>\n </Flex>\n {saveError && <Text variant=\"text-md/semibold\" style={{ color: \"var(--text-danger)\" }}>Error while saving: {saveError}</Text>}\n </Flex>\n </ModalFooter>}\n </ModalRoot>\n );\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport \"./Switch.css\";\n\nimport { classes } from \"@utils/misc\";\nimport { findByPropsLazy } from \"@webpack\";\n\ninterface SwitchProps {\n checked: boolean;\n onChange: (checked: boolean) => void;\n disabled?: boolean;\n}\n\nconst SWITCH_ON = \"var(--green-360)\";\nconst SWITCH_OFF = \"var(--primary-400)\";\nconst SwitchClasses = findByPropsLazy(\"slider\", \"input\", \"container\");\n\nexport function Switch({ checked, onChange, disabled }: SwitchProps) {\n return (\n <div>\n <div className={classes(SwitchClasses.container, \"default-colors\", checked ? SwitchClasses.checked : void 0)} style={{\n backgroundColor: checked ? SWITCH_ON : SWITCH_OFF,\n opacity: disabled ? 0.3 : 1\n }}>\n <svg\n className={SwitchClasses.slider + \" vc-switch-slider\"}\n viewBox=\"0 0 28 20\"\n preserveAspectRatio=\"xMinYMid meet\"\n aria-hidden=\"true\"\n style={{\n transform: checked ? \"translateX(12px)\" : \"translateX(-3px)\",\n }}\n >\n <rect fill=\"white\" x=\"4\" y=\"0\" height=\"20\" width=\"20\" rx=\"10\" />\n <svg viewBox=\"0 0 20 20\" fill=\"none\">\n {checked ? (\n <>\n <path fill={SWITCH_ON} d=\"M7.89561 14.8538L6.30462 13.2629L14.3099 5.25755L15.9009 6.84854L7.89561 14.8538Z\" />\n <path fill={SWITCH_ON} d=\"M4.08643 11.0903L5.67742 9.49929L9.4485 13.2704L7.85751 14.8614L4.08643 11.0903Z\" />\n </>\n ) : (\n <>\n <path fill={SWITCH_OFF} d=\"M5.13231 6.72963L6.7233 5.13864L14.855 13.2704L13.264 14.8614L5.13231 6.72963Z\" />\n <path fill={SWITCH_OFF} d=\"M13.2704 5.13864L14.8614 6.72963L6.72963 14.8614L5.13864 13.2704L13.2704 5.13864Z\" />\n </>\n )}\n\n </svg>\n </svg>\n <input\n disabled={disabled}\n type=\"checkbox\"\n className={SwitchClasses.input}\n tabIndex={0}\n checked={checked}\n onChange={e => onChange(e.currentTarget.checked)}\n />\n </div>\n </div>\n );\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport \"./addonCard.css\";\n\nimport { classNameFactory } from \"@api/Styles\";\nimport { Badge } from \"@components/Badge\";\nimport { Switch } from \"@components/Switch\";\nimport { Text } from \"@webpack/common\";\nimport type { MouseEventHandler, ReactNode } from \"react\";\n\nconst cl = classNameFactory(\"vc-addon-\");\n\ninterface Props {\n name: ReactNode;\n description: ReactNode;\n enabled: boolean;\n setEnabled: (enabled: boolean) => void;\n disabled?: boolean;\n isNew?: boolean;\n onMouseEnter?: MouseEventHandler<HTMLDivElement>;\n onMouseLeave?: MouseEventHandler<HTMLDivElement>;\n\n infoButton?: ReactNode;\n footer?: ReactNode;\n author?: ReactNode;\n}\n\nexport function AddonCard({ disabled, isNew, name, infoButton, footer, author, enabled, setEnabled, description, onMouseEnter, onMouseLeave }: Props) {\n return (\n <div\n className={cl(\"card\", { \"card-disabled\": disabled })}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n >\n <div className={cl(\"header\")}>\n <div className={cl(\"name-author\")}>\n <Text variant=\"text-md/bold\" className={cl(\"name\")}>\n {name}{isNew && <Badge text=\"NEW\" color=\"#ED4245\" />}\n </Text>\n {!!author && (\n <Text variant=\"text-md/normal\" className={cl(\"author\")}>\n {author}\n </Text>\n )}\n </div>\n\n {infoButton}\n\n <Switch\n checked={enabled}\n onChange={setEnabled}\n disabled={disabled}\n />\n </div>\n\n <Text className={cl(\"note\")} variant=\"text-sm/normal\">{description}</Text>\n\n {footer}\n </div>\n );\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nexport class ChangeList<T>{\n private set = new Set<T>();\n\n public get changeCount() {\n return this.set.size;\n }\n\n public get hasChanges() {\n return this.changeCount > 0;\n }\n\n public handleChange(item: T) {\n if (!this.set.delete(item))\n this.set.add(item);\n }\n\n public add(item: T) {\n return this.set.add(item);\n }\n\n public remove(item: T) {\n return this.set.delete(item);\n }\n\n public getChanges() {\n return this.set.values();\n }\n\n public map<R>(mapper: (v: T, idx: number, arr: T[]) => R): R[] {\n return [...this.getChanges()].map(mapper);\n }\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { registerCommand, unregisterCommand } from \"@api/Commands\";\nimport { Settings } from \"@api/Settings\";\nimport { Logger } from \"@utils/Logger\";\nimport { Patch, Plugin, StartAt } from \"@utils/types\";\nimport { FluxDispatcher } from \"@webpack/common\";\nimport { FluxEvents } from \"@webpack/types\";\n\nimport Plugins from \"~plugins\";\n\nimport { traceFunction } from \"../debug/Tracer\";\n\nconst logger = new Logger(\"PluginManager\", \"#a6d189\");\n\nexport const PMLogger = logger;\nexport const plugins = Plugins;\nexport const patches = [] as Patch[];\n\nconst settings = Settings.plugins;\n\nexport function isPluginEnabled(p: string) {\n return (\n Plugins[p]?.required ||\n Plugins[p]?.isDependency ||\n settings[p]?.enabled\n ) ?? false;\n}\n\nconst pluginsValues = Object.values(Plugins);\n\n// First roundtrip to mark and force enable dependencies (only for enabled plugins)\n//\n// FIXME: might need to revisit this if there's ever nested (dependencies of dependencies) dependencies since this only\n// goes for the top level and their children, but for now this works okay with the current API plugins\nfor (const p of pluginsValues) if (settings[p.name]?.enabled) {\n p.dependencies?.forEach(d => {\n const dep = Plugins[d];\n if (dep) {\n settings[d].enabled = true;\n dep.isDependency = true;\n }\n else {\n const error = new Error(`Plugin ${p.name} has unresolved dependency ${d}`);\n if (IS_DEV)\n throw error;\n logger.warn(error);\n }\n });\n}\n\nfor (const p of pluginsValues) {\n if (p.settings) {\n p.settings.pluginName = p.name;\n p.options ??= {};\n for (const [name, def] of Object.entries(p.settings.def)) {\n const checks = p.settings.checks?.[name];\n p.options[name] = { ...def, ...checks };\n }\n }\n\n if (p.patches && isPluginEnabled(p.name)) {\n for (const patch of p.patches) {\n patch.plugin = p.name;\n if (!Array.isArray(patch.replacement))\n patch.replacement = [patch.replacement];\n patches.push(patch);\n }\n }\n}\n\nexport const startAllPlugins = traceFunction(\"startAllPlugins\", function startAllPlugins(target: StartAt) {\n logger.info(`Starting plugins (stage ${target})`);\n for (const name in Plugins)\n if (isPluginEnabled(name)) {\n const p = Plugins[name];\n\n const startAt = p.startAt ?? StartAt.WebpackReady;\n if (startAt !== target) continue;\n\n startPlugin(Plugins[name]);\n }\n});\n\nexport function startDependenciesRecursive(p: Plugin) {\n let restartNeeded = false;\n const failures: string[] = [];\n p.dependencies?.forEach(dep => {\n if (!Settings.plugins[dep].enabled) {\n startDependenciesRecursive(Plugins[dep]);\n // If the plugin has patches, don't start the plugin, just enable it.\n Settings.plugins[dep].enabled = true;\n if (Plugins[dep].patches) {\n logger.warn(`Enabling dependency ${dep} requires restart.`);\n restartNeeded = true;\n return;\n }\n const result = startPlugin(Plugins[dep]);\n if (!result) failures.push(dep);\n }\n });\n return { restartNeeded, failures };\n}\n\nexport const startPlugin = traceFunction(\"startPlugin\", function startPlugin(p: Plugin) {\n const { name, commands, flux } = p;\n\n if (p.start) {\n logger.info(\"Starting plugin\", name);\n if (p.started) {\n logger.warn(`${name} already started`);\n return false;\n }\n try {\n p.start();\n p.started = true;\n } catch (e) {\n logger.error(`Failed to start ${name}\\n`, e);\n return false;\n }\n }\n\n if (commands?.length) {\n logger.info(\"Registering commands of plugin\", name);\n for (const cmd of commands) {\n try {\n registerCommand(cmd, name);\n } catch (e) {\n logger.error(`Failed to register command ${cmd.name}\\n`, e);\n return false;\n }\n }\n }\n\n if (flux) {\n for (const event in flux) {\n FluxDispatcher.subscribe(event as FluxEvents, flux[event]);\n }\n }\n\n return true;\n}, p => `startPlugin ${p.name}`);\n\nexport const stopPlugin = traceFunction(\"stopPlugin\", function stopPlugin(p: Plugin) {\n const { name, commands, flux } = p;\n if (p.stop) {\n logger.info(\"Stopping plugin\", name);\n if (!p.started) {\n logger.warn(`${name} already stopped`);\n return false;\n }\n try {\n p.stop();\n p.started = false;\n } catch (e) {\n logger.error(`Failed to stop ${name}\\n`, e);\n return false;\n }\n }\n\n if (commands?.length) {\n logger.info(\"Unregistering commands of plugin\", name);\n for (const cmd of commands) {\n try {\n unregisterCommand(cmd.name);\n } catch (e) {\n logger.error(`Failed to unregister command ${cmd.name}\\n`, e);\n return false;\n }\n }\n }\n\n if (flux) {\n for (const event in flux) {\n FluxDispatcher.unsubscribe(event as FluxEvents, flux[event]);\n }\n }\n\n return true;\n}, p => `stopPlugin ${p.name}`);\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport \"./styles.css\";\n\nimport * as DataStore from \"@api/DataStore\";\nimport { showNotice } from \"@api/Notices\";\nimport { Settings, useSettings } from \"@api/Settings\";\nimport { classNameFactory } from \"@api/Styles\";\nimport { CogWheel, InfoIcon } from \"@components/Icons\";\nimport PluginModal from \"@components/PluginSettings/PluginModal\";\nimport { AddonCard } from \"@components/VencordSettings/AddonCard\";\nimport { SettingsTab } from \"@components/VencordSettings/shared\";\nimport { ChangeList } from \"@utils/ChangeList\";\nimport { Logger } from \"@utils/Logger\";\nimport { Margins } from \"@utils/margins\";\nimport { classes, isObjectEmpty } from \"@utils/misc\";\nimport { openModalLazy } from \"@utils/modal\";\nimport { useAwaiter } from \"@utils/react\";\nimport { Plugin } from \"@utils/types\";\nimport { findByPropsLazy } from \"@webpack\";\nimport { Alerts, Button, Card, Forms, lodash, Parser, React, Select, Text, TextInput, Toasts, Tooltip } from \"@webpack/common\";\n\nimport Plugins from \"~plugins\";\n\nimport { startDependenciesRecursive, startPlugin, stopPlugin } from \"../../plugins\";\n\n\nconst cl = classNameFactory(\"vc-plugins-\");\nconst logger = new Logger(\"PluginSettings\", \"#a6d189\");\n\nconst InputStyles = findByPropsLazy(\"inputDefault\", \"inputWrapper\");\nconst ButtonClasses = findByPropsLazy(\"button\", \"disabled\", \"enabled\");\n\n\nfunction showErrorToast(message: string) {\n Toasts.show({\n message,\n type: Toasts.Type.FAILURE,\n id: Toasts.genId(),\n options: {\n position: Toasts.Position.BOTTOM\n }\n });\n}\n\nfunction ReloadRequiredCard({ required }: { required: boolean; }) {\n return (\n <Card className={cl(\"info-card\", { \"restart-card\": required })}>\n {required ? (\n <>\n <Forms.FormTitle tag=\"h5\">Restart required!</Forms.FormTitle>\n <Forms.FormText className={cl(\"dep-text\")}>\n Restart now to apply new plugins and their settings\n </Forms.FormText>\n <Button color={Button.Colors.YELLOW} onClick={() => location.reload()}>\n Restart\n </Button>\n </>\n ) : (\n <>\n <Forms.FormTitle tag=\"h5\">Plugin Management</Forms.FormTitle>\n <Forms.FormText>Press the cog wheel or info icon to get more info on a plugin</Forms.FormText>\n <Forms.FormText>Plugins with a cog wheel have settings you can modify!</Forms.FormText>\n </>\n )}\n </Card>\n );\n}\n\ninterface PluginCardProps extends React.HTMLProps<HTMLDivElement> {\n plugin: Plugin;\n disabled: boolean;\n onRestartNeeded(name: string): void;\n isNew?: boolean;\n}\n\nexport function PluginCard({ plugin, disabled, onRestartNeeded, onMouseEnter, onMouseLeave, isNew }: PluginCardProps) {\n const settings = Settings.plugins[plugin.name];\n\n const isEnabled = () => settings.enabled ?? false;\n\n function openModal() {\n openModalLazy(async () => {\n return modalProps => {\n return <PluginModal {...modalProps} plugin={plugin} onRestartNeeded={() => onRestartNeeded(plugin.name)} />;\n };\n });\n }\n\n function toggleEnabled() {\n const wasEnabled = isEnabled();\n\n // If we're enabling a plugin, make sure all deps are enabled recursively.\n if (!wasEnabled) {\n const { restartNeeded, failures } = startDependenciesRecursive(plugin);\n if (failures.length) {\n logger.error(`Failed to start dependencies for ${plugin.name}: ${failures.join(\", \")}`);\n showNotice(\"Failed to start dependencies: \" + failures.join(\", \"), \"Close\", () => null);\n return;\n } else if (restartNeeded) {\n // If any dependencies have patches, don't start the plugin yet.\n settings.enabled = true;\n onRestartNeeded(plugin.name);\n return;\n }\n }\n\n // if the plugin has patches, dont use stopPlugin/startPlugin. Wait for restart to apply changes.\n if (plugin.patches?.length) {\n settings.enabled = !wasEnabled;\n onRestartNeeded(plugin.name);\n return;\n }\n\n // If the plugin is enabled, but hasn't been started, then we can just toggle it off.\n if (wasEnabled && !plugin.started) {\n settings.enabled = !wasEnabled;\n return;\n }\n\n const result = wasEnabled ? stopPlugin(plugin) : startPlugin(plugin);\n\n if (!result) {\n settings.enabled = false;\n\n const msg = `Error while ${wasEnabled ? \"stopping\" : \"starting\"} plugin ${plugin.name}`;\n logger.error(msg);\n showErrorToast(msg);\n return;\n }\n\n settings.enabled = !wasEnabled;\n }\n\n return (\n <AddonCard\n name={plugin.name}\n description={plugin.description}\n isNew={isNew}\n enabled={isEnabled()}\n setEnabled={toggleEnabled}\n disabled={disabled}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n infoButton={\n <button role=\"switch\" onClick={() => openModal()} className={classes(ButtonClasses.button, cl(\"info-button\"))}>\n {plugin.options && !isObjectEmpty(plugin.options)\n ? <CogWheel />\n : <InfoIcon />}\n </button>\n }\n />\n );\n}\n\nconst enum SearchStatus {\n ALL,\n ENABLED,\n DISABLED,\n NEW\n}\n\nexport default function PluginSettings() {\n const settings = useSettings();\n const changes = React.useMemo(() => new ChangeList<string>(), []);\n\n React.useEffect(() => {\n return () => void (changes.hasChanges && Alerts.show({\n title: \"Restart required\",\n body: (\n <>\n <p>The following plugins require a restart:</p>\n <div>{changes.map((s, i) => (\n <>\n {i > 0 && \", \"}\n {Parser.parse(\"`\" + s + \"`\")}\n </>\n ))}</div>\n </>\n ),\n confirmText: \"Restart now\",\n cancelText: \"Later!\",\n onConfirm: () => location.reload()\n }));\n }, []);\n\n const depMap = React.useMemo(() => {\n const o = {} as Record<string, string[]>;\n for (const plugin in Plugins) {\n const deps = Plugins[plugin].dependencies;\n if (deps) {\n for (const dep of deps) {\n o[dep] ??= [];\n o[dep].push(plugin);\n }\n }\n }\n return o;\n }, []);\n\n const sortedPlugins = React.useMemo(() => Object.values(Plugins)\n .sort((a, b) => a.name.localeCompare(b.name)), []);\n\n const [searchValue, setSearchValue] = React.useState({ value: \"\", status: SearchStatus.ALL });\n\n const onSearch = (query: string) => setSearchValue(prev => ({ ...prev, value: query }));\n const onStatusChange = (status: SearchStatus) => setSearchValue(prev => ({ ...prev, status }));\n\n const pluginFilter = (plugin: typeof Plugins[keyof typeof Plugins]) => {\n const enabled = settings.plugins[plugin.name]?.enabled;\n if (enabled && searchValue.status === SearchStatus.DISABLED) return false;\n if (!enabled && searchValue.status === SearchStatus.ENABLED) return false;\n if (searchValue.status === SearchStatus.NEW && !newPlugins?.includes(plugin.name)) return false;\n if (!searchValue.value.length) return true;\n\n const v = searchValue.value.toLowerCase();\n return (\n plugin.name.toLowerCase().includes(v) ||\n plugin.description.toLowerCase().includes(v) ||\n plugin.tags?.some(t => t.toLowerCase().includes(v))\n );\n };\n\n const [newPlugins] = useAwaiter(() => DataStore.get(\"Vencord_existingPlugins\").then((cachedPlugins: Record<string, number> | undefined) => {\n const now = Date.now() / 1000;\n const existingTimestamps: Record<string, number> = {};\n const sortedPluginNames = Object.values(sortedPlugins).map(plugin => plugin.name);\n\n const newPlugins: string[] = [];\n for (const { name: p } of sortedPlugins) {\n const time = existingTimestamps[p] = cachedPlugins?.[p] ?? now;\n if ((time + 60 * 60 * 24 * 2) > now) {\n newPlugins.push(p);\n }\n }\n DataStore.set(\"Vencord_existingPlugins\", existingTimestamps);\n\n return lodash.isEqual(newPlugins, sortedPluginNames) ? [] : newPlugins;\n }));\n\n type P = JSX.Element | JSX.Element[];\n let plugins: P, requiredPlugins: P;\n if (sortedPlugins?.length) {\n plugins = [];\n requiredPlugins = [];\n\n for (const p of sortedPlugins) {\n if (!p.options && p.name.endsWith(\"API\") && searchValue.value !== \"API\")\n continue;\n\n if (!pluginFilter(p)) continue;\n\n const isRequired = p.required || depMap[p.name]?.some(d => settings.plugins[d].enabled);\n\n if (isRequired) {\n const tooltipText = p.required\n ? \"This plugin is required for Vencord to function.\"\n : makeDependencyList(depMap[p.name]?.filter(d => settings.plugins[d].enabled));\n\n requiredPlugins.push(\n <Tooltip text={tooltipText} key={p.name}>\n {({ onMouseLeave, onMouseEnter }) => (\n <PluginCard\n onMouseLeave={onMouseLeave}\n onMouseEnter={onMouseEnter}\n onRestartNeeded={name => changes.handleChange(name)}\n disabled={true}\n plugin={p}\n />\n )}\n </Tooltip>\n );\n } else {\n plugins.push(\n <PluginCard\n onRestartNeeded={name => changes.handleChange(name)}\n disabled={false}\n plugin={p}\n isNew={newPlugins?.includes(p.name)}\n key={p.name}\n />\n );\n }\n\n }\n } else {\n plugins = requiredPlugins = <Text variant=\"text-md/normal\">No plugins meet search criteria.</Text>;\n }\n\n return (\n <SettingsTab title=\"Plugins\">\n <ReloadRequiredCard required={changes.hasChanges} />\n\n <Forms.FormTitle tag=\"h5\" className={classes(Margins.top20, Margins.bottom8)}>\n Filters\n </Forms.FormTitle>\n\n <div className={cl(\"filter-controls\")}>\n <TextInput autoFocus value={searchValue.value} placeholder=\"Search for a plugin...\" onChange={onSearch} className={Margins.bottom20} />\n <div className={InputStyles.inputWrapper}>\n <Select\n className={InputStyles.inputDefault}\n options={[\n { label: \"Show All\", value: SearchStatus.ALL, default: true },\n { label: \"Show Enabled\", value: SearchStatus.ENABLED },\n { label: \"Show Disabled\", value: SearchStatus.DISABLED },\n { label: \"Show New\", value: SearchStatus.NEW }\n ]}\n serialize={String}\n select={onStatusChange}\n isSelected={v => v === searchValue.status}\n closeOnSelect={true}\n />\n </div>\n </div>\n\n <Forms.FormTitle className={Margins.top20}>Plugins</Forms.FormTitle>\n\n <div className={cl(\"grid\")}>\n {plugins}\n </div>\n\n <Forms.FormDivider className={Margins.top20} />\n\n <Forms.FormTitle tag=\"h5\" className={classes(Margins.top20, Margins.bottom8)}>\n Required Plugins\n </Forms.FormTitle>\n <div className={cl(\"grid\")}>\n {requiredPlugins}\n </div>\n </SettingsTab >\n );\n}\n\nfunction makeDependencyList(deps: string[]) {\n return (\n <React.Fragment>\n <Forms.FormText>This plugin is required by:</Forms.FormText>\n {deps.map((dep: string) => <Forms.FormText className={cl(\"dep-text\")}>{dep}</Forms.FormText>)}\n </React.Fragment>\n );\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport PluginSettings from \"@components/PluginSettings\";\n\nimport { wrapTab } from \"./shared\";\n\nexport default wrapTab(PluginSettings, \"Plugins\");\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { React } from \"@webpack/common\";\n\ninterface Props extends React.DetailedHTMLProps<React.AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement> {\n disabled?: boolean;\n}\n\nexport function Link(props: React.PropsWithChildren<Props>) {\n if (props.disabled) {\n props.style ??= {};\n props.style.pointerEvents = \"none\";\n props[\"aria-disabled\"] = true;\n }\n return (\n <a role=\"link\" target=\"_blank\" {...props}>\n {props.children}\n </a>\n );\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { useSettings } from \"@api/Settings\";\nimport { classNameFactory } from \"@api/Styles\";\nimport { Flex } from \"@components/Flex\";\nimport { DeleteIcon } from \"@components/Icons\";\nimport { Link } from \"@components/Link\";\nimport { openInviteModal } from \"@utils/discord\";\nimport { Margins } from \"@utils/margins\";\nimport { classes } from \"@utils/misc\";\nimport { showItemInFolder } from \"@utils/native\";\nimport { useAwaiter } from \"@utils/react\";\nimport { findByPropsLazy, findLazy } from \"@webpack\";\nimport { Button, Card, Forms, React, showToast, TabBar, TextArea, useEffect, useRef, useState } from \"@webpack/common\";\nimport { UserThemeHeader } from \"main/themes\";\nimport type { ComponentType, Ref, SyntheticEvent } from \"react\";\n\nimport { AddonCard } from \"./AddonCard\";\nimport { SettingsTab, wrapTab } from \"./shared\";\n\ntype FileInput = ComponentType<{\n ref: Ref<HTMLInputElement>;\n onChange: (e: SyntheticEvent<HTMLInputElement>) => void;\n multiple?: boolean;\n filters?: { name?: string; extensions: string[]; }[];\n}>;\n\nconst InviteActions = findByPropsLazy(\"resolveInvite\");\nconst FileInput: FileInput = findLazy(m => m.prototype?.activateUploadDialogue && m.prototype.setRef);\nconst TextAreaProps = findLazy(m => typeof m.textarea === \"string\");\n\nconst cl = classNameFactory(\"vc-settings-theme-\");\n\nfunction Validator({ link }: { link: string; }) {\n const [res, err, pending] = useAwaiter(() => fetch(link).then(res => {\n if (res.status > 300) throw `${res.status} ${res.statusText}`;\n const contentType = res.headers.get(\"Content-Type\");\n if (!contentType?.startsWith(\"text/css\") && !contentType?.startsWith(\"text/plain\"))\n throw \"Not a CSS file. Remember to use the raw link!\";\n\n return \"Okay!\";\n }));\n\n const text = pending\n ? \"Checking...\"\n : err\n ? `Error: ${err instanceof Error ? err.message : String(err)}`\n : \"Valid!\";\n\n return <Forms.FormText style={{\n color: pending ? \"var(--text-muted)\" : err ? \"var(--text-danger)\" : \"var(--text-positive)\"\n }}>{text}</Forms.FormText>;\n}\n\nfunction Validators({ themeLinks }: { themeLinks: string[]; }) {\n if (!themeLinks.length) return null;\n\n return (\n <>\n <Forms.FormTitle className={Margins.top20} tag=\"h5\">Validator</Forms.FormTitle>\n <Forms.FormText>This section will tell you whether your themes can successfully be loaded</Forms.FormText>\n <div>\n {themeLinks.map(link => (\n <Card style={{\n padding: \".5em\",\n marginBottom: \".5em\",\n marginTop: \".5em\"\n }} key={link}>\n <Forms.FormTitle tag=\"h5\" style={{\n overflowWrap: \"break-word\"\n }}>\n {link}\n </Forms.FormTitle>\n <Validator link={link} />\n </Card>\n ))}\n </div>\n </>\n );\n}\n\ninterface ThemeCardProps {\n theme: UserThemeHeader;\n enabled: boolean;\n onChange: (enabled: boolean) => void;\n onDelete: () => void;\n}\n\nfunction ThemeCard({ theme, enabled, onChange, onDelete }: ThemeCardProps) {\n return (\n <AddonCard\n name={theme.name}\n description={theme.description}\n author={theme.author}\n enabled={enabled}\n setEnabled={onChange}\n infoButton={\n IS_WEB && (\n <div style={{ cursor: \"pointer\", color: \"var(--status-danger\" }} onClick={onDelete}>\n <DeleteIcon />\n </div>\n )\n }\n footer={\n <Flex flexDirection=\"row\" style={{ gap: \"0.2em\" }}>\n {!!theme.website && <Link href={theme.website}>Website</Link>}\n {!!(theme.website && theme.invite) && \" \u2022 \"}\n {!!theme.invite && (\n <Link\n href={`https://discord.gg/${theme.invite}`}\n onClick={async e => {\n e.preventDefault();\n theme.invite != null && openInviteModal(theme.invite).catch(() => showToast(\"Invalid or expired invite\"));\n }}\n >\n Discord Server\n </Link>\n )}\n </Flex>\n }\n />\n );\n}\n\nenum ThemeTab {\n LOCAL,\n ONLINE\n}\n\nfunction ThemesTab() {\n const settings = useSettings([\"themeLinks\", \"enabledThemes\"]);\n\n const fileInputRef = useRef<HTMLInputElement>(null);\n const [currentTab, setCurrentTab] = useState(ThemeTab.LOCAL);\n const [themeText, setThemeText] = useState(settings.themeLinks.join(\"\\n\"));\n const [userThemes, setUserThemes] = useState<UserThemeHeader[] | null>(null);\n const [themeDir, , themeDirPending] = useAwaiter(VencordNative.themes.getThemesDir);\n\n useEffect(() => {\n refreshLocalThemes();\n }, []);\n\n async function refreshLocalThemes() {\n const themes = await VencordNative.themes.getThemesList();\n setUserThemes(themes);\n }\n\n // When a local theme is enabled/disabled, update the settings\n function onLocalThemeChange(fileName: string, value: boolean) {\n if (value) {\n if (settings.enabledThemes.includes(fileName)) return;\n settings.enabledThemes = [...settings.enabledThemes, fileName];\n } else {\n settings.enabledThemes = settings.enabledThemes.filter(f => f !== fileName);\n }\n }\n\n async function onFileUpload(e: SyntheticEvent<HTMLInputElement>) {\n e.stopPropagation();\n e.preventDefault();\n if (!e.currentTarget?.files?.length) return;\n const { files } = e.currentTarget;\n\n const uploads = Array.from(files, file => {\n const { name } = file;\n if (!name.endsWith(\".css\")) return;\n\n return new Promise<void>((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => {\n VencordNative.themes.uploadTheme(name, reader.result as string)\n .then(resolve)\n .catch(reject);\n };\n reader.readAsText(file);\n });\n });\n\n await Promise.all(uploads);\n refreshLocalThemes();\n }\n\n function renderLocalThemes() {\n return (\n <>\n <Card className=\"vc-settings-card\">\n <Forms.FormTitle tag=\"h5\">Find Themes:</Forms.FormTitle>\n <div style={{ marginBottom: \".5em\", display: \"flex\", flexDirection: \"column\" }}>\n <Link style={{ marginRight: \".5em\" }} href=\"https://betterdiscord.app/themes\">\n BetterDiscord Themes\n </Link>\n <Link href=\"https://github.com/search?q=discord+theme\">GitHub</Link>\n </div>\n <Forms.FormText>If using the BD site, click on \"Download\" and place the downloaded .theme.css file into your themes folder.</Forms.FormText>\n </Card>\n\n <Forms.FormSection title=\"Local Themes\">\n <Card className=\"vc-settings-quick-actions-card\">\n <>\n {IS_WEB ?\n (\n <Button\n size={Button.Sizes.SMALL}\n disabled={themeDirPending}\n >\n Upload Theme\n <FileInput\n ref={fileInputRef}\n onChange={onFileUpload}\n multiple={true}\n filters={[{ extensions: [\"css\"] }]}\n />\n </Button>\n ) : (\n <Button\n onClick={() => showItemInFolder(themeDir!)}\n size={Button.Sizes.SMALL}\n disabled={themeDirPending}\n >\n Open Themes Folder\n </Button>\n )}\n <Button\n onClick={refreshLocalThemes}\n size={Button.Sizes.SMALL}\n >\n Load missing Themes\n </Button>\n <Button\n onClick={() => VencordNative.quickCss.openEditor()}\n size={Button.Sizes.SMALL}\n >\n Edit QuickCSS\n </Button>\n </>\n </Card>\n\n <div className={cl(\"grid\")}>\n {userThemes?.map(theme => (\n <ThemeCard\n key={theme.fileName}\n enabled={settings.enabledThemes.includes(theme.fileName)}\n onChange={enabled => onLocalThemeChange(theme.fileName, enabled)}\n onDelete={async () => {\n onLocalThemeChange(theme.fileName, false);\n await VencordNative.themes.deleteTheme(theme.fileName);\n refreshLocalThemes();\n }}\n theme={theme}\n />\n ))}\n </div>\n </Forms.FormSection>\n </>\n );\n }\n\n // When the user leaves the online theme textbox, update the settings\n function onBlur() {\n settings.themeLinks = [...new Set(\n themeText\n .trim()\n .split(/\\n+/)\n .map(s => s.trim())\n .filter(Boolean)\n )];\n }\n\n function renderOnlineThemes() {\n return (\n <>\n <Card className=\"vc-settings-card vc-text-selectable\">\n <Forms.FormTitle tag=\"h5\">Paste links to css files here</Forms.FormTitle>\n <Forms.FormText>One link per line</Forms.FormText>\n <Forms.FormText>Make sure to use direct links to files (raw or github.io)!</Forms.FormText>\n </Card>\n\n <Forms.FormSection title=\"Online Themes\" tag=\"h5\">\n <TextArea\n value={themeText}\n onChange={setThemeText}\n className={classes(TextAreaProps.textarea, \"vc-settings-theme-links\")}\n placeholder=\"Theme Links\"\n spellCheck={false}\n onBlur={onBlur}\n rows={10}\n />\n <Validators themeLinks={settings.themeLinks} />\n </Forms.FormSection>\n </>\n );\n }\n\n return (\n <SettingsTab title=\"Themes\">\n <TabBar\n type=\"top\"\n look=\"brand\"\n className=\"vc-settings-tab-bar\"\n selectedItem={currentTab}\n onItemSelect={setCurrentTab}\n >\n <TabBar.Item\n className=\"vc-settings-tab-bar-item\"\n id={ThemeTab.LOCAL}\n >\n Local Themes\n </TabBar.Item>\n <TabBar.Item\n className=\"vc-settings-tab-bar-item\"\n id={ThemeTab.ONLINE}\n >\n Online Themes\n </TabBar.Item>\n </TabBar>\n\n {currentTab === ThemeTab.LOCAL && renderLocalThemes()}\n {currentTab === ThemeTab.ONLINE && renderOnlineThemes()}\n </SettingsTab>\n );\n}\n\nexport default wrapTab(ThemesTab, \"Themes\");\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { useSettings } from \"@api/Settings\";\nimport { ErrorCard } from \"@components/ErrorCard\";\nimport { Flex } from \"@components/Flex\";\nimport { Link } from \"@components/Link\";\nimport { Margins } from \"@utils/margins\";\nimport { classes } from \"@utils/misc\";\nimport { relaunch } from \"@utils/native\";\nimport { useAwaiter } from \"@utils/react\";\nimport { changes, checkForUpdates, getRepo, isNewer, update, updateError, UpdateLogger } from \"@utils/updater\";\nimport { Alerts, Button, Card, Forms, Parser, React, Switch, Toasts } from \"@webpack/common\";\n\nimport gitHash from \"~git-hash\";\n\nimport { SettingsTab, wrapTab } from \"./shared\";\n\nfunction withDispatcher(dispatcher: React.Dispatch<React.SetStateAction<boolean>>, action: () => any) {\n return async () => {\n dispatcher(true);\n try {\n await action();\n } catch (e: any) {\n UpdateLogger.error(\"Failed to update\", e);\n if (!e) {\n var err = \"An unknown error occurred (error is undefined).\\nPlease try again.\";\n } else if (e.code && e.cmd) {\n const { code, path, cmd, stderr } = e;\n\n if (code === \"ENOENT\")\n var err = `Command \\`${path}\\` not found.\\nPlease install it and try again`;\n else {\n var err = `An error occurred while running \\`${cmd}\\`:\\n`;\n err += stderr || `Code \\`${code}\\`. See the console for more info`;\n }\n\n } else {\n var err = \"An unknown error occurred. See the console for more info.\";\n }\n Alerts.show({\n title: \"Oops!\",\n body: (\n <ErrorCard>\n {err.split(\"\\n\").map(line => <div>{Parser.parse(line)}</div>)}\n </ErrorCard>\n )\n });\n }\n finally {\n dispatcher(false);\n }\n };\n}\n\ninterface CommonProps {\n repo: string;\n repoPending: boolean;\n}\n\nfunction HashLink({ repo, hash, disabled = false }: { repo: string, hash: string, disabled?: boolean; }) {\n return <Link href={`${repo}/commit/${hash}`} disabled={disabled}>\n {hash}\n </Link>;\n}\n\nfunction Changes({ updates, repo, repoPending }: CommonProps & { updates: typeof changes; }) {\n return (\n <Card style={{ padding: \"0 0.5em\" }}>\n {updates.map(({ hash, author, message }) => (\n <div style={{\n marginTop: \"0.5em\",\n marginBottom: \"0.5em\"\n }}>\n <code><HashLink {...{ repo, hash }} disabled={repoPending} /></code>\n <span style={{\n marginLeft: \"0.5em\",\n color: \"var(--text-normal)\"\n }}>{message} - {author}</span>\n </div>\n ))}\n </Card>\n );\n}\n\nfunction Updatable(props: CommonProps) {\n const [updates, setUpdates] = React.useState(changes);\n const [isChecking, setIsChecking] = React.useState(false);\n const [isUpdating, setIsUpdating] = React.useState(false);\n\n const isOutdated = (updates?.length ?? 0) > 0;\n\n return (\n <>\n {!updates && updateError ? (\n <>\n <Forms.FormText>Failed to check updates. Check the console for more info</Forms.FormText>\n <ErrorCard style={{ padding: \"1em\" }}>\n <p>{updateError.stderr || updateError.stdout || \"An unknown error occurred\"}</p>\n </ErrorCard>\n </>\n ) : (\n <Forms.FormText className={Margins.bottom8}>\n {isOutdated ? (updates.length === 1 ? \"There is 1 Update\" : `There are ${updates.length} Updates`) : \"Up to Date!\"}\n </Forms.FormText>\n )}\n\n {isOutdated && <Changes updates={updates} {...props} />}\n\n <Flex className={classes(Margins.bottom8, Margins.top8)}>\n {isOutdated && <Button\n size={Button.Sizes.SMALL}\n disabled={isUpdating || isChecking}\n onClick={withDispatcher(setIsUpdating, async () => {\n if (await update()) {\n setUpdates([]);\n await new Promise<void>(r => {\n Alerts.show({\n title: \"Update Success!\",\n body: \"Successfully updated. Restart now to apply the changes?\",\n confirmText: \"Restart\",\n cancelText: \"Not now!\",\n onConfirm() {\n relaunch();\n r();\n },\n onCancel: r\n });\n });\n }\n })}\n >\n Update Now\n </Button>}\n <Button\n size={Button.Sizes.SMALL}\n disabled={isUpdating || isChecking}\n onClick={withDispatcher(setIsChecking, async () => {\n const outdated = await checkForUpdates();\n if (outdated) {\n setUpdates(changes);\n } else {\n setUpdates([]);\n Toasts.show({\n message: \"No updates found!\",\n id: Toasts.genId(),\n type: Toasts.Type.MESSAGE,\n options: {\n position: Toasts.Position.BOTTOM\n }\n });\n }\n })}\n >\n Check for Updates\n </Button>\n </Flex>\n </>\n );\n}\n\nfunction Newer(props: CommonProps) {\n return (\n <>\n <Forms.FormText className={Margins.bottom8}>\n Your local copy has more recent commits. Please stash or reset them.\n </Forms.FormText>\n <Changes {...props} updates={changes} />\n </>\n );\n}\n\nfunction Updater() {\n const settings = useSettings([\"notifyAboutUpdates\", \"autoUpdate\", \"autoUpdateNotification\"]);\n\n const [repo, err, repoPending] = useAwaiter(getRepo, { fallbackValue: \"Loading...\" });\n\n React.useEffect(() => {\n if (err)\n UpdateLogger.error(\"Failed to retrieve repo\", err);\n }, [err]);\n\n const commonProps: CommonProps = {\n repo,\n repoPending\n };\n\n return (\n <SettingsTab title=\"Vencord Updater\">\n <Forms.FormTitle tag=\"h5\">Updater Settings</Forms.FormTitle>\n <Switch\n value={settings.notifyAboutUpdates}\n onChange={(v: boolean) => settings.notifyAboutUpdates = v}\n note=\"Shows a notification on startup\"\n disabled={settings.autoUpdate}\n >\n Get notified about new updates\n </Switch>\n <Switch\n value={settings.autoUpdate}\n onChange={(v: boolean) => settings.autoUpdate = v}\n note=\"Automatically update Vencord without confirmation prompt\"\n >\n Automatically update\n </Switch>\n <Switch\n value={settings.autoUpdateNotification}\n onChange={(v: boolean) => settings.autoUpdateNotification = v}\n note=\"Shows a notification when Vencord automatically updates\"\n disabled={!settings.autoUpdate}\n >\n Get notified when an automatic update completes\n </Switch>\n\n <Forms.FormTitle tag=\"h5\">Repo</Forms.FormTitle>\n\n <Forms.FormText className=\"vc-text-selectable\">\n {repoPending\n ? repo\n : err\n ? \"Failed to retrieve - check console\"\n : (\n <Link href={repo}>\n {repo.split(\"/\").slice(-2).join(\"/\")}\n </Link>\n )\n }\n {\" \"}(<HashLink hash={gitHash} repo={repo} disabled={repoPending} />)\n </Forms.FormText>\n\n <Forms.FormDivider className={Margins.top8 + \" \" + Margins.bottom8} />\n\n <Forms.FormTitle tag=\"h5\">Updates</Forms.FormTitle>\n\n {isNewer ? <Newer {...commonProps} /> : <Updatable {...commonProps} />}\n </SettingsTab>\n );\n}\n\nexport default IS_UPDATER_DISABLED ? null : wrapTab(Updater, \"Updater\");\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { React, TextInput } from \"@webpack/common\";\n\n// TODO: Refactor settings to use this as well\ninterface TextInputProps {\n /**\n * WARNING: Changing this between renders will have no effect!\n */\n value: string;\n /**\n * This will only be called if the new value passed validate()\n */\n onChange(newValue: string): void;\n /**\n * Optionally validate the user input\n * Return true if the input is valid\n * Otherwise, return a string containing the reason for this input being invalid\n */\n validate(v: string): true | string;\n}\n\n/**\n * A very simple wrapper around Discord's TextInput that validates input and shows\n * the user an error message and only calls your onChange when the input is valid\n */\nexport function CheckedTextInput({ value: initialValue, onChange, validate }: TextInputProps) {\n const [value, setValue] = React.useState(initialValue);\n const [error, setError] = React.useState<string>();\n\n function handleChange(v: string) {\n setValue(v);\n const res = validate(v);\n if (res === true) {\n setError(void 0);\n onChange(v);\n } else {\n setError(res);\n }\n }\n\n return (\n <>\n <TextInput\n type=\"text\"\n value={value}\n onChange={handleChange}\n error={error}\n />\n </>\n );\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { showNotification } from \"@api/Notifications\";\nimport { Settings, useSettings } from \"@api/Settings\";\nimport { CheckedTextInput } from \"@components/CheckedTextInput\";\nimport { Link } from \"@components/Link\";\nimport { authorizeCloud, cloudLogger, deauthorizeCloud, getCloudAuth, getCloudUrl } from \"@utils/cloud\";\nimport { Margins } from \"@utils/margins\";\nimport { deleteCloudSettings, getCloudSettings, putCloudSettings } from \"@utils/settingsSync\";\nimport { Alerts, Button, Forms, Switch, Tooltip } from \"@webpack/common\";\n\nimport { SettingsTab, wrapTab } from \"./shared\";\n\nfunction validateUrl(url: string) {\n try {\n new URL(url);\n return true;\n } catch {\n return \"Invalid URL\";\n }\n}\n\nasync function eraseAllData() {\n const res = await fetch(new URL(\"/v1/\", getCloudUrl()), {\n method: \"DELETE\",\n headers: new Headers({\n Authorization: await getCloudAuth()\n })\n });\n\n if (!res.ok) {\n cloudLogger.error(`Failed to erase data, API returned ${res.status}`);\n showNotification({\n title: \"Cloud Integrations\",\n body: `Could not erase all data (API returned ${res.status}), please contact support.`,\n color: \"var(--red-360)\"\n });\n return;\n }\n\n Settings.cloud.authenticated = false;\n await deauthorizeCloud();\n\n showNotification({\n title: \"Cloud Integrations\",\n body: \"Successfully erased all data.\",\n color: \"var(--green-360)\"\n });\n}\n\nfunction SettingsSyncSection() {\n const { cloud } = useSettings([\"cloud.authenticated\", \"cloud.settingsSync\"]);\n const sectionEnabled = cloud.authenticated && cloud.settingsSync;\n\n return (\n <Forms.FormSection title=\"Settings Sync\" className={Margins.top16}>\n <Forms.FormText variant=\"text-md/normal\" className={Margins.bottom20}>\n Synchronize your settings to the cloud. This allows easy synchronization across multiple devices with\n minimal effort.\n </Forms.FormText>\n <Switch\n key=\"cloud-sync\"\n disabled={!cloud.authenticated}\n value={cloud.settingsSync}\n onChange={v => { cloud.settingsSync = v; }}\n >\n Settings Sync\n </Switch>\n <div className=\"vc-cloud-settings-sync-grid\">\n <Button\n size={Button.Sizes.SMALL}\n disabled={!sectionEnabled}\n onClick={() => putCloudSettings(true)}\n >Sync to Cloud</Button>\n <Tooltip text=\"This will overwrite your local settings with the ones on the cloud. Use wisely!\">\n {({ onMouseLeave, onMouseEnter }) => (\n <Button\n onMouseLeave={onMouseLeave}\n onMouseEnter={onMouseEnter}\n size={Button.Sizes.SMALL}\n color={Button.Colors.RED}\n disabled={!sectionEnabled}\n onClick={() => getCloudSettings(true, true)}\n >Sync from Cloud</Button>\n )}\n </Tooltip>\n <Button\n size={Button.Sizes.SMALL}\n color={Button.Colors.RED}\n disabled={!sectionEnabled}\n onClick={() => deleteCloudSettings()}\n >Delete Cloud Settings</Button>\n </div>\n </Forms.FormSection>\n );\n}\n\nfunction CloudTab() {\n const settings = useSettings([\"cloud.authenticated\", \"cloud.url\"]);\n\n return (\n <SettingsTab title=\"Vencord Cloud\">\n <Forms.FormSection title=\"Cloud Settings\" className={Margins.top16}>\n <Forms.FormText variant=\"text-md/normal\" className={Margins.bottom20}>\n Vencord comes with a cloud integration that adds goodies like settings sync across devices.\n It <Link href=\"https://vencord.dev/cloud/privacy\">respects your privacy</Link>, and\n the <Link href=\"https://github.com/Vencord/Backend\">source code</Link> is AGPL 3.0 licensed so you\n can host it yourself.\n </Forms.FormText>\n <Switch\n key=\"backend\"\n value={settings.cloud.authenticated}\n onChange={v => { v && authorizeCloud(); if (!v) settings.cloud.authenticated = v; }}\n note=\"This will request authorization if you have not yet set up cloud integrations.\"\n >\n Enable Cloud Integrations\n </Switch>\n <Forms.FormTitle tag=\"h5\">Backend URL</Forms.FormTitle>\n <Forms.FormText className={Margins.bottom8}>\n Which backend to use when using cloud integrations.\n </Forms.FormText>\n <CheckedTextInput\n key=\"backendUrl\"\n value={settings.cloud.url}\n onChange={v => { settings.cloud.url = v; settings.cloud.authenticated = false; deauthorizeCloud(); }}\n validate={validateUrl}\n />\n <Button\n className={Margins.top8}\n size={Button.Sizes.MEDIUM}\n color={Button.Colors.RED}\n disabled={!settings.cloud.authenticated}\n onClick={() => Alerts.show({\n title: \"Are you sure?\",\n body: \"Once your data is erased, we cannot recover it. There's no going back!\",\n onConfirm: eraseAllData,\n confirmText: \"Erase it!\",\n confirmColor: \"vc-cloud-erase-data-danger-btn\",\n cancelText: \"Nevermind\"\n })}\n >Erase All Data</Button>\n <Forms.FormDivider className={Margins.top16} />\n </Forms.FormSection >\n <SettingsSyncSection />\n </SettingsTab>\n );\n}\n\nexport default wrapTab(CloudTab, \"Cloud\");\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Flex } from \"@components/Flex\";\nimport { Margins } from \"@utils/margins\";\nimport { classes } from \"@utils/misc\";\nimport { downloadSettingsBackup, uploadSettingsBackup } from \"@utils/settingsSync\";\nimport { Button, Card, Text } from \"@webpack/common\";\n\nimport { SettingsTab, wrapTab } from \"./shared\";\n\nfunction BackupRestoreTab() {\n return (\n <SettingsTab title=\"Backup & Restore\">\n <Card className={classes(\"vc-settings-card\", \"vc-backup-restore-card\")}>\n <Flex flexDirection=\"column\">\n <strong>Warning</strong>\n <span>Importing a settings file will overwrite your current settings.</span>\n </Flex>\n </Card>\n <Text variant=\"text-md/normal\" className={Margins.bottom8}>\n You can import and export your Vencord settings as a JSON file.\n This allows you to easily transfer your settings to another device,\n or recover your settings after reinstalling Vencord or Discord.\n </Text>\n <Text variant=\"text-md/normal\" className={Margins.bottom8}>\n Settings Export contains:\n <ul>\n <li>&mdash; Custom QuickCSS</li>\n <li>&mdash; Theme Links</li>\n <li>&mdash; Plugin Settings</li>\n </ul>\n </Text>\n <Flex>\n <Button\n onClick={() => uploadSettingsBackup()}\n size={Button.Sizes.SMALL}\n >\n Import Settings\n </Button>\n <Button\n onClick={downloadSettingsBackup}\n size={Button.Sizes.SMALL}\n >\n Export Settings\n </Button>\n </Flex>\n </SettingsTab>\n );\n}\n\nexport default wrapTab(BackupRestoreTab, \"Backup & Restore\");\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and Megumin\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { addContextMenuPatch } from \"@api/ContextMenu\";\nimport { Settings } from \"@api/Settings\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { React, SettingsRouter } from \"@webpack/common\";\n\nimport gitHash from \"~git-hash\";\n\nexport default definePlugin({\n name: \"Settings\",\n description: \"Adds Settings UI and debug info\",\n authors: [Devs.Ven, Devs.Megu],\n required: true,\n\n start() {\n // The settings shortcuts in the user settings cog context menu\n // read the elements from a hardcoded map which for obvious reason\n // doesn't contain our sections. This patches the actions of our\n // sections to manually use SettingsRouter (which only works on desktop\n // but the context menu is usually not available on mobile anyway)\n addContextMenuPatch(\"user-settings-cog\", children => () => {\n const section = children.find(c => Array.isArray(c) && c.some(it => it?.props?.id === \"VencordSettings\")) as any;\n section?.forEach(c => {\n const id = c?.props?.id;\n if (id?.startsWith(\"Vencord\") || id?.startsWith(\"Vesktop\")) {\n c.props.action = () => SettingsRouter.open(id);\n }\n });\n });\n },\n\n patches: [{\n find: \".versionHash\",\n replacement: [\n {\n match: /\\[\\(0,.{1,3}\\.jsxs?\\)\\((.{1,10}),(\\{[^{}}]+\\{.{0,20}.versionHash,.+?\\})\\),\" \"/,\n replace: (m, component, props) => {\n props = props.replace(/children:\\[.+\\]/, \"\");\n return `${m},Vencord.Plugins.plugins.Settings.makeInfoElements(${component}, ${props})`;\n }\n }\n ]\n }, {\n find: \"Messages.ACTIVITY_SETTINGS\",\n replacement: {\n get match() {\n switch (Settings.plugins.Settings.settingsLocation) {\n case \"top\": return /\\{section:(\\i\\.\\i)\\.HEADER,\\s*label:(\\i)\\.\\i\\.Messages\\.USER_SETTINGS\\}/;\n case \"aboveNitro\": return /\\{section:(\\i\\.\\i)\\.HEADER,\\s*label:(\\i)\\.\\i\\.Messages\\.BILLING_SETTINGS\\}/;\n case \"belowNitro\": return /\\{section:(\\i\\.\\i)\\.HEADER,\\s*label:(\\i)\\.\\i\\.Messages\\.APP_SETTINGS\\}/;\n case \"belowActivity\": return /(?<=\\{section:(\\i\\.\\i)\\.DIVIDER},)\\{section:\"changelog\"/;\n case \"bottom\": return /\\{section:(\\i\\.\\i)\\.CUSTOM,\\s*element:.+?}/;\n case \"aboveActivity\":\n default:\n return /\\{section:(\\i\\.\\i)\\.HEADER,\\s*label:(\\i)\\.\\i\\.Messages\\.ACTIVITY_SETTINGS\\}/;\n }\n },\n replace: \"...$self.makeSettingsCategories($1),$&\"\n }\n }],\n\n customSections: [] as ((SectionTypes: Record<string, unknown>) => any)[],\n\n makeSettingsCategories(SectionTypes: Record<string, unknown>) {\n return [\n {\n section: SectionTypes.HEADER,\n label: \"Vencord\",\n className: \"vc-settings-header\"\n },\n {\n section: \"VencordSettings\",\n label: \"Vencord\",\n element: require(\"@components/VencordSettings/VencordTab\").default,\n className: \"vc-settings\"\n },\n {\n section: \"VencordPlugins\",\n label: \"Plugins\",\n element: require(\"@components/VencordSettings/PluginsTab\").default,\n className: \"vc-plugins\"\n },\n {\n section: \"VencordThemes\",\n label: \"Themes\",\n element: require(\"@components/VencordSettings/ThemesTab\").default,\n className: \"vc-themes\"\n },\n !IS_UPDATER_DISABLED && {\n section: \"VencordUpdater\",\n label: \"Updater\",\n element: require(\"@components/VencordSettings/UpdaterTab\").default,\n className: \"vc-updater\"\n },\n {\n section: \"VencordCloud\",\n label: \"Cloud\",\n element: require(\"@components/VencordSettings/CloudTab\").default,\n className: \"vc-cloud\"\n },\n {\n section: \"VencordSettingsSync\",\n label: \"Backup & Restore\",\n element: require(\"@components/VencordSettings/BackupAndRestoreTab\").default,\n className: \"vc-backup-restore\"\n },\n IS_DEV && {\n section: \"VencordPatchHelper\",\n label: \"Patch Helper\",\n element: require(\"@components/VencordSettings/PatchHelperTab\").default,\n className: \"vc-patch-helper\"\n },\n ...this.customSections.map(func => func(SectionTypes)),\n {\n section: SectionTypes.DIVIDER\n }\n ].filter(Boolean);\n },\n\n options: {\n settingsLocation: {\n type: OptionType.SELECT,\n description: \"Where to put the Vencord settings section\",\n options: [\n { label: \"At the very top\", value: \"top\" },\n { label: \"Above the Nitro section\", value: \"aboveNitro\" },\n { label: \"Below the Nitro section\", value: \"belowNitro\" },\n { label: \"Above Activity Settings\", value: \"aboveActivity\", default: true },\n { label: \"Below Activity Settings\", value: \"belowActivity\" },\n { label: \"At the very bottom\", value: \"bottom\" },\n ],\n restartNeeded: true\n },\n },\n\n get electronVersion() {\n return VencordNative.native.getVersions().electron || window.armcord?.electron || null;\n },\n\n get chromiumVersion() {\n try {\n return VencordNative.native.getVersions().chrome\n // @ts-ignore Typescript will add userAgentData IMMEDIATELY\n || navigator.userAgentData?.brands?.find(b => b.brand === \"Chromium\" || b.brand === \"Google Chrome\")?.version\n || null;\n } catch { // inb4 some stupid browser throws unsupported error for navigator.userAgentData, it's only in chromium\n return null;\n }\n },\n\n get additionalInfo() {\n if (IS_DEV) return \" (Dev)\";\n if (IS_WEB) return \" (Web)\";\n if (IS_VESKTOP) return ` (Vesktop v${VesktopNative.app.getVersion()})`;\n if (IS_STANDALONE) return \" (Standalone)\";\n return \"\";\n },\n\n makeInfoElements(Component: React.ComponentType<React.PropsWithChildren>, props: React.PropsWithChildren) {\n const { electronVersion, chromiumVersion, additionalInfo } = this;\n\n return (\n <>\n <Component {...props}>Vencord {gitHash}{additionalInfo}</Component>\n {electronVersion && <Component {...props}>Electron {electronVersion}</Component>}\n {chromiumVersion && <Component {...props}>Chromium {chromiumVersion}</Component>}\n </>\n );\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { DataStore } from \"@api/index\";\nimport { Devs, SUPPORT_CHANNEL_ID } from \"@utils/constants\";\nimport { isPluginDev } from \"@utils/misc\";\nimport { makeCodeblock } from \"@utils/text\";\nimport definePlugin from \"@utils/types\";\nimport { isOutdated } from \"@utils/updater\";\nimport { Alerts, Forms, UserStore } from \"@webpack/common\";\n\nimport gitHash from \"~git-hash\";\nimport plugins from \"~plugins\";\n\nimport settings from \"./settings\";\n\nconst REMEMBER_DISMISS_KEY = \"Vencord-SupportHelper-Dismiss\";\n\nconst AllowedChannelIds = [\n SUPPORT_CHANNEL_ID,\n \"1024286218801926184\", // Vencord > #bot-spam\n \"1033680203433660458\", // Vencord > #v\n];\n\nexport default definePlugin({\n name: \"SupportHelper\",\n required: true,\n description: \"Helps us provide support to you\",\n authors: [Devs.Ven],\n dependencies: [\"CommandsAPI\"],\n\n commands: [{\n name: \"vencord-debug\",\n description: \"Send Vencord Debug info\",\n predicate: ctx => AllowedChannelIds.includes(ctx.channel.id),\n async execute() {\n const { RELEASE_CHANNEL } = window.GLOBAL_ENV;\n\n const client = (() => {\n if (IS_DISCORD_DESKTOP) return `Discord Desktop v${DiscordNative.app.getVersion()}`;\n if (IS_VESKTOP) return `Vesktop v${VesktopNative.app.getVersion()}`;\n if (\"armcord\" in window) return `ArmCord v${window.armcord.version}`;\n\n // @ts-expect-error\n const name = typeof unsafeWindow !== \"undefined\" ? \"UserScript\" : \"Web\";\n return `${name} (${navigator.userAgent})`;\n })();\n\n const isApiPlugin = (plugin: string) => plugin.endsWith(\"API\") || plugins[plugin].required;\n\n const enabledPlugins = Object.keys(plugins).filter(p => Vencord.Plugins.isPluginEnabled(p) && !isApiPlugin(p));\n const enabledApiPlugins = Object.keys(plugins).filter(p => Vencord.Plugins.isPluginEnabled(p) && isApiPlugin(p));\n\n const info = {\n Vencord: `v${VERSION} \u2022 ${gitHash}${settings.additionalInfo} - ${Intl.DateTimeFormat(\"en-GB\", { dateStyle: \"medium\" }).format(BUILD_TIMESTAMP)}`,\n \"Discord Branch\": RELEASE_CHANNEL,\n Client: client,\n Platform: window.navigator.platform,\n Outdated: isOutdated,\n OpenAsar: \"openasar\" in window,\n };\n\n if (IS_DISCORD_DESKTOP) {\n info[\"Last Crash Reason\"] = (await DiscordNative.processUtils.getLastCrash())?.rendererCrashReason ?? \"N/A\";\n }\n\n const debugInfo = `\n**Vencord Debug Info**\n>>> ${Object.entries(info).map(([k, v]) => `${k}: ${v}`).join(\"\\n\")}\n\nEnabled Plugins (${enabledPlugins.length + enabledApiPlugins.length}):\n${makeCodeblock(enabledPlugins.join(\", \") + \"\\n\\n\" + enabledApiPlugins.join(\", \"))}\n`;\n\n return {\n content: debugInfo.trim().replaceAll(\"```\\n\", \"```\")\n };\n }\n }],\n\n flux: {\n async CHANNEL_SELECT({ channelId }) {\n if (channelId !== SUPPORT_CHANNEL_ID) return;\n\n if (isPluginDev(UserStore.getCurrentUser().id)) return;\n\n if (isOutdated && gitHash !== await DataStore.get(REMEMBER_DISMISS_KEY)) {\n const rememberDismiss = () => DataStore.set(REMEMBER_DISMISS_KEY, gitHash);\n\n Alerts.show({\n title: \"Hold on!\",\n body: <div>\n <Forms.FormText>You are using an outdated version of Vencord! Chances are, your issue is already fixed.</Forms.FormText>\n <Forms.FormText>\n Please first update using the Updater Page in Settings, or use the VencordInstaller (Update Vencord Button)\n to do so, in case you can't access the Updater page.\n </Forms.FormText>\n </div>,\n onCancel: rememberDismiss,\n onConfirm: rememberDismiss\n });\n }\n }\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\n\nexport default definePlugin({\n name: \"AlwaysAnimate\",\n description: \"Animates anything that can be animated\",\n authors: [Devs.FieryFlames],\n\n patches: [\n {\n find: \"canAnimate:\",\n all: true,\n // Some modules match the find but the replacement is returned untouched\n noWarn: true,\n replacement: {\n match: /canAnimate:.+?(?=([,}].*?\\)))/g,\n replace: (m, rest) => {\n const destructuringMatch = rest.match(/}=.+/);\n if (destructuringMatch == null) return \"canAnimate:!0\";\n return m;\n }\n }\n },\n {\n // Status emojis\n find: \".Messages.GUILD_OWNER,\",\n replacement: {\n match: /(?<=\\.activityEmoji,.+?animate:)\\i/,\n replace: \"!0\"\n }\n },\n {\n // Guild Banner\n find: \".animatedBannerHoverLayer,onMouseEnter:\",\n replacement: {\n match: /(?<=guildBanner:\\i,animate:)\\i(?=}\\))/,\n replace: \"!0\"\n }\n }\n ]\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\n\nexport default definePlugin({\n name: \"AlwaysTrust\",\n description: \"Removes the annoying untrusted domain and suspicious file popup\",\n authors: [Devs.zt],\n patches: [\n {\n find: \".displayName=\\\"MaskedLinkStore\\\"\",\n replacement: {\n match: /(?<=isTrustedDomain\\(\\i\\){)return \\i\\(\\i\\)/,\n replace: \"return true\"\n }\n },\n {\n find: \"isSuspiciousDownload:\",\n replacement: {\n match: /function \\i\\(\\i\\){(?=.{0,60}\\.parse\\(\\i\\))/,\n replace: \"$&return null;\"\n }\n }\n ]\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Settings } from \"@api/Settings\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin, { OptionType } from \"@utils/types\";\n\nconst enum Methods {\n Random,\n Consistent,\n Timestamp,\n}\n\nconst tarExtMatcher = /\\.tar\\.\\w+$/;\n\nexport default definePlugin({\n name: \"AnonymiseFileNames\",\n authors: [Devs.obscurity],\n description: \"Anonymise uploaded file names\",\n patches: [\n {\n find: \"instantBatchUpload:function\",\n replacement: {\n match: /uploadFiles:(.{1,2}),/,\n replace:\n \"uploadFiles:(...args)=>(args[0].uploads.forEach(f=>f.filename=$self.anonymise(f.filename)),$1(...args)),\",\n },\n },\n ],\n\n options: {\n method: {\n description: \"Anonymising method\",\n type: OptionType.SELECT,\n options: [\n { label: \"Random Characters\", value: Methods.Random, default: true },\n { label: \"Consistent\", value: Methods.Consistent },\n { label: \"Timestamp (4chan-like)\", value: Methods.Timestamp },\n ],\n },\n randomisedLength: {\n description: \"Random characters length\",\n type: OptionType.NUMBER,\n default: 7,\n disabled: () => Settings.plugins.AnonymiseFileNames.method !== Methods.Random,\n },\n consistent: {\n description: \"Consistent filename\",\n type: OptionType.STRING,\n default: \"image\",\n disabled: () => Settings.plugins.AnonymiseFileNames.method !== Methods.Consistent,\n },\n },\n\n anonymise(file: string) {\n let name = \"image\";\n const tarMatch = tarExtMatcher.exec(file);\n const extIdx = tarMatch?.index ?? file.lastIndexOf(\".\");\n const ext = extIdx !== -1 ? file.slice(extIdx) : \"\";\n\n switch (Settings.plugins.AnonymiseFileNames.method) {\n case Methods.Random:\n const chars = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\";\n name = Array.from(\n { length: Settings.plugins.AnonymiseFileNames.randomisedLength },\n () => chars[Math.floor(Math.random() * chars.length)]\n ).join(\"\");\n break;\n case Methods.Consistent:\n name = Settings.plugins.AnonymiseFileNames.consistent;\n break;\n case Methods.Timestamp:\n // UNIX timestamp in nanos, i could not find a better dependency-less way\n name = `${Math.floor(Date.now() / 1000)}${Math.floor(window.performance.now())}`;\n break;\n }\n return name + ext;\n },\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 OpenAsar\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { popNotice, showNotice } from \"@api/Notices\";\nimport { Link } from \"@components/Link\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\nimport { findByPropsLazy } from \"@webpack\";\nimport { ApplicationAssetUtils, FluxDispatcher, Forms, Toasts } from \"@webpack/common\";\n\nconst RpcUtils = findByPropsLazy(\"fetchApplicationsRPC\", \"getRemoteIconURL\");\n\nasync function lookupAsset(applicationId: string, key: string): Promise<string> {\n return (await ApplicationAssetUtils.fetchAssetIds(applicationId, [key]))[0];\n}\n\nconst apps: any = {};\nasync function lookupApp(applicationId: string): Promise<string> {\n const socket: any = {};\n await RpcUtils.fetchApplicationsRPC(socket, applicationId);\n return socket.application;\n}\n\nlet ws: WebSocket;\nexport default definePlugin({\n name: \"WebRichPresence (arRPC)\",\n description: \"Client plugin for arRPC to enable RPC on Discord Web (experimental)\",\n authors: [Devs.Ducko],\n\n settingsAboutComponent: () => (\n <>\n <Forms.FormTitle tag=\"h3\">How to use arRPC</Forms.FormTitle>\n <Forms.FormText>\n <Link href=\"https://github.com/OpenAsar/arrpc/tree/main#server\">Follow the instructions in the GitHub repo</Link> to get the server running, and then enable the plugin.\n </Forms.FormText>\n </>\n ),\n\n async handleEvent(e: MessageEvent<any>) {\n const data = JSON.parse(e.data);\n\n const { activity } = data;\n const assets = activity?.assets;\n\n if (assets?.large_image) assets.large_image = await lookupAsset(activity.application_id, assets.large_image);\n if (assets?.small_image) assets.small_image = await lookupAsset(activity.application_id, assets.small_image);\n\n if (activity) {\n const appId = activity.application_id;\n apps[appId] ||= await lookupApp(appId);\n\n const app = apps[appId];\n activity.name ||= app.name;\n }\n\n FluxDispatcher.dispatch({ type: \"LOCAL_ACTIVITY_UPDATE\", ...data });\n },\n\n async start() {\n // ArmCord comes with its own arRPC implementation, so this plugin just confuses users\n if (\"armcord\" in window) return;\n\n if (ws) ws.close();\n ws = new WebSocket(\"ws://127.0.0.1:1337\"); // try to open WebSocket\n\n ws.onmessage = this.handleEvent;\n\n const connectionSuccessful = await new Promise(res => setTimeout(() => res(ws.readyState === WebSocket.OPEN), 1000)); // check if open after 1s\n if (!connectionSuccessful) {\n showNotice(\"Failed to connect to arRPC, is it running?\", \"Retry\", () => { // show notice about failure to connect, with retry/ignore\n popNotice();\n this.start();\n });\n return;\n }\n\n Toasts.show({ // show toast on success\n message: \"Connected to arRPC\",\n type: Toasts.Type.SUCCESS,\n id: Toasts.genId(),\n options: {\n duration: 1000,\n position: Toasts.Position.BOTTOM\n }\n });\n },\n\n stop() {\n FluxDispatcher.dispatch({ type: \"LOCAL_ACTIVITY_UPDATE\", activity: null }); // clear status\n ws?.close(); // close WebSocket\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Devs } from \"@utils/constants\";\nimport definePlugin, { OptionType } from \"@utils/types\";\n\nexport default definePlugin({\n name: \"BANger\",\n description: \"Replaces the GIF in the ban dialogue with a custom one.\",\n authors: [Devs.Xinto, Devs.Glitch],\n patches: [\n {\n find: \"BAN_CONFIRM_TITLE.\",\n replacement: {\n match: /src:\\i\\(\"\\d+\"\\)/g,\n replace: \"src: Vencord.Settings.plugins.BANger.source\"\n }\n }\n ],\n options: {\n source: {\n description: \"Source to replace ban GIF with (Video or Gif)\",\n type: OptionType.STRING,\n default: \"https://i.imgur.com/wp5q52C.mp4\",\n restartNeeded: true,\n }\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport ErrorBoundary from \"@components/ErrorBoundary\";\nimport { findByPropsLazy, findComponentByCodeLazy, findStoreLazy } from \"@webpack\";\nimport { useStateFromStores } from \"@webpack/common\";\nimport type { CSSProperties } from \"react\";\n\nimport { ExpandedGuildFolderStore, settings } from \".\";\n\nconst ChannelRTCStore = findStoreLazy(\"ChannelRTCStore\");\nconst Animations = findByPropsLazy(\"a\", \"animated\", \"useTransition\");\nconst GuildsBar = findComponentByCodeLazy('(\"guildsnav\")');\n\nexport default ErrorBoundary.wrap(guildsBarProps => {\n const expandedFolders = useStateFromStores([ExpandedGuildFolderStore], () => ExpandedGuildFolderStore.getExpandedFolders());\n const isFullscreen = useStateFromStores([ChannelRTCStore], () => ChannelRTCStore.isFullscreenInContext());\n\n const Sidebar = (\n <GuildsBar\n {...guildsBarProps}\n isBetterFolders={true}\n betterFoldersExpandedIds={expandedFolders}\n />\n );\n\n const visible = !!expandedFolders.size;\n const guilds = document.querySelector(guildsBarProps.className.split(\" \").map(c => `.${c}`).join(\"\"));\n\n // We need to display none if we are in fullscreen. Yes this seems horrible doing with css, but it's literally how Discord does it.\n // Also display flex otherwise to fix scrolling\n const barStyle = {\n display: isFullscreen ? \"none\" : \"flex\",\n } as CSSProperties;\n\n if (!guilds || !settings.store.sidebarAnim) {\n return visible\n ? <div style={barStyle}>{Sidebar}</div>\n : null;\n }\n\n return (\n <Animations.Transition\n items={visible}\n from={{ width: 0 }}\n enter={{ width: guilds.getBoundingClientRect().width }}\n leave={{ width: 0 }}\n config={{ duration: 200 }}\n >\n {(animationStyle, show) =>\n show && (\n <Animations.animated.div style={{ ...animationStyle, ...barStyle }}>\n {Sidebar}\n </Animations.animated.div>\n )\n }\n </Animations.Transition>\n );\n}, { noop: true });\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { definePluginSettings } from \"@api/Settings\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { findByPropsLazy, findStoreLazy } from \"@webpack\";\nimport { FluxDispatcher, i18n } from \"@webpack/common\";\n\nimport FolderSideBar from \"./FolderSideBar\";\n\nenum FolderIconDisplay {\n Never,\n Always,\n MoreThanOneFolderExpanded\n}\n\nconst { GuildsTree } = findByPropsLazy(\"GuildsTree\");\nconst SortedGuildStore = findStoreLazy(\"SortedGuildStore\");\nexport const ExpandedGuildFolderStore = findStoreLazy(\"ExpandedGuildFolderStore\");\nconst FolderUtils = findByPropsLazy(\"move\", \"toggleGuildFolderExpand\");\n\nlet lastGuildId = null as string | null;\nlet dispatchingFoldersClose = false;\n\nfunction getGuildFolder(id: string) {\n return SortedGuildStore.getGuildFolders().find(folder => folder.guildIds.includes(id));\n}\n\nfunction closeFolders() {\n for (const id of ExpandedGuildFolderStore.getExpandedFolders())\n FolderUtils.toggleGuildFolderExpand(id);\n}\n\nexport const settings = definePluginSettings({\n sidebar: {\n type: OptionType.BOOLEAN,\n description: \"Display servers from folder on dedicated sidebar\",\n restartNeeded: true,\n default: true\n },\n sidebarAnim: {\n type: OptionType.BOOLEAN,\n description: \"Animate opening the folder sidebar\",\n default: true\n },\n closeAllFolders: {\n type: OptionType.BOOLEAN,\n description: \"Close all folders when selecting a server not in a folder\",\n default: false\n },\n closeAllHomeButton: {\n type: OptionType.BOOLEAN,\n description: \"Close all folders when clicking on the home button\",\n restartNeeded: true,\n default: false\n },\n closeOthers: {\n type: OptionType.BOOLEAN,\n description: \"Close other folders when opening a folder\",\n default: false\n },\n forceOpen: {\n type: OptionType.BOOLEAN,\n description: \"Force a folder to open when switching to a server of that folder\",\n default: false\n },\n keepIcons: {\n type: OptionType.BOOLEAN,\n description: \"Keep showing guild icons in the primary guild bar folder when it's open in the BetterFolders sidebar\",\n restartNeeded: true,\n default: false\n },\n showFolderIcon: {\n type: OptionType.SELECT,\n description: \"Show the folder icon above the folder guilds in the BetterFolders sidebar\",\n options: [\n { label: \"Never\", value: FolderIconDisplay.Never },\n { label: \"Always\", value: FolderIconDisplay.Always, default: true },\n { label: \"When more than one folder is expanded\", value: FolderIconDisplay.MoreThanOneFolderExpanded }\n ],\n restartNeeded: true\n }\n});\n\nexport default definePlugin({\n name: \"BetterFolders\",\n description: \"Shows server folders on dedicated sidebar and adds folder related improvements\",\n authors: [Devs.juby, Devs.AutumnVN, Devs.Nuckyz],\n\n settings,\n\n patches: [\n {\n find: '(\"guildsnav\")',\n predicate: () => settings.store.sidebar,\n replacement: [\n // Create the isBetterFolders variable in the GuildsBar component\n {\n match: /(?<=let{disableAppDownload:\\i=\\i\\.isPlatformEmbedded,isOverlay:.+?)(?=}=\\i,)/,\n replace: \",isBetterFolders\"\n },\n // If we are rendering the Better Folders sidebar, we filter out guilds that are not in folders and unexpanded folders\n {\n match: /(useStateFromStoresArray\\).{0,25}let \\i)=(\\i\\.\\i.getGuildsTree\\(\\))/,\n replace: (_, rest, guildsTree) => `${rest}=$self.getGuildTree(!!arguments[0].isBetterFolders,${guildsTree},arguments[0].betterFoldersExpandedIds)`\n },\n // If we are rendering the Better Folders sidebar, we filter out everything but the servers and folders from the GuildsBar Guild List children\n {\n match: /lastTargetNode:\\i\\[\\i\\.length-1\\].+?Fragment.+?\\]}\\)\\]/,\n replace: \"$&.filter($self.makeGuildsBarGuildListFilter(!!arguments[0].isBetterFolders))\"\n },\n // If we are rendering the Better Folders sidebar, we filter out everything but the scroller for the guild list from the GuildsBar Tree children\n {\n match: /unreadMentionsIndicatorBottom,barClassName.+?}\\)\\]/,\n replace: \"$&.filter($self.makeGuildsBarTreeFilter(!!arguments[0].isBetterFolders))\"\n },\n // Export the isBetterFolders variable to the folders component\n {\n match: /(?<=\\.Messages\\.SERVERS.+?switch\\((\\i)\\.type\\){case \\i\\.\\i\\.FOLDER:.+?folderNode:\\i,)/,\n replace: 'isBetterFolders:typeof isBetterFolders!==\"undefined\"?isBetterFolders:false,'\n }\n ]\n },\n {\n // This is the parent folder component\n find: \".MAX_GUILD_FOLDER_NAME_LENGTH,\",\n predicate: () => settings.store.sidebar && settings.store.showFolderIcon !== FolderIconDisplay.Always,\n replacement: [\n {\n // Modify the expanded state to instead return the list of expanded folders\n match: /(useStateFromStores\\).{0,20}=>)(\\i\\.\\i)\\.isFolderExpanded\\(\\i\\)/,\n replace: (_, rest, ExpandedGuildFolderStore) => `${rest}${ExpandedGuildFolderStore}.getExpandedFolders()`,\n },\n {\n // Modify the expanded prop to use the boolean if the above patch fails, or check if the folder is expanded from the list if it succeeds\n // Also export the list of expanded folders to the child folder component if the patch above succeeds, else export undefined\n match: /(?<=folderNode:(\\i),expanded:)\\i(?=,)/,\n replace: (isExpandedOrExpandedIds, folderNote) => \"\"\n + `typeof ${isExpandedOrExpandedIds}===\"boolean\"?${isExpandedOrExpandedIds}:${isExpandedOrExpandedIds}.has(${folderNote}.id),`\n + `betterFoldersExpandedIds:${isExpandedOrExpandedIds} instanceof Set?${isExpandedOrExpandedIds}:void 0`\n }\n ]\n },\n {\n find: \".FOLDER_ITEM_GUILD_ICON_MARGIN);\",\n predicate: () => settings.store.sidebar,\n replacement: [\n // We use arguments[0] to access the isBetterFolders variable in this nested folder component (the parent exports all the props so we don't have to patch it)\n\n // If we are rendering the normal GuildsBar sidebar, we make Discord think the folder is always collapsed to show better icons (the mini guild icons) and avoid transitions\n {\n predicate: () => settings.store.keepIcons,\n match: /(?<=let{folderNode:\\i,setNodeRef:\\i,.+?expanded:(\\i),.+?;)(?=let)/,\n replace: (_, isExpanded) => `${isExpanded}=!!arguments[0].isBetterFolders&&${isExpanded};`\n },\n // Disable expanding and collapsing folders transition in the normal GuildsBar sidebar\n {\n predicate: () => !settings.store.keepIcons,\n match: /(?<=\\.Messages\\.SERVER_FOLDER_PLACEHOLDER.+?useTransition\\)\\()/,\n replace: \"!!arguments[0].isBetterFolders&&\"\n },\n // If we are rendering the normal GuildsBar sidebar, we avoid rendering guilds from folders that are expanded\n {\n predicate: () => !settings.store.keepIcons,\n match: /expandedFolderBackground,.+?,(?=\\i\\(\\(\\i,\\i,\\i\\)=>{let{key.{0,45}ul)(?<=selected:\\i,expanded:(\\i),.+?)/,\n replace: (m, isExpanded) => `${m}!arguments[0].isBetterFolders&&${isExpanded}?null:`\n },\n {\n // Decide if we should render the expanded folder background if we are rendering the Better Folders sidebar\n predicate: () => settings.store.showFolderIcon !== FolderIconDisplay.Always,\n match: /(?<=\\.wrapper,children:\\[)/,\n replace: \"$self.shouldShowFolderIconAndBackground(!!arguments[0].isBetterFolders,arguments[0].betterFoldersExpandedIds)&&\"\n },\n {\n // Decide if we should render the expanded folder icon if we are rendering the Better Folders sidebar\n predicate: () => settings.store.showFolderIcon !== FolderIconDisplay.Always,\n match: /(?<=\\.expandedFolderBackground.+?}\\),)(?=\\i,)/,\n replace: \"!$self.shouldShowFolderIconAndBackground(!!arguments[0].isBetterFolders,arguments[0].betterFoldersExpandedIds)?null:\"\n }\n ]\n },\n {\n find: \"APPLICATION_LIBRARY,render\",\n predicate: () => settings.store.sidebar,\n replacement: {\n // Render the Better Folders sidebar\n match: /(?<=({className:\\i\\.guilds,themeOverride:\\i})\\))/,\n replace: \",$self.FolderSideBar($1)\"\n }\n },\n {\n find: \".Messages.DISCODO_DISABLED\",\n predicate: () => settings.store.closeAllHomeButton,\n replacement: {\n // Close all folders when clicking the home button\n match: /(?<=onClick:\\(\\)=>{)(?=.{0,200}\"discodo\")/,\n replace: \"$self.closeFolders();\"\n }\n }\n ],\n\n flux: {\n CHANNEL_SELECT(data) {\n if (!settings.store.closeAllFolders && !settings.store.forceOpen)\n return;\n\n if (lastGuildId !== data.guildId) {\n lastGuildId = data.guildId;\n const guildFolder = getGuildFolder(data.guildId);\n\n if (guildFolder?.folderId) {\n if (settings.store.forceOpen && !ExpandedGuildFolderStore.isFolderExpanded(guildFolder.folderId)) {\n FolderUtils.toggleGuildFolderExpand(guildFolder.folderId);\n }\n } else if (settings.store.closeAllFolders) {\n closeFolders();\n }\n }\n },\n\n TOGGLE_GUILD_FOLDER_EXPAND(data) {\n if (settings.store.closeOthers && !dispatchingFoldersClose) {\n dispatchingFoldersClose = true;\n\n FluxDispatcher.wait(() => {\n const expandedFolders = ExpandedGuildFolderStore.getExpandedFolders();\n\n if (expandedFolders.size > 1) {\n for (const id of expandedFolders) if (id !== data.folderId)\n FolderUtils.toggleGuildFolderExpand(id);\n }\n\n dispatchingFoldersClose = false;\n });\n }\n }\n },\n\n getGuildTree(isBetterFolders: boolean, oldTree: any, expandedFolderIds?: Set<any>) {\n if (!isBetterFolders || expandedFolderIds == null) return oldTree;\n\n const newTree = new GuildsTree();\n // Children is every folder and guild which is not in a folder, this filters out only the expanded folders\n newTree.root.children = oldTree.root.children.filter(guildOrFolder => expandedFolderIds.has(guildOrFolder.id));\n // Nodes is every folder and guild, even if it's in a folder, this filters out only the expanded folders and guilds inside them\n newTree.nodes = Object.fromEntries(\n Object.entries(oldTree.nodes)\n .filter(([_, guildOrFolder]: any[]) => expandedFolderIds.has(guildOrFolder.id) || expandedFolderIds.has(guildOrFolder.parentId))\n );\n\n return newTree;\n },\n\n makeGuildsBarGuildListFilter(isBetterFolders: boolean) {\n return child => {\n if (isBetterFolders) {\n return child?.props?.[\"aria-label\"] === i18n.Messages.SERVERS;\n }\n return true;\n };\n },\n\n makeGuildsBarTreeFilter(isBetterFolders: boolean) {\n return child => {\n if (isBetterFolders) {\n return \"onScroll\" in child.props;\n }\n return true;\n };\n },\n\n shouldShowFolderIconAndBackground(isBetterFolders: boolean, expandedFolderIds?: Set<any>) {\n if (!isBetterFolders) return true;\n\n switch (settings.store.showFolderIcon) {\n case FolderIconDisplay.Never:\n return false;\n case FolderIconDisplay.Always:\n return true;\n case FolderIconDisplay.MoreThanOneFolderExpanded:\n return (expandedFolderIds?.size ?? 0) > 1;\n default:\n return true;\n }\n },\n\n FolderSideBar: guildsBarProps => <FolderSideBar {...guildsBarProps} />,\n\n closeFolders\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\n\nexport default definePlugin({\n name: \"BetterGifAltText\",\n authors: [Devs.Ven],\n description:\n \"Change GIF alt text from simply being 'GIF' to containing the gif tags / filename\",\n patches: [\n {\n find: \"onCloseImage=\",\n replacement: {\n match: /(return.{0,10}\\.jsx.{0,50}isWindowFocused)/,\n replace:\n \"$self.altify(e);$1\",\n },\n },\n {\n find: \".Messages.GIF,\",\n replacement: {\n match: /alt:(\\i)=(\\i\\.default\\.Messages\\.GIF)(?=,[^}]*\\}=(\\i))/,\n replace:\n // rename prop so we can always use default value\n \"alt_$$:$1=$self.altify($3)||$2\",\n },\n },\n ],\n\n altify(props: any) {\n props.alt ??= \"GIF\";\n if (props.alt !== \"GIF\") return props.alt;\n\n let url: string = props.original || props.src;\n try {\n url = decodeURI(url);\n } catch { }\n\n let name = url\n .slice(url.lastIndexOf(\"/\") + 1)\n .replace(/\\d/g, \"\") // strip numbers\n .replace(/.gif$/, \"\") // strip extension\n .split(/[,\\-_ ]+/g)\n .slice(0, 20)\n .join(\" \");\n if (name.length > 300) {\n name = name.slice(0, 300) + \"...\";\n }\n\n if (name) props.alt += ` - ${name}`;\n\n return props.alt;\n },\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Settings } from \"@api/Settings\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { findByPropsLazy } from \"@webpack\";\n\nconst UserPopoutSectionCssClasses = findByPropsLazy(\"section\", \"lastSection\");\n\nexport default definePlugin({\n name: \"BetterNotesBox\",\n description: \"Hide notes or disable spellcheck (Configure in settings!!)\",\n authors: [Devs.Ven],\n\n patches: [\n {\n find: \"hideNote:\",\n all: true,\n // Some modules match the find but the replacement is returned untouched\n noWarn: true,\n predicate: () => Vencord.Settings.plugins.BetterNotesBox.hide,\n replacement: {\n match: /hideNote:.+?(?=([,}].*?\\)))/g,\n replace: (m, rest) => {\n const destructuringMatch = rest.match(/}=.+/);\n if (destructuringMatch == null) return \"hideNote:!0\";\n return m;\n }\n }\n },\n {\n find: \"Messages.NOTE_PLACEHOLDER\",\n replacement: {\n match: /\\.NOTE_PLACEHOLDER,/,\n replace: \"$&spellCheck:!Vencord.Settings.plugins.BetterNotesBox.noSpellCheck,\"\n }\n },\n {\n find: \".Messages.NOTE}\",\n replacement: {\n match: /(?<=return \\i\\?)null(?=:\\(0,\\i\\.jsxs)/,\n replace: \"$self.patchPadding(arguments[0])\"\n }\n }\n ],\n\n options: {\n hide: {\n type: OptionType.BOOLEAN,\n description: \"Hide notes\",\n default: false,\n restartNeeded: true\n },\n noSpellCheck: {\n type: OptionType.BOOLEAN,\n description: \"Disable spellcheck in notes\",\n disabled: () => Settings.plugins.BetterNotesBox.hide,\n default: false\n }\n },\n\n patchPadding(e: any) {\n if (!e.lastSection) return;\n return (\n <div className={UserPopoutSectionCssClasses.lastSection}></div>\n );\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Settings } from \"@api/Settings\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { Clipboard, Toasts } from \"@webpack/common\";\n\nexport default definePlugin({\n name: \"BetterRoleDot\",\n authors: [Devs.Ven, Devs.AutumnVN],\n description:\n \"Copy role colour on RoleDot (accessibility setting) click. Also allows using both RoleDot and coloured names simultaneously\",\n\n patches: [\n {\n find: \".dotBorderBase\",\n replacement: {\n match: /,viewBox:\"0 0 20 20\"/,\n replace: \"$&,onClick:()=>$self.copyToClipBoard(arguments[0].color),style:{cursor:'pointer'}\",\n },\n },\n {\n find: '\"dot\"===',\n all: true,\n noWarn: true,\n predicate: () => Settings.plugins.BetterRoleDot.bothStyles,\n replacement: {\n match: /\"(?:username|dot)\"===\\i(?!\\.\\i)/g,\n replace: \"true\",\n },\n },\n\n {\n find: \".ADD_ROLE_A11Y_LABEL\",\n predicate: () => Settings.plugins.BetterRoleDot.copyRoleColorInProfilePopout && !Settings.plugins.BetterRoleDot.bothStyles,\n noWarn: true,\n replacement: {\n match: /\"dot\"===\\i/,\n replace: \"true\"\n }\n },\n {\n find: \".roleVerifiedIcon\",\n predicate: () => Settings.plugins.BetterRoleDot.copyRoleColorInProfilePopout && !Settings.plugins.BetterRoleDot.bothStyles,\n noWarn: true,\n replacement: {\n match: /\"dot\"===\\i/,\n replace: \"true\"\n }\n }\n ],\n\n options: {\n bothStyles: {\n type: OptionType.BOOLEAN,\n description: \"Show both role dot and coloured names\",\n restartNeeded: true,\n default: false,\n },\n copyRoleColorInProfilePopout: {\n type: OptionType.BOOLEAN,\n description: \"Allow click on role dot in profile popout to copy role color\",\n restartNeeded: true,\n default: false\n }\n },\n\n copyToClipBoard(color: string) {\n Clipboard.copy(color);\n Toasts.show({\n message: \"Copied to Clipboard!\",\n type: Toasts.Type.SUCCESS,\n id: Toasts.genId(),\n options: {\n duration: 1000,\n position: Toasts.Position.BOTTOM\n }\n });\n },\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\n\nexport default definePlugin({\n name: \"BetterUploadButton\",\n authors: [Devs.obscurity, Devs.Ven],\n description: \"Upload with a single click, open menu with right click\",\n patches: [\n {\n find: \"Messages.CHAT_ATTACH_UPLOAD_OR_INVITE\",\n replacement: {\n // Discord merges multiple props here with Object.assign()\n // This patch passes a third object to it with which we override onClick and onContextMenu\n match: /CHAT_ATTACH_UPLOAD_OR_INVITE,onDoubleClick:(.+?:void 0),\\.\\.\\.(\\i),/,\n replace: \"$&onClick:$1,onContextMenu:$2.onClick,\",\n },\n },\n ],\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { findStoreLazy } from \"@webpack\";\n\nimport * as t from \"./types/stores\";\n\nexport const ApplicationStreamPreviewStore: t.ApplicationStreamPreviewStore = findStoreLazy(\"ApplicationStreamPreviewStore\");\nexport const ApplicationStreamingStore: t.ApplicationStreamingStore = findStoreLazy(\"ApplicationStreamingStore\");\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { addContextMenuPatch, NavContextMenuPatchCallback, removeContextMenuPatch } from \"@api/ContextMenu\";\nimport { ScreenshareIcon } from \"@components/Icons\";\nimport { Devs } from \"@utils/constants\";\nimport { openImageModal } from \"@utils/discord\";\nimport definePlugin from \"@utils/types\";\nimport { Menu } from \"@webpack/common\";\nimport { Channel, User } from \"discord-types/general\";\n\nimport { ApplicationStreamingStore, ApplicationStreamPreviewStore } from \"./webpack/stores\";\nimport { ApplicationStream, Stream } from \"./webpack/types/stores\";\n\nexport interface UserContextProps {\n channel: Channel,\n channelSelected: boolean,\n className: string,\n config: { context: string; };\n context: string,\n onHeightUpdate: Function,\n position: string,\n target: HTMLElement,\n theme: string,\n user: User;\n}\n\nexport interface StreamContextProps {\n appContext: string,\n className: string,\n config: { context: string; };\n context: string,\n exitFullscreen: Function,\n onHeightUpdate: Function,\n position: string,\n target: HTMLElement,\n stream: Stream,\n theme: string,\n}\n\nexport const handleViewPreview = async ({ guildId, channelId, ownerId }: ApplicationStream | Stream) => {\n const previewUrl = await ApplicationStreamPreviewStore.getPreviewURL(guildId, channelId, ownerId);\n if (!previewUrl) return;\n\n openImageModal(previewUrl);\n};\n\nexport const addViewStreamContext: NavContextMenuPatchCallback = (children, { userId }: { userId: string | bigint; }) => () => {\n const stream = ApplicationStreamingStore.getAnyStreamForUser(userId);\n if (!stream) return;\n\n const streamPreviewItem = (\n <Menu.MenuItem\n label=\"View Stream Preview\"\n id=\"view-stream-preview\"\n icon={ScreenshareIcon}\n action={() => stream && handleViewPreview(stream)}\n disabled={!stream}\n />\n );\n\n children.push(<Menu.MenuSeparator />, streamPreviewItem);\n};\n\nexport const streamContextPatch: NavContextMenuPatchCallback = (children, { stream }: StreamContextProps) => {\n return addViewStreamContext(children, { userId: stream.ownerId });\n};\n\nexport const userContextPatch: NavContextMenuPatchCallback = (children, { user }: UserContextProps) => {\n if (user) return addViewStreamContext(children, { userId: user.id });\n};\n\nexport default definePlugin({\n name: \"BiggerStreamPreview\",\n description: \"This plugin allows you to enlarge stream previews\",\n authors: [Devs.phil],\n start: () => {\n addContextMenuPatch(\"user-context\", userContextPatch);\n addContextMenuPatch(\"stream-context\", streamContextPatch);\n },\n stop: () => {\n removeContextMenuPatch(\"user-context\", userContextPatch);\n removeContextMenuPatch(\"stream-context\", streamContextPatch);\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Settings } from \"@api/Settings\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin, { OptionType } from \"@utils/types\";\n\nlet style: HTMLStyleElement;\n\nfunction setCss() {\n style.textContent = `\n .vc-nsfw-img [class^=imageWrapper] img,\n .vc-nsfw-img [class^=wrapperPaused] video {\n filter: blur(${Settings.plugins.BlurNSFW.blurAmount}px);\n transition: filter 0.2s;\n }\n .vc-nsfw-img [class^=imageWrapper]:hover img,\n .vc-nsfw-img [class^=wrapperPaused]:hover video {\n filter: unset;\n }\n `;\n}\n\nexport default definePlugin({\n name: \"BlurNSFW\",\n description: \"Blur attachments in NSFW channels until hovered\",\n authors: [Devs.Ven],\n\n patches: [\n {\n find: \".embedWrapper,embed\",\n replacement: [{\n match: /\\.embedWrapper(?=.+?channel_id:(\\i)\\.id)/g,\n replace: \"$&+($1.nsfw?' vc-nsfw-img':'')\"\n }]\n }\n ],\n\n options: {\n blurAmount: {\n type: OptionType.NUMBER,\n description: \"Blur Amount\",\n default: 10,\n onChange: setCss\n }\n },\n\n start() {\n style = document.createElement(\"style\");\n style.id = \"VcBlurNsfw\";\n document.head.appendChild(style);\n\n setCss();\n },\n\n stop() {\n style?.remove();\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Settings } from \"@api/Settings\";\nimport ErrorBoundary from \"@components/ErrorBoundary\";\nimport { Devs } from \"@utils/constants\";\nimport { useTimer } from \"@utils/react\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { React } from \"@webpack/common\";\n\nfunction formatDuration(ms: number) {\n // here be dragons (moment fucking sucks)\n const human = Settings.plugins.CallTimer.format === \"human\";\n\n const format = (n: number) => human ? n : n.toString().padStart(2, \"0\");\n const unit = (s: string) => human ? s : \"\";\n const delim = human ? \" \" : \":\";\n\n // thx copilot\n const d = Math.floor(ms / 86400000);\n const h = Math.floor((ms % 86400000) / 3600000);\n const m = Math.floor(((ms % 86400000) % 3600000) / 60000);\n const s = Math.floor((((ms % 86400000) % 3600000) % 60000) / 1000);\n\n let res = \"\";\n if (d) res += `${d}d `;\n if (h || res) res += `${format(h)}${unit(\"h\")}${delim}`;\n if (m || res || !human) res += `${format(m)}${unit(\"m\")}${delim}`;\n res += `${format(s)}${unit(\"s\")}`;\n\n return res;\n}\n\nexport default definePlugin({\n name: \"CallTimer\",\n description: \"Adds a timer to vcs\",\n authors: [Devs.Ven],\n\n startTime: 0,\n interval: void 0 as NodeJS.Timeout | undefined,\n\n options: {\n format: {\n type: OptionType.SELECT,\n description: \"The timer format. This can be any valid moment.js format\",\n options: [\n {\n label: \"30d 23:00:42\",\n value: \"stopwatch\",\n default: true\n },\n {\n label: \"30d 23h 00m 42s\",\n value: \"human\"\n }\n ]\n }\n },\n\n patches: [{\n find: \"renderConnectionStatus(){\",\n replacement: {\n match: /(?<=renderConnectionStatus\\(\\)\\{.+\\.channel,children:)\\i/,\n replace: \"[$&, $self.renderTimer(this.props.channel.id)]\"\n }\n }],\n renderTimer(channelId: string) {\n return <ErrorBoundary noop>\n <this.Timer channelId={channelId} />\n </ErrorBoundary>;\n },\n\n Timer({ channelId }: { channelId: string; }) {\n const time = useTimer({\n deps: [channelId]\n });\n\n return <p style={{ margin: 0 }}>Connected for <span style={{ fontFamily: \"var(--font-code)\" }}>{formatDuration(time)}</span></p>;\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Logger } from \"@utils/Logger\";\nimport { MessageStore } from \"@webpack/common\";\nimport { CustomEmoji } from \"@webpack/types\";\nimport type { Channel, Message } from \"discord-types/general\";\nimport type { Promisable } from \"type-fest\";\n\nconst MessageEventsLogger = new Logger(\"MessageEvents\", \"#e5c890\");\n\nexport interface MessageObject {\n content: string,\n validNonShortcutEmojis: CustomEmoji[];\n invalidEmojis: any[];\n tts: boolean;\n}\n\nexport interface Upload {\n classification: string;\n currentSize: number;\n description: string | null;\n filename: string;\n id: string;\n isImage: boolean;\n isVideo: boolean;\n item: {\n file: File;\n platform: number;\n };\n loaded: number;\n mimeType: string;\n preCompressionSize: number;\n responseUrl: string;\n sensitive: boolean;\n showLargeMessageDialog: boolean;\n spoiler: boolean;\n status: \"NOT_STARTED\" | \"STARTED\" | \"UPLOADING\" | \"ERROR\" | \"COMPLETED\" | \"CANCELLED\";\n uniqueId: string;\n uploadedFilename: string;\n}\n\nexport interface MessageReplyOptions {\n messageReference: Message[\"messageReference\"];\n allowedMentions?: {\n parse: Array<string>;\n repliedUser: boolean;\n };\n}\n\nexport interface MessageExtra {\n stickers?: string[];\n uploads?: Upload[];\n replyOptions: MessageReplyOptions;\n content: string;\n channel: Channel;\n type?: any;\n openWarningPopout: (props: any) => any;\n}\n\nexport type SendListener = (channelId: string, messageObj: MessageObject, extra: MessageExtra) => Promisable<void | { cancel: boolean; }>;\nexport type EditListener = (channelId: string, messageId: string, messageObj: MessageObject) => Promisable<void>;\n\nconst sendListeners = new Set<SendListener>();\nconst editListeners = new Set<EditListener>();\n\nexport async function _handlePreSend(channelId: string, messageObj: MessageObject, extra: MessageExtra, replyOptions: MessageReplyOptions) {\n extra.replyOptions = replyOptions;\n for (const listener of sendListeners) {\n try {\n const result = await listener(channelId, messageObj, extra);\n if (result && result.cancel === true) {\n return true;\n }\n } catch (e) {\n MessageEventsLogger.error(\"MessageSendHandler: Listener encountered an unknown error\\n\", e);\n }\n }\n return false;\n}\n\nexport async function _handlePreEdit(channelId: string, messageId: string, messageObj: MessageObject) {\n for (const listener of editListeners) {\n try {\n await listener(channelId, messageId, messageObj);\n } catch (e) {\n MessageEventsLogger.error(\"MessageEditHandler: Listener encountered an unknown error\\n\", e);\n }\n }\n}\n\n/**\n * Note: This event fires off before a message is sent, allowing you to edit the message.\n */\nexport function addPreSendListener(listener: SendListener) {\n sendListeners.add(listener);\n return listener;\n}\n/**\n * Note: This event fires off before a message's edit is applied, allowing you to further edit the message.\n */\nexport function addPreEditListener(listener: EditListener) {\n editListeners.add(listener);\n return listener;\n}\nexport function removePreSendListener(listener: SendListener) {\n return sendListeners.delete(listener);\n}\nexport function removePreEditListener(listener: EditListener) {\n return editListeners.delete(listener);\n}\n\n\n// Message clicks\ntype ClickListener = (message: Message, channel: Channel, event: MouseEvent) => void;\n\nconst listeners = new Set<ClickListener>();\n\nexport function _handleClick(message: Message, channel: Channel, event: MouseEvent) {\n // message object may be outdated, so (try to) fetch latest one\n message = MessageStore.getMessage(channel.id, message.id) ?? message;\n for (const listener of listeners) {\n try {\n listener(message, channel, event);\n } catch (e) {\n MessageEventsLogger.error(\"MessageClickHandler: Listener encountered an unknown error\\n\", e);\n }\n }\n}\n\nexport function addClickListener(listener: ClickListener) {\n listeners.add(listener);\n return listener;\n}\n\nexport function removeClickListener(listener: ClickListener) {\n return listeners.delete(listener);\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nexport const defaultRules = [\n \"action_object_map\",\n \"action_type_map\",\n \"action_ref_map\",\n \"spm@*.aliexpress.com\",\n \"scm@*.aliexpress.com\",\n \"aff_platform\",\n \"aff_trace_key\",\n \"algo_expid@*.aliexpress.*\",\n \"algo_pvid@*.aliexpress.*\",\n \"btsid\",\n \"ws_ab_test\",\n \"pd_rd_*@amazon.*\",\n \"_encoding@amazon.*\",\n \"psc@amazon.*\",\n \"tag@amazon.*\",\n \"ref_@amazon.*\",\n \"pf_rd_*@amazon.*\",\n \"pf@amazon.*\",\n \"crid@amazon.*\",\n \"keywords@amazon.*\",\n \"sprefix@amazon.*\",\n \"sr@amazon.*\",\n \"ie@amazon.*\",\n \"node@amazon.*\",\n \"qid@amazon.*\",\n \"callback@bilibili.com\",\n \"cvid@bing.com\",\n \"form@bing.com\",\n \"sk@bing.com\",\n \"sp@bing.com\",\n \"sc@bing.com\",\n \"qs@bing.com\",\n \"pq@bing.com\",\n \"sc_cid\",\n \"mkt_tok\",\n \"trk\",\n \"trkCampaign\",\n \"ga_*\",\n \"gclid\",\n \"gclsrc\",\n \"hmb_campaign\",\n \"hmb_medium\",\n \"hmb_source\",\n \"spReportId\",\n \"spJobID\",\n \"spUserID\",\n \"spMailingID\",\n \"itm_*\",\n \"s_cid\",\n \"elqTrackId\",\n \"elqTrack\",\n \"assetType\",\n \"assetId\",\n \"recipientId\",\n \"campaignId\",\n \"siteId\",\n \"mc_cid\",\n \"mc_eid\",\n \"pk_*\",\n \"sc_campaign\",\n \"sc_channel\",\n \"sc_content\",\n \"sc_medium\",\n \"sc_outcome\",\n \"sc_geo\",\n \"sc_country\",\n \"nr_email_referer\",\n \"vero_conv\",\n \"vero_id\",\n \"yclid\",\n \"_openstat\",\n \"mbid\",\n \"cmpid\",\n \"cid\",\n \"c_id\",\n \"campaign_id\",\n \"Campaign\",\n \"hash@ebay.*\",\n \"fb_action_ids\",\n \"fb_action_types\",\n \"fb_ref\",\n \"fb_source\",\n \"fbclid\",\n \"refsrc@facebook.com\",\n \"hrc@facebook.com\",\n \"gs_l\",\n \"gs_lcp@google.*\",\n \"ved@google.*\",\n \"ei@google.*\",\n \"sei@google.*\",\n \"gws_rd@google.*\",\n \"gs_gbg@google.*\",\n \"gs_mss@google.*\",\n \"gs_rn@google.*\",\n \"_hsenc\",\n \"_hsmi\",\n \"__hssc\",\n \"__hstc\",\n \"hsCtaTracking\",\n \"source@sourceforge.net\",\n \"position@sourceforge.net\",\n \"t@*.twitter.com\",\n \"s@*.twitter.com\",\n \"ref_*@*.twitter.com\",\n \"t@*.x.com\",\n \"s@*.x.com\",\n \"ref_*@*.x.com\",\n \"t@*.fixupx.com\",\n \"s@*.fixupx.com\",\n \"ref_*@*.fixupx.com\",\n \"t@*.fxtwitter.com\",\n \"s@*.fxtwitter.com\",\n \"ref_*@*.fxtwitter.com\",\n \"t@*.twittpr.com\",\n \"s@*.twittpr.com\",\n \"ref_*@*.twittpr.com\",\n \"t@*.fixvx.com\",\n \"s@*.fixvx.com\",\n \"ref_*@*.fixvx.com\",\n \"tt_medium\",\n \"tt_content\",\n \"lr@yandex.*\",\n \"redircnt@yandex.*\",\n \"feature@youtube.com\",\n \"kw@youtube.com\",\n \"si@youtube.com\",\n \"pp@youtube.com\",\n \"si@youtu.be\",\n \"wt_zmc\",\n \"utm_source\",\n \"utm_content\",\n \"utm_medium\",\n \"utm_campaign\",\n \"utm_term\",\n \"si@open.spotify.com\",\n \"igshid\",\n \"share_id@reddit.com\",\n];\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport {\n addPreEditListener,\n addPreSendListener,\n MessageObject,\n removePreEditListener,\n removePreSendListener\n} from \"@api/MessageEvents\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\n\nimport { defaultRules } from \"./defaultRules\";\n\n// From lodash\nconst reRegExpChar = /[\\\\^$.*+?()[\\]{}|]/g;\nconst reHasRegExpChar = RegExp(reRegExpChar.source);\n\nexport default definePlugin({\n name: \"ClearURLs\",\n description: \"Removes tracking garbage from URLs\",\n authors: [Devs.adryd],\n dependencies: [\"MessageEventsAPI\"],\n\n escapeRegExp(str: string) {\n return (str && reHasRegExpChar.test(str))\n ? str.replace(reRegExpChar, \"\\\\$&\")\n : (str || \"\");\n },\n\n createRules() {\n // Can be extended upon once user configs are available\n // Eg. (useDefaultRules: boolean, customRules: Array[string])\n const rules = defaultRules;\n\n this.universalRules = new Set();\n this.rulesByHost = new Map();\n this.hostRules = new Map();\n\n for (const rule of rules) {\n const splitRule = rule.split(\"@\");\n const paramRule = new RegExp(\n \"^\" +\n this.escapeRegExp(splitRule[0]).replace(/\\\\\\*/, \".+?\") +\n \"$\"\n );\n\n if (!splitRule[1]) {\n this.universalRules.add(paramRule);\n continue;\n }\n const hostRule = new RegExp(\n \"^(www\\\\.)?\" +\n this.escapeRegExp(splitRule[1])\n .replace(/\\\\\\./, \"\\\\.\")\n .replace(/^\\\\\\*\\\\\\./, \"(.+?\\\\.)?\")\n .replace(/\\\\\\*/, \".+?\") +\n \"$\"\n );\n const hostRuleIndex = hostRule.toString();\n\n this.hostRules.set(hostRuleIndex, hostRule);\n if (this.rulesByHost.get(hostRuleIndex) == null) {\n this.rulesByHost.set(hostRuleIndex, new Set());\n }\n this.rulesByHost.get(hostRuleIndex).add(paramRule);\n }\n },\n\n removeParam(rule: string | RegExp, param: string, parent: URLSearchParams) {\n if (param === rule || rule instanceof RegExp && rule.test(param)) {\n parent.delete(param);\n }\n },\n\n replacer(match: string) {\n // Parse URL without throwing errors\n try {\n var url = new URL(match);\n } catch (error) {\n // Don't modify anything if we can't parse the URL\n return match;\n }\n\n // Cheap way to check if there are any search params\n if (url.searchParams.entries().next().done) {\n // If there are none, we don't need to modify anything\n return match;\n }\n\n // Check all universal rules\n this.universalRules.forEach(rule => {\n url.searchParams.forEach((_value, param, parent) => {\n this.removeParam(rule, param, parent);\n });\n });\n\n // Check rules for each hosts that match\n this.hostRules.forEach((regex, hostRuleName) => {\n if (!regex.test(url.hostname)) return;\n this.rulesByHost.get(hostRuleName).forEach(rule => {\n url.searchParams.forEach((_value, param, parent) => {\n this.removeParam(rule, param, parent);\n });\n });\n });\n\n return url.toString();\n },\n\n onSend(msg: MessageObject) {\n // Only run on messages that contain URLs\n if (msg.content.match(/http(s)?:\\/\\//)) {\n msg.content = msg.content.replace(\n /(https?:\\/\\/[^\\s<]+[^<.,:;\"'>)|\\]\\s])/g,\n match => this.replacer(match)\n );\n }\n },\n\n start() {\n this.createRules();\n this.preSend = addPreSendListener((_, msg) => this.onSend(msg));\n this.preEdit = addPreEditListener((_cid, _mid, msg) =>\n this.onSend(msg)\n );\n },\n\n stop() {\n removePreSendListener(this.preSend);\n removePreEditListener(this.preEdit);\n },\n});\n", "/*\n * Vencord, a Discord client mod\n * Copyright (c) 2023 Vendicated and contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport \"./clientTheme.css\";\n\nimport { definePluginSettings } from \"@api/Settings\";\nimport { Devs } from \"@utils/constants\";\nimport { getTheme, Theme } from \"@utils/discord\";\nimport { Margins } from \"@utils/margins\";\nimport { classes } from \"@utils/misc\";\nimport definePlugin, { OptionType, StartAt } from \"@utils/types\";\nimport { findComponentByCodeLazy } from \"@webpack\";\nimport { Button, Forms } from \"@webpack/common\";\n\nconst ColorPicker = findComponentByCodeLazy(\".Messages.USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR\", \".BACKGROUND_PRIMARY)\");\n\nconst colorPresets = [\n \"#1E1514\", \"#172019\", \"#13171B\", \"#1C1C28\", \"#402D2D\",\n \"#3A483D\", \"#344242\", \"#313D4B\", \"#2D2F47\", \"#322B42\",\n \"#3C2E42\", \"#422938\"\n];\n\nfunction onPickColor(color: number) {\n const hexColor = color.toString(16).padStart(6, \"0\");\n\n settings.store.color = hexColor;\n updateColorVars(hexColor);\n}\n\nfunction ThemeSettings() {\n const lightnessWarning = hexToLightness(settings.store.color) > 45;\n const lightModeWarning = getTheme() === Theme.Light;\n\n return (\n <div className=\"client-theme-settings\">\n <div className=\"client-theme-container\">\n <div className=\"client-theme-settings-labels\">\n <Forms.FormTitle tag=\"h3\">Theme Color</Forms.FormTitle>\n <Forms.FormText>Add a color to your Discord client theme</Forms.FormText>\n </div>\n <ColorPicker\n color={parseInt(settings.store.color, 16)}\n onChange={onPickColor}\n showEyeDropper={false}\n suggestedColors={colorPresets}\n />\n </div>\n {lightnessWarning || lightModeWarning\n ? <div>\n <Forms.FormDivider className={classes(Margins.top8, Margins.bottom8)} />\n <Forms.FormText className=\"client-theme-warning\">Your theme won't look good:</Forms.FormText>\n {lightnessWarning && <Forms.FormText className=\"client-theme-warning\">Selected color is very light</Forms.FormText>}\n {lightModeWarning && <Forms.FormText className=\"client-theme-warning\">Light mode isn't supported</Forms.FormText>}\n </div>\n : null\n }\n </div>\n );\n}\n\nconst settings = definePluginSettings({\n color: {\n description: \"Color your Discord client theme will be based around. Light mode isn't supported\",\n type: OptionType.COMPONENT,\n default: \"313338\",\n component: () => <ThemeSettings />\n },\n resetColor: {\n description: \"Reset Theme Color\",\n type: OptionType.COMPONENT,\n default: \"313338\",\n component: () => (\n <Button onClick={() => onPickColor(0x313338)}>\n Reset Theme Color\n </Button>\n )\n }\n});\n\nexport default definePlugin({\n name: \"ClientTheme\",\n authors: [Devs.F53, Devs.Nuckyz],\n description: \"Recreation of the old client theme experiment. Add a color to your Discord client theme\",\n settings,\n\n startAt: StartAt.DOMContentLoaded,\n start() {\n updateColorVars(settings.store.color);\n generateColorOffsets();\n },\n\n stop() {\n document.getElementById(\"clientThemeVars\")?.remove();\n document.getElementById(\"clientThemeOffsets\")?.remove();\n }\n});\n\nconst variableRegex = /(--primary-[5-9]\\d{2}-hsl):.*?(\\S*)%;/g;\n\nasync function generateColorOffsets() {\n\n const styleLinkNodes = document.querySelectorAll('link[rel=\"stylesheet\"]');\n const variableLightness = {} as Record<string, number>;\n\n // Search all stylesheets for color variables\n for (const styleLinkNode of styleLinkNodes) {\n const cssLink = styleLinkNode.getAttribute(\"href\");\n if (!cssLink) continue;\n\n const res = await fetch(cssLink);\n const cssString = await res.text();\n\n // Get lightness values of --primary variables >=500\n let variableMatch = variableRegex.exec(cssString);\n while (variableMatch !== null) {\n const [, variable, lightness] = variableMatch;\n variableLightness[variable] = parseFloat(lightness);\n variableMatch = variableRegex.exec(cssString);\n }\n }\n\n // Generate offsets\n const lightnessOffsets = Object.entries(variableLightness)\n .map(([key, lightness]) => {\n const lightnessOffset = lightness - variableLightness[\"--primary-600-hsl\"];\n const plusOrMinus = lightnessOffset >= 0 ? \"+\" : \"-\";\n return `${key}: var(--theme-h) var(--theme-s) calc(var(--theme-l) ${plusOrMinus} ${Math.abs(lightnessOffset).toFixed(2)}%);`;\n })\n .join(\"\\n\");\n\n const style = document.createElement(\"style\");\n style.setAttribute(\"id\", \"clientThemeOffsets\");\n style.textContent = `:root:root {\n ${lightnessOffsets}\n }`;\n document.head.appendChild(style);\n}\n\nfunction updateColorVars(color: string) {\n const { hue, saturation, lightness } = hexToHSL(color);\n\n let style = document.getElementById(\"clientThemeVars\");\n if (!style) {\n style = document.createElement(\"style\");\n style.setAttribute(\"id\", \"clientThemeVars\");\n document.head.appendChild(style);\n }\n\n style.textContent = `:root {\n --theme-h: ${hue};\n --theme-s: ${saturation}%;\n --theme-l: ${lightness}%;\n }`;\n}\n\n// https://css-tricks.com/converting-color-spaces-in-javascript/\nfunction hexToHSL(hexCode: string) {\n // Hex => RGB normalized to 0-1\n const r = parseInt(hexCode.substring(0, 2), 16) / 255;\n const g = parseInt(hexCode.substring(2, 4), 16) / 255;\n const b = parseInt(hexCode.substring(4, 6), 16) / 255;\n\n // RGB => HSL\n const cMax = Math.max(r, g, b);\n const cMin = Math.min(r, g, b);\n const delta = cMax - cMin;\n\n let hue: number, saturation: number, lightness: number;\n\n lightness = (cMax + cMin) / 2;\n\n if (delta === 0) {\n // If r=g=b then the only thing that matters is lightness\n hue = 0;\n saturation = 0;\n } else {\n // Magic\n saturation = delta / (1 - Math.abs(2 * lightness - 1));\n\n if (cMax === r)\n hue = ((g - b) / delta) % 6;\n else if (cMax === g)\n hue = (b - r) / delta + 2;\n else\n hue = (r - g) / delta + 4;\n hue *= 60;\n if (hue < 0)\n hue += 360;\n }\n\n // Move saturation and lightness from 0-1 to 0-100\n saturation *= 100;\n lightness *= 100;\n\n return { hue, saturation, lightness };\n}\n\n// Minimized math just for lightness, lowers lag when changing colors\nfunction hexToLightness(hexCode: string) {\n // Hex => RGB normalized to 0-1\n const r = parseInt(hexCode.substring(0, 2), 16) / 255;\n const g = parseInt(hexCode.substring(2, 4), 16) / 255;\n const b = parseInt(hexCode.substring(4, 6), 16) / 255;\n\n const cMax = Math.max(r, g, b);\n const cMin = Math.min(r, g, b);\n\n const lightness = 100 * ((cMax + cMin) / 2);\n\n return lightness;\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\n\nexport default definePlugin({\n name: \"ColorSighted\",\n description: \"Removes the colorblind-friendly icons from statuses, just like 2015-2017 Discord\",\n authors: [Devs.lewisakura],\n patches: [\n {\n find: \"Masks.STATUS_ONLINE\",\n replacement: {\n match: /Masks\\.STATUS_(?:IDLE|DND|STREAMING|OFFLINE)/g,\n replace: \"Masks.STATUS_ONLINE\"\n }\n },\n {\n find: \".AVATAR_STATUS_MOBILE_16;\",\n replacement: {\n match: /(?<=fromIsMobile:\\i=!0,.+?)status:(\\i)/,\n // Rename field to force it to always use \"online\"\n replace: 'status_$:$1=\"online\"'\n }\n }\n ]\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Devs } from \"@utils/constants\";\nimport { relaunch } from \"@utils/native\";\nimport { canonicalizeMatch, canonicalizeReplace, canonicalizeReplacement } from \"@utils/patches\";\nimport definePlugin from \"@utils/types\";\nimport * as Webpack from \"@webpack\";\nimport { extract, filters, findAll, search } from \"@webpack\";\nimport { React, ReactDOM } from \"@webpack/common\";\nimport type { ComponentType } from \"react\";\n\nconst WEB_ONLY = (f: string) => () => {\n throw new Error(`'${f}' is Discord Desktop only.`);\n};\n\nexport default definePlugin({\n name: \"ConsoleShortcuts\",\n description: \"Adds shorter Aliases for many things on the window. Run `shortcutList` for a list.\",\n authors: [Devs.Ven],\n\n getShortcuts() {\n function newFindWrapper(filterFactory: (...props: any[]) => Webpack.FilterFn) {\n const cache = new Map<string, unknown>();\n\n return function (...filterProps: unknown[]) {\n const cacheKey = String(filterProps);\n if (cache.has(cacheKey)) return cache.get(cacheKey);\n\n const matches = findAll(filterFactory(...filterProps));\n\n const result = (() => {\n switch (matches.length) {\n case 0: return null;\n case 1: return matches[0];\n default:\n const uniqueMatches = [...new Set(matches)];\n if (uniqueMatches.length > 1)\n console.warn(`Warning: This filter matches ${matches.length} modules. Make it more specific!\\n`, uniqueMatches);\n\n return matches[0];\n }\n })();\n if (result && cacheKey) cache.set(cacheKey, result);\n return result;\n };\n }\n\n let fakeRenderWin: WeakRef<Window> | undefined;\n const find = newFindWrapper(f => f);\n const findByProps = newFindWrapper(filters.byProps);\n return {\n ...Vencord.Webpack.Common,\n wp: Vencord.Webpack,\n wpc: Webpack.wreq.c,\n wreq: Webpack.wreq,\n wpsearch: search,\n wpex: extract,\n wpexs: (code: string) => extract(Webpack.findModuleId(code)!),\n find,\n findAll,\n findByProps,\n findAllByProps: (...props: string[]) => findAll(filters.byProps(...props)),\n findByCode: newFindWrapper(filters.byCode),\n findAllByCode: (code: string) => findAll(filters.byCode(code)),\n findComponentByCode: newFindWrapper(filters.componentByCode),\n findAllComponentsByCode: (...code: string[]) => findAll(filters.componentByCode(...code)),\n findExportedComponent: (...props: string[]) => findByProps(...props)[props[0]],\n findStore: newFindWrapper(filters.byStoreName),\n PluginsApi: Vencord.Plugins,\n plugins: Vencord.Plugins.plugins,\n Settings: Vencord.Settings,\n Api: Vencord.Api,\n reload: () => location.reload(),\n restart: IS_WEB ? WEB_ONLY(\"restart\") : relaunch,\n canonicalizeMatch,\n canonicalizeReplace,\n canonicalizeReplacement,\n fakeRender: (component: ComponentType, props: any) => {\n const prevWin = fakeRenderWin?.deref();\n const win = prevWin?.closed === false ? prevWin : window.open(\"about:blank\", \"Fake Render\", \"popup,width=500,height=500\")!;\n fakeRenderWin = new WeakRef(win);\n win.focus();\n\n const doc = win.document;\n doc.body.style.margin = \"1em\";\n\n if (!win.prepared) {\n win.prepared = true;\n\n [...document.querySelectorAll(\"style\"), ...document.querySelectorAll(\"link[rel=stylesheet]\")].forEach(s => {\n const n = s.cloneNode(true) as HTMLStyleElement | HTMLLinkElement;\n\n if (s.parentElement?.tagName === \"HEAD\")\n doc.head.append(n);\n else if (n.id?.startsWith(\"vencord-\") || n.id?.startsWith(\"vcd-\"))\n doc.documentElement.append(n);\n else\n doc.body.append(n);\n });\n }\n\n ReactDOM.render(React.createElement(component, props), doc.body.appendChild(document.createElement(\"div\")));\n }\n };\n },\n\n start() {\n const shortcuts = this.getShortcuts();\n window.shortcutList = shortcuts;\n for (const [key, val] of Object.entries(shortcuts))\n window[key] = val;\n },\n\n stop() {\n delete window.shortcutList;\n for (const key in this.getShortcuts())\n delete window[key];\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { addContextMenuPatch, NavContextMenuPatchCallback, removeContextMenuPatch } from \"@api/ContextMenu\";\nimport { LinkIcon } from \"@components/Icons\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\nimport { Clipboard, Menu } from \"@webpack/common\";\nimport type { Channel, User } from \"discord-types/general\";\n\ninterface UserContextProps {\n channel: Channel;\n guildId?: string;\n user: User;\n}\n\nconst UserContextMenuPatch: NavContextMenuPatchCallback = (children, { user }: UserContextProps) => () => {\n if (!user) return;\n\n children.push(\n <Menu.MenuItem\n id=\"vc-copy-user-url\"\n label=\"Copy User URL\"\n action={() => Clipboard.copy(`<https://discord.com/users/${user.id}>`)}\n icon={LinkIcon}\n />\n );\n};\n\nexport default definePlugin({\n name: \"CopyUserURLs\",\n authors: [Devs.castdrian],\n description: \"Adds a 'Copy User URL' option to the user context menu.\",\n\n start() {\n addContextMenuPatch(\"user-context\", UserContextMenuPatch);\n },\n\n stop() {\n removeContextMenuPatch(\"user-context\", UserContextMenuPatch);\n },\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { showNotification } from \"@api/Notifications\";\nimport { definePluginSettings } from \"@api/Settings\";\nimport { Devs } from \"@utils/constants\";\nimport { Logger } from \"@utils/Logger\";\nimport { closeAllModals } from \"@utils/modal\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { maybePromptToUpdate } from \"@utils/updater\";\nimport { filters, findBulk, proxyLazyWebpack } from \"@webpack\";\nimport { FluxDispatcher, NavigationRouter, SelectedChannelStore } from \"@webpack/common\";\nimport type { ReactElement } from \"react\";\n\nconst CrashHandlerLogger = new Logger(\"CrashHandler\");\nconst { ModalStack, DraftManager, DraftType, closeExpressionPicker } = proxyLazyWebpack(() => {\n const modules = findBulk(\n filters.byProps(\"pushLazy\", \"popAll\"),\n filters.byProps(\"clearDraft\", \"saveDraft\"),\n filters.byProps(\"DraftType\"),\n filters.byProps(\"closeExpressionPicker\", \"openExpressionPicker\"),\n );\n\n return {\n ModalStack: modules[0],\n DraftManager: modules[1],\n DraftType: modules[2]?.DraftType,\n closeExpressionPicker: modules[3]?.closeExpressionPicker,\n };\n});\n\nconst settings = definePluginSettings({\n attemptToPreventCrashes: {\n type: OptionType.BOOLEAN,\n description: \"Whether to attempt to prevent Discord crashes.\",\n default: true\n },\n attemptToNavigateToHome: {\n type: OptionType.BOOLEAN,\n description: \"Whether to attempt to navigate to the home when preventing Discord crashes.\",\n default: false\n }\n});\n\nlet crashCount: number = 0;\nlet lastCrashTimestamp: number = 0;\nlet shouldAttemptNextHandle = false;\n\nexport default definePlugin({\n name: \"CrashHandler\",\n description: \"Utility plugin for handling and possibly recovering from Crashes without a restart\",\n authors: [Devs.Nuckyz],\n enabledByDefault: true,\n\n settings,\n\n patches: [\n {\n find: \".Messages.ERRORS_UNEXPECTED_CRASH\",\n replacement: {\n match: /(?=this\\.setState\\()/,\n replace: \"$self.handleCrash(this)||\"\n }\n }\n ],\n\n handleCrash(_this: ReactElement & { forceUpdate: () => void; }) {\n if (Date.now() - lastCrashTimestamp <= 1_000 && !shouldAttemptNextHandle) return true;\n\n shouldAttemptNextHandle = false;\n\n if (++crashCount > 5) {\n try {\n showNotification({\n color: \"#eed202\",\n title: \"Discord has crashed!\",\n body: \"Awn :( Discord has crashed more than five times, not attempting to recover.\",\n noPersist: true,\n });\n } catch { }\n\n lastCrashTimestamp = Date.now();\n return false;\n }\n\n setTimeout(() => crashCount--, 60_000);\n\n try {\n if (crashCount === 1) maybePromptToUpdate(\"Uh oh, Discord has just crashed... but good news, there is a Vencord update available that might fix this issue! Would you like to update now?\", true);\n\n if (settings.store.attemptToPreventCrashes) {\n this.handlePreventCrash(_this);\n return true;\n }\n\n return false;\n } catch (err) {\n CrashHandlerLogger.error(\"Failed to handle crash\", err);\n return false;\n } finally {\n lastCrashTimestamp = Date.now();\n }\n },\n\n handlePreventCrash(_this: ReactElement & { forceUpdate: () => void; }) {\n if (Date.now() - lastCrashTimestamp >= 1_000) {\n try {\n showNotification({\n color: \"#eed202\",\n title: \"Discord has crashed!\",\n body: \"Attempting to recover...\",\n noPersist: true,\n });\n } catch { }\n }\n\n try {\n const channelId = SelectedChannelStore.getChannelId();\n\n DraftManager.clearDraft(channelId, DraftType.ChannelMessage);\n DraftManager.clearDraft(channelId, DraftType.FirstThreadMessage);\n } catch (err) {\n CrashHandlerLogger.debug(\"Failed to clear drafts.\", err);\n }\n try {\n closeExpressionPicker();\n }\n catch (err) {\n CrashHandlerLogger.debug(\"Failed to close expression picker.\", err);\n }\n try {\n FluxDispatcher.dispatch({ type: \"CONTEXT_MENU_CLOSE\" });\n } catch (err) {\n CrashHandlerLogger.debug(\"Failed to close open context menu.\", err);\n }\n try {\n ModalStack.popAll();\n } catch (err) {\n CrashHandlerLogger.debug(\"Failed to close old modals.\", err);\n }\n try {\n closeAllModals();\n } catch (err) {\n CrashHandlerLogger.debug(\"Failed to close all open modals.\", err);\n }\n try {\n FluxDispatcher.dispatch({ type: \"USER_PROFILE_MODAL_CLOSE\" });\n } catch (err) {\n CrashHandlerLogger.debug(\"Failed to close user popout.\", err);\n }\n try {\n FluxDispatcher.dispatch({ type: \"LAYER_POP_ALL\" });\n } catch (err) {\n CrashHandlerLogger.debug(\"Failed to pop all layers.\", err);\n }\n if (settings.store.attemptToNavigateToHome) {\n try {\n NavigationRouter.transitionTo(\"/channels/@me\");\n } catch (err) {\n CrashHandlerLogger.debug(\"Failed to navigate to home\", err);\n }\n }\n\n try {\n shouldAttemptNextHandle = true;\n _this.forceUpdate();\n } catch (err) {\n CrashHandlerLogger.debug(\"Failed to update crash handler component.\", err);\n }\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nexport function isTruthy<T>(item: T): item is Exclude<T, 0 | \"\" | false | null | undefined> {\n return Boolean(item);\n}\n\nexport function isNonNullish<T>(item: T): item is Exclude<T, null | undefined> {\n return item != null;\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { definePluginSettings, Settings } from \"@api/Settings\";\nimport { Link } from \"@components/Link\";\nimport { Devs } from \"@utils/constants\";\nimport { isTruthy } from \"@utils/guards\";\nimport { useAwaiter } from \"@utils/react\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { findByPropsLazy, findComponentByCodeLazy } from \"@webpack\";\nimport { ApplicationAssetUtils, FluxDispatcher, Forms, GuildStore, React, SelectedChannelStore, SelectedGuildStore, UserStore } from \"@webpack/common\";\n\nconst ActivityComponent = findComponentByCodeLazy(\"onOpenGameProfile\");\nconst ActivityClassName = findByPropsLazy(\"activity\", \"buttonColor\");\nconst Colors = findByPropsLazy(\"profileColors\");\n\nasync function getApplicationAsset(key: string): Promise<string> {\n if (/https?:\\/\\/(cdn|media)\\.discordapp\\.(com|net)\\/attachments\\//.test(key)) return \"mp:\" + key.replace(/https?:\\/\\/(cdn|media)\\.discordapp\\.(com|net)\\//, \"\");\n return (await ApplicationAssetUtils.fetchAssetIds(settings.store.appID!, [key]))[0];\n}\n\ninterface ActivityAssets {\n large_image?: string;\n large_text?: string;\n small_image?: string;\n small_text?: string;\n}\n\ninterface Activity {\n state?: string;\n details?: string;\n timestamps?: {\n start?: number;\n end?: number;\n };\n assets?: ActivityAssets;\n buttons?: Array<string>;\n name: string;\n application_id: string;\n metadata?: {\n button_urls?: Array<string>;\n };\n type: ActivityType;\n url?: string;\n flags: number;\n}\n\nconst enum ActivityType {\n PLAYING = 0,\n STREAMING = 1,\n LISTENING = 2,\n WATCHING = 3,\n COMPETING = 5\n}\n\nconst enum TimestampMode {\n NONE,\n NOW,\n TIME,\n CUSTOM,\n}\n\nconst settings = definePluginSettings({\n appID: {\n type: OptionType.STRING,\n description: \"Application ID (required)\",\n onChange: onChange,\n isValid: (value: string) => {\n if (!value) return \"Application ID is required.\";\n if (value && !/^\\d+$/.test(value)) return \"Application ID must be a number.\";\n return true;\n }\n },\n appName: {\n type: OptionType.STRING,\n description: \"Application name (required)\",\n onChange: onChange,\n isValid: (value: string) => {\n if (!value) return \"Application name is required.\";\n if (value.length > 128) return \"Application name must be not longer than 128 characters.\";\n return true;\n }\n },\n details: {\n type: OptionType.STRING,\n description: \"Details (line 1)\",\n onChange: onChange,\n isValid: (value: string) => {\n if (value && value.length > 128) return \"Details (line 1) must be not longer than 128 characters.\";\n return true;\n }\n },\n state: {\n type: OptionType.STRING,\n description: \"State (line 2)\",\n onChange: onChange,\n isValid: (value: string) => {\n if (value && value.length > 128) return \"State (line 2) must be not longer than 128 characters.\";\n return true;\n }\n },\n type: {\n type: OptionType.SELECT,\n description: \"Activity type\",\n onChange: onChange,\n options: [\n {\n label: \"Playing\",\n value: ActivityType.PLAYING,\n default: true\n },\n {\n label: \"Streaming\",\n value: ActivityType.STREAMING\n },\n {\n label: \"Listening\",\n value: ActivityType.LISTENING\n },\n {\n label: \"Watching\",\n value: ActivityType.WATCHING\n },\n {\n label: \"Competing\",\n value: ActivityType.COMPETING\n }\n ]\n },\n streamLink: {\n type: OptionType.STRING,\n description: \"Twitch.tv or Youtube.com link (only for Streaming activity type)\",\n onChange: onChange,\n disabled: isStreamLinkDisabled,\n isValid: isStreamLinkValid\n },\n timestampMode: {\n type: OptionType.SELECT,\n description: \"Timestamp mode\",\n onChange: onChange,\n options: [\n {\n label: \"None\",\n value: TimestampMode.NONE,\n default: true\n },\n {\n label: \"Since discord open\",\n value: TimestampMode.NOW\n },\n {\n label: \"Same as your current time\",\n value: TimestampMode.TIME\n },\n {\n label: \"Custom\",\n value: TimestampMode.CUSTOM\n }\n ]\n },\n startTime: {\n type: OptionType.NUMBER,\n description: \"Start timestamp (only for custom timestamp mode)\",\n onChange: onChange,\n disabled: isTimestampDisabled,\n isValid: (value: number) => {\n if (value && value < 0) return \"Start timestamp must be greater than 0.\";\n return true;\n }\n },\n endTime: {\n type: OptionType.NUMBER,\n description: \"End timestamp (only for custom timestamp mode)\",\n onChange: onChange,\n disabled: isTimestampDisabled,\n isValid: (value: number) => {\n if (value && value < 0) return \"End timestamp must be greater than 0.\";\n return true;\n }\n },\n imageBig: {\n type: OptionType.STRING,\n description: \"Big image key/link\",\n onChange: onChange,\n isValid: isImageKeyValid\n },\n imageBigTooltip: {\n type: OptionType.STRING,\n description: \"Big image tooltip\",\n onChange: onChange,\n isValid: (value: string) => {\n if (value && value.length > 128) return \"Big image tooltip must be not longer than 128 characters.\";\n return true;\n }\n },\n imageSmall: {\n type: OptionType.STRING,\n description: \"Small image key/link\",\n onChange: onChange,\n isValid: isImageKeyValid\n },\n imageSmallTooltip: {\n type: OptionType.STRING,\n description: \"Small image tooltip\",\n onChange: onChange,\n isValid: (value: string) => {\n if (value && value.length > 128) return \"Small image tooltip must be not longer than 128 characters.\";\n return true;\n }\n },\n buttonOneText: {\n type: OptionType.STRING,\n description: \"Button 1 text\",\n onChange: onChange,\n isValid: (value: string) => {\n if (value && value.length > 31) return \"Button 1 text must be not longer than 31 characters.\";\n return true;\n }\n },\n buttonOneURL: {\n type: OptionType.STRING,\n description: \"Button 1 URL\",\n onChange: onChange\n },\n buttonTwoText: {\n type: OptionType.STRING,\n description: \"Button 2 text\",\n onChange: onChange,\n isValid: (value: string) => {\n if (value && value.length > 31) return \"Button 2 text must be not longer than 31 characters.\";\n return true;\n }\n },\n buttonTwoURL: {\n type: OptionType.STRING,\n description: \"Button 2 URL\",\n onChange: onChange\n }\n});\n\nfunction onChange() {\n setRpc(true);\n if (Settings.plugins.CustomRPC.enabled) setRpc();\n}\n\nfunction isStreamLinkDisabled() {\n return settings.store.type !== ActivityType.STREAMING;\n}\n\nfunction isStreamLinkValid(value: string) {\n if (!isStreamLinkDisabled() && !/https?:\\/\\/(www\\.)?(twitch\\.tv|youtube\\.com)\\/\\w+/.test(value)) return \"Streaming link must be a valid URL.\";\n return true;\n}\n\nfunction isTimestampDisabled() {\n return settings.store.timestampMode !== TimestampMode.CUSTOM;\n}\n\nfunction isImageKeyValid(value: string) {\n if (/https?:\\/\\/(?!i\\.)?imgur\\.com\\//.test(value)) return \"Imgur link must be a direct link to the image. (e.g. https://i.imgur.com/...)\";\n if (/https?:\\/\\/(?!media\\.)?tenor\\.com\\//.test(value)) return \"Tenor link must be a direct link to the image. (e.g. https://media.tenor.com/...)\";\n return true;\n}\n\nasync function createActivity(): Promise<Activity | undefined> {\n const {\n appID,\n appName,\n details,\n state,\n type,\n streamLink,\n startTime,\n endTime,\n imageBig,\n imageBigTooltip,\n imageSmall,\n imageSmallTooltip,\n buttonOneText,\n buttonOneURL,\n buttonTwoText,\n buttonTwoURL\n } = settings.store;\n\n if (!appName) return;\n\n const activity: Activity = {\n application_id: appID || \"0\",\n name: appName,\n state,\n details,\n type,\n flags: 1 << 0,\n };\n\n if (type === ActivityType.STREAMING) activity.url = streamLink;\n\n switch (settings.store.timestampMode) {\n case TimestampMode.NOW:\n activity.timestamps = {\n start: Math.floor(Date.now() / 1000)\n };\n break;\n case TimestampMode.TIME:\n activity.timestamps = {\n start: Math.floor(Date.now() / 1000) - (new Date().getHours() * 3600) - (new Date().getMinutes() * 60) - new Date().getSeconds()\n };\n break;\n case TimestampMode.CUSTOM:\n if (startTime || endTime) {\n activity.timestamps = {};\n if (startTime) activity.timestamps.start = startTime;\n if (endTime) activity.timestamps.end = endTime;\n }\n break;\n case TimestampMode.NONE:\n default:\n break;\n }\n\n if (buttonOneText) {\n activity.buttons = [\n buttonOneText,\n buttonTwoText\n ].filter(isTruthy);\n\n activity.metadata = {\n button_urls: [\n buttonOneURL,\n buttonTwoURL\n ].filter(isTruthy)\n };\n }\n\n if (imageBig) {\n activity.assets = {\n large_image: await getApplicationAsset(imageBig),\n large_text: imageBigTooltip || undefined\n };\n }\n\n if (imageSmall) {\n activity.assets = {\n ...activity.assets,\n small_image: await getApplicationAsset(imageSmall),\n small_text: imageSmallTooltip || undefined\n };\n }\n\n\n for (const k in activity) {\n if (k === \"type\") continue;\n const v = activity[k];\n if (!v || v.length === 0)\n delete activity[k];\n }\n\n return activity;\n}\n\nasync function setRpc(disable?: boolean) {\n const activity: Activity | undefined = await createActivity();\n\n FluxDispatcher.dispatch({\n type: \"LOCAL_ACTIVITY_UPDATE\",\n activity: !disable ? activity : null,\n socketId: \"CustomRPC\",\n });\n}\n\nexport default definePlugin({\n name: \"CustomRPC\",\n description: \"Allows you to set a custom rich presence.\",\n authors: [Devs.captain, Devs.AutumnVN],\n start: setRpc,\n stop: () => setRpc(true),\n settings,\n\n settingsAboutComponent: () => {\n const activity = useAwaiter(createActivity);\n return (\n <>\n <Forms.FormText>\n Go to <Link href=\"https://discord.com/developers/applications\">Discord Developer Portal</Link> to create an application and\n get the application ID.\n </Forms.FormText>\n <Forms.FormText>\n Upload images in the Rich Presence tab to get the image keys.\n </Forms.FormText>\n <Forms.FormText>\n If you want to use image link, download your image and reupload the image to <Link href=\"https://imgur.com\">Imgur</Link> and get the image link by right-clicking the image and select \"Copy image address\".\n </Forms.FormText>\n <Forms.FormDivider />\n <div style={{ width: \"284px\" }} className={Colors.profileColors}>\n {activity[0] && <ActivityComponent activity={activity[0]} className={ActivityClassName.activity} channelId={SelectedChannelStore.getChannelId()}\n guild={GuildStore.getGuild(SelectedGuildStore.getLastSelectedGuildId())}\n application={{ id: settings.store.appID }}\n user={UserStore.getCurrentUser()} />}\n </div>\n </>\n );\n }\n});\n", "/*\n * Vencord, a Discord client mod\n * Copyright (c) 2023 Vendicated and contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport \"./styles.css\";\n\nimport ErrorBoundary from \"@components/ErrorBoundary\";\nimport { Devs } from \"@utils/constants\";\nimport { Logger } from \"@utils/Logger\";\nimport definePlugin from \"@utils/types\";\nimport { Tooltip } from \"@webpack/common\";\nimport type { Component } from \"react\";\n\ninterface Props {\n embed: {\n rawTitle: string;\n provider?: {\n name: string;\n };\n thumbnail: {\n proxyURL: string;\n };\n video: {\n url: string;\n };\n\n dearrow: {\n enabled: boolean;\n oldTitle?: string;\n oldThumb?: string;\n };\n };\n}\n\nconst embedUrlRe = /https:\\/\\/www\\.youtube\\.com\\/embed\\/([a-zA-Z0-9_-]{11})/;\n\nasync function embedDidMount(this: Component<Props>) {\n try {\n const { embed } = this.props;\n if (!embed || embed.dearrow || embed.provider?.name !== \"YouTube\" || !embed.video?.url) return;\n\n const videoId = embedUrlRe.exec(embed.video.url)?.[1];\n if (!videoId) return;\n\n const res = await fetch(`https://sponsor.ajay.app/api/branding?videoID=${videoId}`);\n if (!res.ok) return;\n\n const { titles, thumbnails } = await res.json();\n\n const hasTitle = titles[0]?.votes >= 0;\n const hasThumb = thumbnails[0]?.votes >= 0 && !thumbnails[0].original;\n\n if (!hasTitle && !hasThumb) return;\n\n embed.dearrow = {\n enabled: true\n };\n\n if (hasTitle) {\n embed.dearrow.oldTitle = embed.rawTitle;\n embed.rawTitle = titles[0].title.replace(/ >(\\S)/g, \" $1\");\n }\n\n if (hasThumb) {\n embed.dearrow.oldThumb = embed.thumbnail.proxyURL;\n embed.thumbnail.proxyURL = `https://dearrow-thumb.ajay.app/api/v1/getThumbnail?videoID=${videoId}&time=${thumbnails[0].timestamp}`;\n }\n\n this.forceUpdate();\n } catch (err) {\n new Logger(\"Dearrow\").error(\"Failed to dearrow embed\", err);\n }\n}\n\nfunction DearrowButton({ component }: { component: Component<Props>; }) {\n const { embed } = component.props;\n if (!embed?.dearrow) return null;\n\n return (\n <Tooltip text={embed.dearrow.enabled ? \"This embed has been dearrowed, click to restore\" : \"Click to dearrow\"}>\n {({ onMouseEnter, onMouseLeave }) => (\n <button\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n className={\"vc-dearrow-toggle-\" + (embed.dearrow.enabled ? \"on\" : \"off\")}\n onClick={() => {\n const { enabled, oldThumb, oldTitle } = embed.dearrow;\n embed.dearrow.enabled = !enabled;\n if (oldTitle) {\n embed.dearrow.oldTitle = embed.rawTitle;\n embed.rawTitle = oldTitle;\n }\n if (oldThumb) {\n embed.dearrow.oldThumb = embed.thumbnail.proxyURL;\n embed.thumbnail.proxyURL = oldThumb;\n }\n\n component.forceUpdate();\n }}\n >\n {/* Dearrow Icon, taken from https://dearrow.ajay.app/logo.svg (and optimised) */}\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24px\"\n height=\"24px\"\n viewBox=\"0 0 36 36\"\n aria-label=\"Toggle Dearrow\"\n >\n <path\n fill=\"#1213BD\"\n d=\"M36 18.302c0 4.981-2.46 9.198-5.655 12.462s-7.323 5.152-12.199 5.152s-9.764-1.112-12.959-4.376S0 23.283 0 18.302s2.574-9.38 5.769-12.644S13.271 0 18.146 0s9.394 2.178 12.589 5.442C33.931 8.706 36 13.322 36 18.302z\"\n />\n <path\n fill=\"#88c9f9\"\n d=\"m 30.394282,18.410186 c 0,3.468849 -1.143025,6.865475 -3.416513,9.137917 -2.273489,2.272442 -5.670115,2.92874 -9.137918,2.92874 -3.467803,0 -6.373515,-1.147212 -8.6470033,-3.419654 -2.2734888,-2.272442 -3.5871299,-5.178154 -3.5871299,-8.647003 0,-3.46885 0.9420533,-6.746149 3.2144954,-9.0196379 2.2724418,-2.2734888 5.5507878,-3.9513905 9.0196378,-3.9513905 3.46885,0 6.492841,1.9322561 8.76633,4.204698 2.273489,2.2724424 3.788101,5.2974804 3.788101,8.7663304 z\"\n />\n <path\n fill=\"#0a62a5\"\n d=\"m 23.95823,17.818306 c 0,3.153748 -2.644888,5.808102 -5.798635,5.808102 -3.153748,0 -5.599825,-2.654354 -5.599825,-5.808102 0,-3.153747 2.446077,-5.721714 5.599825,-5.721714 3.153747,0 5.798635,2.567967 5.798635,5.721714 z\"\n />\n </svg>\n\n </button>\n )}\n </Tooltip>\n );\n}\n\nexport default definePlugin({\n name: \"Dearrow\",\n description: \"Makes YouTube embed titles and thumbnails less sensationalist, powered by Dearrow\",\n authors: [Devs.Ven],\n\n embedDidMount,\n renderButton(component: Component<Props>) {\n return (\n <ErrorBoundary noop>\n <DearrowButton component={component} />\n </ErrorBoundary>\n );\n },\n\n patches: [{\n find: \"this.renderInlineMediaEmbed\",\n replacement: [\n // patch componentDidMount to replace embed thumbnail and title\n {\n match: /render\\(\\)\\{.{0,30}let\\{embed:/,\n replace: \"componentDidMount=$self.embedDidMount;$&\"\n },\n\n // add dearrow button\n {\n match: /children:\\[(?=null!=\\i\\?\\i\\.renderSuppressButton)/,\n replace: \"children:[$self.renderButton(this),\"\n }\n ]\n }],\n});\n", "/*\n * Vencord, a Discord client mod\n * Copyright (c) 2023 Vendicated and contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nexport const BASE_URL = \"https://decor.fieryflames.dev\";\nexport const API_URL = BASE_URL + \"/api\";\nexport const AUTHORIZE_URL = API_URL + \"/authorize\";\nexport const CDN_URL = \"https://ugc.decor.fieryflames.dev\";\nexport const CLIENT_ID = \"1096966363416899624\";\nexport const SKU_ID = \"100101099111114\"; // decor in ascii numbers\nexport const RAW_SKU_ID = \"11497119\"; // raw in ascii numbers\nexport const GUILD_ID = \"1096357702931841148\";\nexport const INVITE_KEY = \"dXp2SdxDcP\";\nexport const DECORATION_FETCH_COOLDOWN = 1000 * 60 * 60 * 4; // 4 hours\n", "/*\n * Vencord, a Discord client mod\n * Copyright (c) 2023 Vendicated and contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport { DataStore } from \"@api/index\";\nimport { proxyLazy } from \"@utils/lazy\";\nimport { Logger } from \"@utils/Logger\";\nimport { openModal } from \"@utils/modal\";\nimport { OAuth2AuthorizeModal, showToast, Toasts, UserStore, zustandCreate, zustandPersist } from \"@webpack/common\";\nimport type { StateStorage } from \"zustand/middleware\";\n\nimport { AUTHORIZE_URL, CLIENT_ID } from \"../constants\";\n\ninterface AuthorizationState {\n token: string | null;\n tokens: Record<string, string>;\n init: () => void;\n authorize: () => Promise<void>;\n setToken: (token: string) => void;\n remove: (id: string) => void;\n isAuthorized: () => boolean;\n}\n\nconst indexedDBStorage: StateStorage = {\n async getItem(name: string): Promise<string | null> {\n return DataStore.get(name).then(v => v ?? null);\n },\n async setItem(name: string, value: string): Promise<void> {\n await DataStore.set(name, value);\n },\n async removeItem(name: string): Promise<void> {\n await DataStore.del(name);\n },\n};\n\n// TODO: Move switching accounts subscription inside the store?\nexport const useAuthorizationStore = proxyLazy(() => zustandCreate<AuthorizationState>(\n zustandPersist(\n (set, get) => ({\n token: null,\n tokens: {},\n init: () => { set({ token: get().tokens[UserStore.getCurrentUser().id] ?? null }); },\n setToken: (token: string) => set({ token, tokens: { ...get().tokens, [UserStore.getCurrentUser().id]: token } }),\n remove: (id: string) => {\n const { tokens, init } = get();\n const newTokens = { ...tokens };\n delete newTokens[id];\n set({ tokens: newTokens });\n\n init();\n },\n async authorize() {\n return new Promise((resolve, reject) => openModal(props =>\n <OAuth2AuthorizeModal\n {...props}\n scopes={[\"identify\"]}\n responseType=\"code\"\n redirectUri={AUTHORIZE_URL}\n permissions={0n}\n clientId={CLIENT_ID}\n cancelCompletesFlow={false}\n callback={async (response: any) => {\n try {\n const url = new URL(response.location);\n url.searchParams.append(\"client\", \"vencord\");\n\n const req = await fetch(url);\n\n if (req?.ok) {\n const token = await req.text();\n get().setToken(token);\n } else {\n throw new Error(\"Request not OK\");\n }\n resolve(void 0);\n } catch (e) {\n if (e instanceof Error) {\n showToast(`Failed to authorize: ${e.message}`, Toasts.Type.FAILURE);\n new Logger(\"Decor\").error(\"Failed to authorize\", e);\n reject(e);\n }\n }\n }}\n />, {\n onCloseCallback() {\n reject(new Error(\"Authorization cancelled\"));\n },\n }\n ));\n },\n isAuthorized: () => !!get().token,\n }),\n {\n name: \"decor-auth\",\n getStorage: () => indexedDBStorage,\n partialize: state => ({ tokens: state.tokens }),\n onRehydrateStorage: () => state => state?.init()\n }\n )\n));\n", "/*\n * Vencord, a Discord client mod\n * Copyright (c) 2023 Vendicated and contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport { API_URL } from \"./constants\";\nimport { useAuthorizationStore } from \"./stores/AuthorizationStore\";\n\nexport interface Preset {\n id: string;\n name: string;\n description: string | null;\n decorations: Decoration[];\n authorIds: string[];\n}\n\nexport interface Decoration {\n hash: string;\n animated: boolean;\n alt: string | null;\n authorId: string | null;\n reviewed: boolean | null;\n presetId: string | null;\n}\n\nexport interface NewDecoration {\n file: File;\n alt: string | null;\n}\n\nexport async function fetchApi(url: RequestInfo, options?: RequestInit) {\n const res = await fetch(url, {\n ...options,\n headers: {\n ...options?.headers,\n Authorization: `Bearer ${useAuthorizationStore.getState().token}`\n }\n });\n\n if (res.ok) return res;\n else throw new Error(await res.text());\n}\n\nexport const getUsersDecorations = async (ids?: string[]): Promise<Record<string, string | null>> => {\n if (ids?.length === 0) return {};\n\n const url = new URL(API_URL + \"/users\");\n if (ids && ids.length !== 0) url.searchParams.set(\"ids\", JSON.stringify(ids));\n\n return await fetch(url).then(c => c.json());\n};\n\nexport const getUserDecorations = async (id: string = \"@me\"): Promise<Decoration[]> =>\n fetchApi(API_URL + `/users/${id}/decorations`).then(c => c.json());\n\nexport const getUserDecoration = async (id: string = \"@me\"): Promise<Decoration | null> =>\n fetchApi(API_URL + `/users/${id}/decoration`).then(c => c.json());\n\nexport const setUserDecoration = async (decoration: Decoration | NewDecoration | null, id: string = \"@me\"): Promise<string | Decoration> => {\n const formData = new FormData();\n\n if (!decoration) {\n formData.append(\"hash\", \"null\");\n } else if (\"hash\" in decoration) {\n formData.append(\"hash\", decoration.hash);\n } else if (\"file\" in decoration) {\n formData.append(\"image\", decoration.file);\n formData.append(\"alt\", decoration.alt ?? \"null\");\n }\n\n return fetchApi(API_URL + `/users/${id}/decoration`, { method: \"PUT\", body: formData }).then(c =>\n decoration && \"file\" in decoration ? c.json() : c.text()\n );\n};\n\nexport const getDecoration = async (hash: string): Promise<Decoration> => fetch(API_URL + `/decorations/${hash}`).then(c => c.json());\n\nexport const deleteDecoration = async (hash: string): Promise<void> => {\n await fetchApi(API_URL + `/decorations/${hash}`, { method: \"DELETE\" });\n};\n\nexport const getPresets = async (): Promise<Preset[]> => fetch(API_URL + \"/decorations/presets\").then(c => c.json());\n", "/*\n * Vencord, a Discord client mod\n * Copyright (c) 2023 Vendicated and contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport { AvatarDecoration } from \"../../\";\nimport { Decoration } from \"../api\";\nimport { SKU_ID } from \"../constants\";\n\nexport function decorationToAsset(decoration: Decoration) {\n return `${decoration.animated ? \"a_\" : \"\"}${decoration.hash}`;\n}\n\nexport function decorationToAvatarDecoration(decoration: Decoration): AvatarDecoration {\n return { asset: decorationToAsset(decoration), skuId: SKU_ID };\n}\n", "/*\n * Vencord, a Discord client mod\n * Copyright (c) 2023 Vendicated and contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport { debounce } from \"@utils/debounce\";\nimport { proxyLazy } from \"@utils/lazy\";\nimport { useEffect, useState, zustandCreate } from \"@webpack/common\";\nimport { User } from \"discord-types/general\";\n\nimport { AvatarDecoration } from \"../../\";\nimport { getUsersDecorations } from \"../api\";\nimport { DECORATION_FETCH_COOLDOWN, SKU_ID } from \"../constants\";\n\ninterface UserDecorationData {\n asset: string | null;\n fetchedAt: Date;\n}\n\ninterface UsersDecorationsState {\n usersDecorations: Map<string, UserDecorationData>;\n fetchQueue: Set<string>;\n bulkFetch: () => Promise<void>;\n fetch: (userId: string, force?: boolean) => Promise<void>;\n fetchMany: (userIds: string[]) => Promise<void>;\n get: (userId: string) => UserDecorationData | undefined;\n getAsset: (userId: string) => string | null | undefined;\n has: (userId: string) => boolean;\n set: (userId: string, decoration: string | null) => void;\n}\n\nexport const useUsersDecorationsStore = proxyLazy(() => zustandCreate<UsersDecorationsState>((set, get) => ({\n usersDecorations: new Map<string, UserDecorationData>(),\n fetchQueue: new Set(),\n bulkFetch: debounce(async () => {\n const { fetchQueue, usersDecorations } = get();\n\n if (fetchQueue.size === 0) return;\n\n set({ fetchQueue: new Set() });\n\n const fetchIds = Array.from(fetchQueue);\n const fetchedUsersDecorations = await getUsersDecorations(fetchIds);\n\n const newUsersDecorations = new Map(usersDecorations);\n\n const now = new Date();\n for (const fetchId of fetchIds) {\n const newDecoration = fetchedUsersDecorations[fetchId] ?? null;\n newUsersDecorations.set(fetchId, { asset: newDecoration, fetchedAt: now });\n }\n\n set({ usersDecorations: newUsersDecorations });\n }),\n async fetch(userId: string, force: boolean = false) {\n const { usersDecorations, fetchQueue, bulkFetch } = get();\n\n const { fetchedAt } = usersDecorations.get(userId) ?? {};\n if (fetchedAt) {\n if (!force && Date.now() - fetchedAt.getTime() < DECORATION_FETCH_COOLDOWN) return;\n }\n\n set({ fetchQueue: new Set(fetchQueue).add(userId) });\n bulkFetch();\n },\n async fetchMany(userIds) {\n if (!userIds.length) return;\n const { usersDecorations, fetchQueue, bulkFetch } = get();\n\n const newFetchQueue = new Set(fetchQueue);\n\n const now = Date.now();\n for (const userId of userIds) {\n const { fetchedAt } = usersDecorations.get(userId) ?? {};\n if (fetchedAt) {\n if (now - fetchedAt.getTime() < DECORATION_FETCH_COOLDOWN) continue;\n }\n newFetchQueue.add(userId);\n }\n\n set({ fetchQueue: newFetchQueue });\n bulkFetch();\n },\n get(userId: string) { return get().usersDecorations.get(userId); },\n getAsset(userId: string) { return get().usersDecorations.get(userId)?.asset; },\n has(userId: string) { return get().usersDecorations.has(userId); },\n set(userId: string, decoration: string | null) {\n const { usersDecorations } = get();\n const newUsersDecorations = new Map(usersDecorations);\n\n newUsersDecorations.set(userId, { asset: decoration, fetchedAt: new Date() });\n set({ usersDecorations: newUsersDecorations });\n }\n})));\n\nexport function useUserDecorAvatarDecoration(user?: User): AvatarDecoration | null | undefined {\n const [decorAvatarDecoration, setDecorAvatarDecoration] = useState<string | null>(user ? useUsersDecorationsStore.getState().getAsset(user.id) ?? null : null);\n\n useEffect(() => {\n const destructor = useUsersDecorationsStore.subscribe(\n state => {\n if (!user) return;\n const newDecorAvatarDecoration = state.getAsset(user.id);\n if (!newDecorAvatarDecoration) return;\n if (decorAvatarDecoration !== newDecorAvatarDecoration) setDecorAvatarDecoration(newDecorAvatarDecoration);\n }\n );\n\n if (user) {\n const { fetch: fetchUserDecorAvatarDecoration } = useUsersDecorationsStore.getState();\n fetchUserDecorAvatarDecoration(user.id);\n }\n return destructor;\n }, []);\n\n return decorAvatarDecoration ? { asset: decorAvatarDecoration, skuId: SKU_ID } : null;\n}\n", "/*\n * Vencord, a Discord client mod\n * Copyright (c) 2023 Vendicated and contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport { proxyLazy } from \"@utils/lazy\";\nimport { UserStore, zustandCreate } from \"@webpack/common\";\n\nimport { Decoration, deleteDecoration, getUserDecoration, getUserDecorations, NewDecoration, setUserDecoration } from \"../api\";\nimport { decorationToAsset } from \"../utils/decoration\";\nimport { useUsersDecorationsStore } from \"./UsersDecorationsStore\";\n\ninterface UserDecorationsState {\n decorations: Decoration[];\n selectedDecoration: Decoration | null;\n fetch: () => Promise<void>;\n delete: (decoration: Decoration | string) => Promise<void>;\n create: (decoration: NewDecoration) => Promise<void>;\n select: (decoration: Decoration | null) => Promise<void>;\n clear: () => void;\n}\n\nexport const useCurrentUserDecorationsStore = proxyLazy(() => zustandCreate<UserDecorationsState>((set, get) => ({\n decorations: [],\n selectedDecoration: null,\n async fetch() {\n const decorations = await getUserDecorations();\n const selectedDecoration = await getUserDecoration();\n\n set({ decorations, selectedDecoration });\n },\n async create(newDecoration: NewDecoration) {\n const decoration = (await setUserDecoration(newDecoration)) as Decoration;\n set({ decorations: [...get().decorations, decoration] });\n },\n async delete(decoration: Decoration | string) {\n const hash = typeof decoration === \"object\" ? decoration.hash : decoration;\n await deleteDecoration(hash);\n\n const { selectedDecoration, decorations } = get();\n const newState = {\n decorations: decorations.filter(d => d.hash !== hash),\n selectedDecoration: selectedDecoration?.hash === hash ? null : selectedDecoration\n };\n\n set(newState);\n },\n async select(decoration: Decoration | null) {\n if (get().selectedDecoration === decoration) return;\n set({ selectedDecoration: decoration });\n setUserDecoration(decoration);\n useUsersDecorationsStore.getState().set(UserStore.getCurrentUser().id, decoration ? decorationToAsset(decoration) : null);\n },\n clear: () => set({ decorations: [], selectedDecoration: null })\n})));\n", "/*\n * Vencord, a Discord client mod\n * Copyright (c) 2023 Vendicated and contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport { classNameFactory } from \"@api/Styles\";\nimport { extractAndLoadChunksLazy, findByPropsLazy } from \"@webpack\";\n\nexport const cl = classNameFactory(\"vc-decor-\");\nexport const DecorationModalStyles = findByPropsLazy(\"modalFooterShopButton\");\n\nexport const requireAvatarDecorationModal = extractAndLoadChunksLazy([\"openAvatarDecorationModal:\"]);\nexport const requireCreateStickerModal = extractAndLoadChunksLazy([\"stickerInspected]:\"]);\n", "/*\n * Vencord, a Discord client mod\n * Copyright (c) 2023 Vendicated and contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport { findComponentByCode, LazyComponentWebpack } from \"@webpack\";\nimport { React } from \"@webpack/common\";\nimport type { ComponentType, HTMLProps, PropsWithChildren } from \"react\";\n\nimport { AvatarDecoration } from \"../..\";\n\ntype DecorationGridItemComponent = ComponentType<PropsWithChildren<HTMLProps<HTMLDivElement>> & {\n onSelect: () => void,\n isSelected: boolean,\n}>;\n\nexport let DecorationGridItem: DecorationGridItemComponent;\nexport const setDecorationGridItem = v => DecorationGridItem = v;\n\nexport const AvatarDecorationModalPreview = LazyComponentWebpack(() => {\n const component = findComponentByCode(\".shopPreviewBanner\");\n return React.memo(component);\n});\n\ntype DecorationGridDecorationComponent = React.ComponentType<HTMLProps<HTMLDivElement> & {\n avatarDecoration: AvatarDecoration;\n onSelect: () => void,\n isSelected: boolean,\n}>;\n\nexport let DecorationGridDecoration: DecorationGridDecorationComponent;\nexport const setDecorationGridDecoration = v => DecorationGridDecoration = v;\n", "/*\n * Vencord, a Discord client mod\n * Copyright (c) 2023 Vendicated and contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport { PlusIcon } from \"@components/Icons\";\nimport { i18n, Text } from \"@webpack/common\";\nimport { HTMLProps } from \"react\";\n\nimport { DecorationGridItem } from \".\";\n\ntype DecorationGridCreateProps = HTMLProps<HTMLDivElement> & {\n onSelect: () => void;\n};\n\nexport default function DecorationGridCreate(props: DecorationGridCreateProps) {\n return <DecorationGridItem\n {...props}\n isSelected={false}\n >\n <PlusIcon />\n <Text\n variant=\"text-xs/normal\"\n color=\"header-primary\"\n >\n {i18n.Messages.CREATE}\n </Text>\n </DecorationGridItem >;\n}\n", "/*\n * Vencord, a Discord client mod\n * Copyright (c) 2023 Vendicated and contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport { NoEntrySignIcon } from \"@components/Icons\";\nimport { i18n, Text } from \"@webpack/common\";\nimport { HTMLProps } from \"react\";\n\nimport { DecorationGridItem } from \".\";\n\ntype DecorationGridNoneProps = HTMLProps<HTMLDivElement> & {\n isSelected: boolean;\n onSelect: () => void;\n};\n\nexport default function DecorationGridNone(props: DecorationGridNoneProps) {\n return <DecorationGridItem\n {...props}\n >\n <NoEntrySignIcon />\n <Text\n variant=\"text-xs/normal\"\n color=\"header-primary\"\n >\n {i18n.Messages.NONE}\n </Text>\n </DecorationGridItem >;\n}\n", "/*\n * Vencord, a Discord client mod\n * Copyright (c) 2023 Vendicated and contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport { CopyIcon, DeleteIcon } from \"@components/Icons\";\nimport { Alerts, Clipboard, ContextMenuApi, Menu, UserStore } from \"webpack/common\";\n\nimport { Decoration } from \"../../lib/api\";\nimport { useCurrentUserDecorationsStore } from \"../../lib/stores/CurrentUserDecorationsStore\";\nimport { cl } from \"../\";\n\nexport default function DecorationContextMenu({ decoration }: { decoration: Decoration; }) {\n const { delete: deleteDecoration } = useCurrentUserDecorationsStore();\n\n return <Menu.Menu\n navId={cl(\"decoration-context-menu\")}\n onClose={ContextMenuApi.closeContextMenu}\n aria-label=\"Decoration Options\"\n >\n <Menu.MenuItem\n id={cl(\"decoration-context-menu-copy-hash\")}\n label=\"Copy Decoration Hash\"\n icon={CopyIcon}\n action={() => Clipboard.copy(decoration.hash)}\n />\n {decoration.authorId === UserStore.getCurrentUser().id &&\n <Menu.MenuItem\n id={cl(\"decoration-context-menu-delete\")}\n label=\"Delete Decoration\"\n color=\"danger\"\n icon={DeleteIcon}\n action={() => Alerts.show({\n title: \"Delete Decoration\",\n body: `Are you sure you want to delete ${decoration.alt}?`,\n confirmText: \"Delete\",\n confirmColor: cl(\"danger-btn\"),\n cancelText: \"Cancel\",\n onConfirm() {\n deleteDecoration(decoration);\n }\n })}\n />\n }\n </Menu.Menu>;\n}\n", "/*\n * Vencord, a Discord client mod\n * Copyright (c) 2023 Vendicated and contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport { ContextMenuApi } from \"@webpack/common\";\nimport type { HTMLProps } from \"react\";\n\nimport { Decoration } from \"../../lib/api\";\nimport { decorationToAvatarDecoration } from \"../../lib/utils/decoration\";\nimport { DecorationGridDecoration } from \".\";\nimport DecorationContextMenu from \"./DecorationContextMenu\";\n\ninterface DecorDecorationGridDecorationProps extends HTMLProps<HTMLDivElement> {\n decoration: Decoration;\n isSelected: boolean;\n onSelect: () => void;\n}\n\nexport default function DecorDecorationGridDecoration(props: DecorDecorationGridDecorationProps) {\n const { decoration } = props;\n\n return <DecorationGridDecoration\n {...props}\n onContextMenu={e => {\n ContextMenuApi.openContextMenu(e, () => (\n <DecorationContextMenu\n decoration={decoration}\n />\n ));\n }}\n avatarDecoration={decorationToAvatarDecoration(decoration)}\n />;\n}\n", "/*\n * Vencord, a Discord client mod\n * Copyright (c) 2023 Vendicated and contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport { React } from \"@webpack/common\";\n\nimport { cl } from \"../\";\n\nexport interface GridProps<ItemT> {\n renderItem: (item: ItemT) => JSX.Element;\n getItemKey: (item: ItemT) => string;\n itemKeyPrefix?: string;\n items: Array<ItemT>;\n}\n\nexport default function Grid<ItemT,>({ renderItem, getItemKey, itemKeyPrefix: ikp, items }: GridProps<ItemT>) {\n return <div className={cl(\"sectioned-grid-list-grid\")}>\n {items.map(item =>\n <React.Fragment\n key={`${ikp ? `${ikp}-` : \"\"}${getItemKey(item)}`}\n >\n {renderItem(item)}\n </React.Fragment>\n )}\n </div>;\n}\n", "/*\n * Vencord, a Discord client mod\n * Copyright (c) 2023 Vendicated and contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport { classes } from \"@utils/misc\";\nimport { findByPropsLazy } from \"@webpack\";\nimport { React } from \"@webpack/common\";\n\nimport { cl } from \"../\";\nimport Grid, { GridProps } from \"./Grid\";\n\nconst ScrollerClasses = findByPropsLazy(\"managedReactiveScroller\");\n\ntype Section<SectionT, ItemT> = SectionT & {\n items: Array<ItemT>;\n};\n\ninterface SectionedGridListProps<ItemT, SectionT, SectionU = Section<SectionT, ItemT>> extends Omit<GridProps<ItemT>, \"items\"> {\n renderSectionHeader: (section: SectionU) => JSX.Element;\n getSectionKey: (section: SectionU) => string;\n sections: SectionU[];\n}\n\nexport default function SectionedGridList<ItemT, SectionU,>(props: SectionedGridListProps<ItemT, SectionU>) {\n return <div className={classes(cl(\"sectioned-grid-list-container\"), ScrollerClasses.thin)}>\n {props.sections.map(section => <div key={props.getSectionKey(section)} className={cl(\"sectioned-grid-list-section\")}>\n {props.renderSectionHeader(section)}\n <Grid\n renderItem={props.renderItem}\n getItemKey={props.getItemKey}\n itemKeyPrefix={props.getSectionKey(section)}\n items={section.items}\n />\n </div>)}\n </div>;\n}\n", "/*\n * Vencord, a Discord client mod\n * Copyright (c) 2023 Vendicated and contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport ErrorBoundary from \"@components/ErrorBoundary\";\nimport { Link } from \"@components/Link\";\nimport { openInviteModal } from \"@utils/discord\";\nimport { Margins } from \"@utils/margins\";\nimport { closeAllModals, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from \"@utils/modal\";\nimport { findByPropsLazy, findComponentByCodeLazy } from \"@webpack\";\nimport { Button, FluxDispatcher, Forms, GuildStore, NavigationRouter, Text, TextInput, useEffect, useMemo, UserStore, useState } from \"@webpack/common\";\n\nimport { GUILD_ID, INVITE_KEY, RAW_SKU_ID } from \"../../lib/constants\";\nimport { useCurrentUserDecorationsStore } from \"../../lib/stores/CurrentUserDecorationsStore\";\nimport { cl, DecorationModalStyles, requireAvatarDecorationModal, requireCreateStickerModal } from \"../\";\nimport { AvatarDecorationModalPreview } from \"../components\";\n\nconst FileUpload = findComponentByCodeLazy(\"fileUploadInput,\");\n\nconst { default: HelpMessage, HelpMessageTypes } = findByPropsLazy(\"HelpMessageTypes\");\n\nfunction useObjectURL(object: Blob | MediaSource | null) {\n const [url, setUrl] = useState<string | null>(null);\n\n useEffect(() => {\n if (!object) return;\n\n const objectUrl = URL.createObjectURL(object);\n setUrl(objectUrl);\n\n return () => {\n URL.revokeObjectURL(objectUrl);\n setUrl(null);\n };\n }, [object]);\n\n return url;\n}\n\nfunction CreateDecorationModal(props: ModalProps) {\n const [name, setName] = useState(\"\");\n const [file, setFile] = useState<File | null>(null);\n const [submitting, setSubmitting] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n useEffect(() => {\n if (error) setError(null);\n }, [file]);\n\n const { create: createDecoration } = useCurrentUserDecorationsStore();\n\n const fileUrl = useObjectURL(file);\n\n const decoration = useMemo(() => fileUrl ? { asset: fileUrl, skuId: RAW_SKU_ID } : null, [fileUrl]);\n\n return <ModalRoot\n {...props}\n size={ModalSize.MEDIUM}\n className={DecorationModalStyles.modal}\n >\n <ModalHeader separator={false} className={cl(\"modal-header\")}>\n <Text\n color=\"header-primary\"\n variant=\"heading-lg/semibold\"\n tag=\"h1\"\n style={{ flexGrow: 1 }}\n >\n Create Decoration\n </Text>\n <ModalCloseButton onClick={props.onClose} />\n </ModalHeader>\n <ModalContent\n className={cl(\"create-decoration-modal-content\")}\n scrollbarType=\"none\"\n >\n <ErrorBoundary>\n <HelpMessage messageType={HelpMessageTypes.WARNING}>\n Make sure your decoration does not violate <Link\n href=\"https://github.com/decor-discord/.github/blob/main/GUIDELINES.md\"\n >\n the guidelines\n </Link> before submitting it.\n </HelpMessage>\n <div className={cl(\"create-decoration-modal-form-preview-container\")}>\n <div className={cl(\"create-decoration-modal-form\")}>\n {error !== null && <Text color=\"text-danger\" variant=\"text-xs/normal\">{error.message}</Text>}\n <Forms.FormSection title=\"File\">\n <FileUpload\n filename={file?.name}\n placeholder=\"Choose a file\"\n buttonText=\"Browse\"\n filters={[{ name: \"Decoration file\", extensions: [\"png\", \"apng\"] }]}\n onFileSelect={setFile}\n />\n <Forms.FormText type=\"description\" className={Margins.top8}>\n File should be APNG or PNG.\n </Forms.FormText>\n </Forms.FormSection>\n <Forms.FormSection title=\"Name\">\n <TextInput\n placeholder=\"Companion Cube\"\n value={name}\n onChange={setName}\n />\n <Forms.FormText type=\"description\" className={Margins.top8}>\n This name will be used when referring to this decoration.\n </Forms.FormText>\n </Forms.FormSection>\n </div>\n <div>\n <AvatarDecorationModalPreview\n avatarDecorationOverride={decoration}\n user={UserStore.getCurrentUser()}\n />\n </div>\n </div>\n <Forms.FormText type=\"description\" className={Margins.bottom16}>\n <br />You can receive updates on your decoration's review by joining <Link\n href={`https://discord.gg/${INVITE_KEY}`}\n onClick={async e => {\n e.preventDefault();\n if (!GuildStore.getGuild(GUILD_ID)) {\n const inviteAccepted = await openInviteModal(INVITE_KEY);\n if (inviteAccepted) {\n closeAllModals();\n FluxDispatcher.dispatch({ type: \"LAYER_POP_ALL\" });\n }\n } else {\n closeAllModals();\n FluxDispatcher.dispatch({ type: \"LAYER_POP_ALL\" });\n NavigationRouter.transitionToGuild(GUILD_ID);\n }\n }}\n >\n Decor's Discord server\n </Link>.\n </Forms.FormText>\n </ErrorBoundary>\n </ModalContent>\n <ModalFooter className={cl(\"modal-footer\")}>\n <Button\n onClick={() => {\n setSubmitting(true);\n createDecoration({ alt: name, file: file! })\n .then(props.onClose).catch(e => { setSubmitting(false); setError(e); });\n }}\n disabled={!file || !name}\n submitting={submitting}\n >\n Submit for Review\n </Button>\n <Button\n onClick={props.onClose}\n color={Button.Colors.PRIMARY}\n look={Button.Looks.LINK}\n >\n Cancel\n </Button>\n </ModalFooter>\n </ModalRoot>;\n}\n\nexport const openCreateDecorationModal = () =>\n Promise.all([requireAvatarDecorationModal(), requireCreateStickerModal()])\n .then(() => openModal(props => <CreateDecorationModal {...props} />));\n", "/*\n * Vencord, a Discord client mod\n * Copyright (c) 2023 Vendicated and contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport { Link } from \"@components/Link\";\nimport { ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from \"@utils/modal\";\nimport { Button, Forms, Text } from \"@webpack/common\";\n\nimport { settings } from \"../../settings\";\nimport { cl, DecorationModalStyles, requireAvatarDecorationModal } from \"../\";\nimport { openCreateDecorationModal } from \"./CreateDecorationModal\";\n\nfunction GuidelinesModal(props: ModalProps) {\n return <ModalRoot\n {...props}\n size={ModalSize.SMALL}\n className={DecorationModalStyles.modal}\n >\n <ModalHeader separator={false} className={cl(\"modal-header\")}>\n <Text\n color=\"header-primary\"\n variant=\"heading-lg/semibold\"\n tag=\"h1\"\n style={{ flexGrow: 1 }}\n >\n Hold on\n </Text>\n <ModalCloseButton onClick={props.onClose} />\n </ModalHeader>\n <ModalContent\n scrollbarType=\"none\"\n >\n <Forms.FormText>\n By submitting a decoration, you agree to <Link\n href=\"https://github.com/decor-discord/.github/blob/main/GUIDELINES.md\"\n >\n the guidelines\n </Link>. Not reading these guidelines may get your account suspended from creating more decorations in the future.\n </Forms.FormText>\n </ModalContent>\n <ModalFooter className={cl(\"modal-footer\")}>\n <Button\n onClick={() => {\n settings.store.agreedToGuidelines = true;\n props.onClose();\n openCreateDecorationModal();\n }}\n >\n Continue\n </Button>\n <Button\n onClick={props.onClose}\n color={Button.Colors.PRIMARY}\n look={Button.Looks.LINK}\n >\n Go Back\n </Button>\n </ModalFooter>\n </ModalRoot>;\n}\n\nexport const openGuidelinesModal = () =>\n requireAvatarDecorationModal().then(() => openModal(props => <GuidelinesModal {...props} />));\n", "/*\n * Vencord, a Discord client mod\n * Copyright (c) 2023 Vendicated and contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport ErrorBoundary from \"@components/ErrorBoundary\";\nimport { Flex } from \"@components/Flex\";\nimport { openInviteModal } from \"@utils/discord\";\nimport { Margins } from \"@utils/margins\";\nimport { classes } from \"@utils/misc\";\nimport { closeAllModals, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from \"@utils/modal\";\nimport { findComponentByCodeLazy } from \"@webpack\";\nimport { Alerts, Button, FluxDispatcher, Forms, GuildStore, NavigationRouter, Parser, Text, Tooltip, useEffect, UserStore, UserUtils, useState } from \"@webpack/common\";\nimport { User } from \"discord-types/general\";\n\nimport { Decoration, getPresets, Preset } from \"../../lib/api\";\nimport { GUILD_ID, INVITE_KEY } from \"../../lib/constants\";\nimport { useAuthorizationStore } from \"../../lib/stores/AuthorizationStore\";\nimport { useCurrentUserDecorationsStore } from \"../../lib/stores/CurrentUserDecorationsStore\";\nimport { decorationToAvatarDecoration } from \"../../lib/utils/decoration\";\nimport { settings } from \"../../settings\";\nimport { cl, DecorationModalStyles, requireAvatarDecorationModal } from \"../\";\nimport { AvatarDecorationModalPreview } from \"../components\";\nimport DecorationGridCreate from \"../components/DecorationGridCreate\";\nimport DecorationGridNone from \"../components/DecorationGridNone\";\nimport DecorDecorationGridDecoration from \"../components/DecorDecorationGridDecoration\";\nimport SectionedGridList from \"../components/SectionedGridList\";\nimport { openCreateDecorationModal } from \"./CreateDecorationModal\";\nimport { openGuidelinesModal } from \"./GuidelinesModal\";\n\nconst UserSummaryItem = findComponentByCodeLazy(\"defaultRenderUser\", \"showDefaultAvatarsForNullUsers\");\n\nfunction usePresets() {\n const [presets, setPresets] = useState<Preset[]>([]);\n useEffect(() => { getPresets().then(setPresets); }, []);\n return presets;\n}\n\ninterface Section {\n title: string;\n subtitle?: string;\n sectionKey: string;\n items: (\"none\" | \"create\" | Decoration)[];\n authorIds?: string[];\n}\n\nfunction SectionHeader({ section }: { section: Section; }) {\n const hasSubtitle = typeof section.subtitle !== \"undefined\";\n const hasAuthorIds = typeof section.authorIds !== \"undefined\";\n\n const [authors, setAuthors] = useState<User[]>([]);\n\n useEffect(() => {\n (async () => {\n if (!section.authorIds) return;\n\n for (const authorId of section.authorIds) {\n const author = UserStore.getUser(authorId) ?? await UserUtils.getUser(authorId);\n setAuthors(authors => [...authors, author]);\n }\n })();\n }, [section.authorIds]);\n\n return <div>\n <Flex>\n <Forms.FormTitle style={{ flexGrow: 1 }}>{section.title}</Forms.FormTitle>\n {hasAuthorIds && <UserSummaryItem\n users={authors}\n guildId={undefined}\n renderIcon={false}\n max={5}\n showDefaultAvatarsForNullUsers\n size={16}\n showUserPopout\n className={Margins.bottom8}\n />\n }\n </Flex>\n {hasSubtitle &&\n <Forms.FormText type=\"description\" className={Margins.bottom8}>\n {section.subtitle}\n </Forms.FormText>\n }\n </div>;\n}\n\nfunction ChangeDecorationModal(props: ModalProps) {\n // undefined = not trying, null = none, Decoration = selected\n const [tryingDecoration, setTryingDecoration] = useState<Decoration | null | undefined>(undefined);\n const isTryingDecoration = typeof tryingDecoration !== \"undefined\";\n\n const avatarDecorationOverride = tryingDecoration != null ? decorationToAvatarDecoration(tryingDecoration) : tryingDecoration;\n\n const {\n decorations,\n selectedDecoration,\n fetch: fetchUserDecorations,\n select: selectDecoration\n } = useCurrentUserDecorationsStore();\n\n useEffect(() => {\n fetchUserDecorations();\n }, []);\n\n const activeSelectedDecoration = isTryingDecoration ? tryingDecoration : selectedDecoration;\n const activeDecorationHasAuthor = typeof activeSelectedDecoration?.authorId !== \"undefined\";\n const hasDecorationPendingReview = decorations.some(d => d.reviewed === false);\n\n const presets = usePresets();\n const presetDecorations = presets.flatMap(preset => preset.decorations);\n\n const activeDecorationPreset = presets.find(preset => preset.id === activeSelectedDecoration?.presetId);\n const isActiveDecorationPreset = typeof activeDecorationPreset !== \"undefined\";\n\n const ownDecorations = decorations.filter(d => !presetDecorations.some(p => p.hash === d.hash));\n\n const data = [\n {\n title: \"Your Decorations\",\n subtitle: \"You can delete your own decorations by right clicking on them.\",\n sectionKey: \"ownDecorations\",\n items: [\"none\", ...ownDecorations, \"create\"]\n },\n ...presets.map(preset => ({\n title: preset.name,\n subtitle: preset.description || undefined,\n sectionKey: `preset-${preset.id}`,\n items: preset.decorations,\n authorIds: preset.authorIds\n }))\n ] as Section[];\n\n return <ModalRoot\n {...props}\n size={ModalSize.DYNAMIC}\n className={DecorationModalStyles.modal}\n >\n <ModalHeader separator={false} className={cl(\"modal-header\")}>\n <Text\n color=\"header-primary\"\n variant=\"heading-lg/semibold\"\n tag=\"h1\"\n style={{ flexGrow: 1 }}\n >\n Change Decoration\n </Text>\n <ModalCloseButton onClick={props.onClose} />\n </ModalHeader>\n <ModalContent\n className={cl(\"change-decoration-modal-content\")}\n scrollbarType=\"none\"\n >\n <ErrorBoundary>\n <SectionedGridList\n renderItem={item => {\n if (typeof item === \"string\") {\n switch (item) {\n case \"none\":\n return <DecorationGridNone\n className={cl(\"change-decoration-modal-decoration\")}\n isSelected={activeSelectedDecoration === null}\n onSelect={() => setTryingDecoration(null)}\n />;\n case \"create\":\n return <Tooltip text=\"You already have a decoration pending review\" shouldShow={hasDecorationPendingReview}>\n {tooltipProps => <DecorationGridCreate\n className={cl(\"change-decoration-modal-decoration\")}\n {...tooltipProps}\n onSelect={!hasDecorationPendingReview ? (settings.store.agreedToGuidelines ? openCreateDecorationModal : openGuidelinesModal) : () => { }}\n />}\n </Tooltip>;\n }\n } else {\n return <Tooltip text={\"Pending review\"} shouldShow={item.reviewed === false}>\n {tooltipProps => (\n <DecorDecorationGridDecoration\n {...tooltipProps}\n className={cl(\"change-decoration-modal-decoration\")}\n onSelect={item.reviewed !== false ? () => setTryingDecoration(item) : () => { }}\n isSelected={activeSelectedDecoration?.hash === item.hash}\n decoration={item}\n />\n )}\n </Tooltip>;\n }\n }}\n getItemKey={item => typeof item === \"string\" ? item : item.hash}\n getSectionKey={section => section.sectionKey}\n renderSectionHeader={section => <SectionHeader section={section} />}\n sections={data}\n />\n <div className={cl(\"change-decoration-modal-preview\")}>\n <AvatarDecorationModalPreview\n avatarDecorationOverride={avatarDecorationOverride}\n user={UserStore.getCurrentUser()}\n />\n {isActiveDecorationPreset && <Forms.FormTitle className=\"\">Part of the {activeDecorationPreset.name} Preset</Forms.FormTitle>}\n {typeof activeSelectedDecoration === \"object\" &&\n <Text\n variant=\"text-sm/semibold\"\n color=\"header-primary\"\n >\n {activeSelectedDecoration?.alt}\n </Text>\n }\n {activeDecorationHasAuthor && <Text key={`createdBy-${activeSelectedDecoration.authorId}`}>Created by {Parser.parse(`<@${activeSelectedDecoration.authorId}>`)}</Text>}\n </div>\n </ErrorBoundary>\n </ModalContent>\n <ModalFooter className={classes(cl(\"change-decoration-modal-footer\", cl(\"modal-footer\")))}>\n <div className={cl(\"change-decoration-modal-footer-btn-container\")}>\n <Button\n onClick={() => {\n selectDecoration(tryingDecoration!).then(props.onClose);\n }}\n disabled={!isTryingDecoration}\n >\n Apply\n </Button>\n <Button\n onClick={props.onClose}\n color={Button.Colors.PRIMARY}\n look={Button.Looks.LINK}\n >\n Cancel\n </Button>\n </div>\n <div className={cl(\"change-decoration-modal-footer-btn-container\")}>\n <Button\n onClick={() => Alerts.show({\n title: \"Log Out\",\n body: \"Are you sure you want to log out of Decor?\",\n confirmText: \"Log Out\",\n confirmColor: cl(\"danger-btn\"),\n cancelText: \"Cancel\",\n onConfirm() {\n useAuthorizationStore.getState().remove(UserStore.getCurrentUser().id);\n props.onClose();\n }\n })}\n color={Button.Colors.PRIMARY}\n look={Button.Looks.LINK}\n >\n Log Out\n </Button>\n <Tooltip text=\"Join Decor's Discord Server for notifications on your decoration's review, and when new presets are released\">\n {tooltipProps => <Button\n {...tooltipProps}\n onClick={async () => {\n if (!GuildStore.getGuild(GUILD_ID)) {\n const inviteAccepted = await openInviteModal(INVITE_KEY);\n if (inviteAccepted) {\n closeAllModals();\n FluxDispatcher.dispatch({ type: \"LAYER_POP_ALL\" });\n }\n } else {\n props.onClose();\n FluxDispatcher.dispatch({ type: \"LAYER_POP_ALL\" });\n NavigationRouter.transitionToGuild(GUILD_ID);\n }\n }}\n color={Button.Colors.PRIMARY}\n look={Button.Looks.LINK}\n >\n Discord Server\n </Button>}\n </Tooltip>\n </div>\n </ModalFooter>\n </ModalRoot>;\n}\n\nexport const openChangeDecorationModal = () =>\n requireAvatarDecorationModal().then(() => openModal(props => <ChangeDecorationModal {...props} />));\n", "/*\n * Vencord, a Discord client mod\n * Copyright (c) 2023 Vendicated and contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport { Flex } from \"@components/Flex\";\nimport { findByCodeLazy } from \"@webpack\";\nimport { Button, useEffect } from \"@webpack/common\";\n\nimport { useAuthorizationStore } from \"../../lib/stores/AuthorizationStore\";\nimport { useCurrentUserDecorationsStore } from \"../../lib/stores/CurrentUserDecorationsStore\";\nimport { cl } from \"../\";\nimport { openChangeDecorationModal } from \"../modals/ChangeDecorationModal\";\n\nconst CustomizationSection = findByCodeLazy(\".customizationSectionBackground\");\n\ninterface DecorSectionProps {\n hideTitle?: boolean;\n hideDivider?: boolean;\n noMargin?: boolean;\n}\n\nexport default function DecorSection({ hideTitle = false, hideDivider = false, noMargin = false }: DecorSectionProps) {\n const authorization = useAuthorizationStore();\n const { selectedDecoration, select: selectDecoration, fetch: fetchDecorations } = useCurrentUserDecorationsStore();\n\n useEffect(() => {\n if (authorization.isAuthorized()) fetchDecorations();\n }, [authorization.token]);\n\n return <CustomizationSection\n title={!hideTitle && \"Decor\"}\n hasBackground={true}\n hideDivider={hideDivider}\n className={noMargin && cl(\"section-remove-margin\")}\n >\n <Flex>\n <Button\n onClick={() => {\n if (!authorization.isAuthorized()) {\n authorization.authorize().then(openChangeDecorationModal).catch(() => { });\n } else openChangeDecorationModal();\n }}\n size={Button.Sizes.SMALL}\n >\n Change Decoration\n </Button>\n {selectedDecoration && authorization.isAuthorized() && <Button\n onClick={() => selectDecoration(null)}\n color={Button.Colors.PRIMARY}\n size={Button.Sizes.SMALL}\n look={Button.Looks.LINK}\n >\n Remove Decoration\n </Button>}\n </Flex>\n </CustomizationSection>;\n}\n", "/*\n * Vencord, a Discord client mod\n * Copyright (c) 2023 Vendicated and contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport { definePluginSettings } from \"@api/Settings\";\nimport { Link } from \"@components/Link\";\nimport { Margins } from \"@utils/margins\";\nimport { classes } from \"@utils/misc\";\nimport { closeAllModals } from \"@utils/modal\";\nimport { OptionType } from \"@utils/types\";\nimport { FluxDispatcher, Forms } from \"@webpack/common\";\n\nimport DecorSection from \"./ui/components/DecorSection\";\n\nexport const settings = definePluginSettings({\n changeDecoration: {\n type: OptionType.COMPONENT,\n description: \"Change your avatar decoration\",\n component() {\n if (!Vencord.Plugins.plugins.Decor.started) return <Forms.FormText>\n Enable Decor and restart your client to change your avatar decoration.\n </Forms.FormText>;\n\n return <div>\n <DecorSection hideTitle hideDivider noMargin />\n <Forms.FormText type=\"description\" className={classes(Margins.top8, Margins.bottom8)}>\n You can also access Decor decorations from the <Link\n href=\"/settings/profile-customization\"\n onClick={e => {\n e.preventDefault();\n closeAllModals();\n FluxDispatcher.dispatch({ type: \"USER_SETTINGS_MODAL_SET_SECTION\", section: \"Profile Customization\" });\n }}\n >Profiles</Link> page.\n </Forms.FormText>\n </div>;\n }\n },\n agreedToGuidelines: {\n type: OptionType.BOOLEAN,\n description: \"Agreed to guidelines\",\n hidden: true,\n default: false\n }\n});\n", "/*\n * Vencord, a Discord client mod\n * Copyright (c) 2023 Vendicated, FieryFlames and contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport \"./ui/styles.css\";\n\nimport ErrorBoundary from \"@components/ErrorBoundary\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\nimport { findByPropsLazy } from \"@webpack\";\nimport { UserStore } from \"@webpack/common\";\n\nimport { CDN_URL, RAW_SKU_ID, SKU_ID } from \"./lib/constants\";\nimport { useAuthorizationStore } from \"./lib/stores/AuthorizationStore\";\nimport { useCurrentUserDecorationsStore } from \"./lib/stores/CurrentUserDecorationsStore\";\nimport { useUserDecorAvatarDecoration, useUsersDecorationsStore } from \"./lib/stores/UsersDecorationsStore\";\nimport { settings } from \"./settings\";\nimport { setDecorationGridDecoration, setDecorationGridItem } from \"./ui/components\";\nimport DecorSection from \"./ui/components/DecorSection\";\n\nconst { isAnimatedAvatarDecoration } = findByPropsLazy(\"isAnimatedAvatarDecoration\");\nexport interface AvatarDecoration {\n asset: string;\n skuId: string;\n}\n\nexport default definePlugin({\n name: \"Decor\",\n description: \"Create and use your own custom avatar decorations, or pick your favorite from the presets.\",\n authors: [Devs.FieryFlames],\n patches: [\n // Patch MediaResolver to return correct URL for Decor avatar decorations\n {\n find: \"getAvatarDecorationURL:\",\n replacement: {\n match: /(?<=function \\i\\(\\i\\){)(?=let{avatarDecoration)/,\n replace: \"const vcDecorDecoration=$self.getDecorAvatarDecorationURL(arguments[0]);if(vcDecorDecoration)return vcDecorDecoration;\"\n }\n },\n // Patch profile customization settings to include Decor section\n {\n find: \"DefaultCustomizationSections\",\n replacement: {\n match: /(?<={user:\\i},\"decoration\"\\),)/,\n replace: \"$self.DecorSection(),\"\n }\n },\n // Decoration modal module\n {\n find: \".decorationGridItem\",\n replacement: [\n {\n match: /(?<==)\\i=>{let{children.{20,100}decorationGridItem/,\n replace: \"$self.DecorationGridItem=$&\"\n },\n {\n match: /(?<==)\\i=>{let{user:\\i,avatarDecoration.{300,600}decorationGridItemChurned/,\n replace: \"$self.DecorationGridDecoration=$&\"\n },\n // Remove NEW label from decor avatar decorations\n {\n match: /(?<=\\.Section\\.PREMIUM_PURCHASE&&\\i;if\\()(?<=avatarDecoration:(\\i).+?)/,\n replace: \"$1.skuId===$self.SKU_ID||\"\n }\n ]\n },\n {\n find: \"isAvatarDecorationAnimating:\",\n group: true,\n replacement: [\n // Add Decor avatar decoration hook to avatar decoration hook\n {\n match: /(?<=TryItOut:\\i}\\),)(?<=user:(\\i).+?)/,\n replace: \"vcDecorAvatarDecoration=$self.useUserDecorAvatarDecoration($1),\"\n },\n // Use added hook\n {\n match: /(?<={avatarDecoration:).{1,20}?(?=,)(?<=avatarDecorationOverride:(\\i).+?)/,\n replace: \"$1??vcDecorAvatarDecoration??($&)\"\n },\n // Make memo depend on added hook\n {\n match: /(?<=size:\\i}\\),\\[)/,\n replace: \"vcDecorAvatarDecoration,\"\n }\n ]\n },\n // Current user area, at bottom of channels/dm list\n {\n find: \"renderAvatarWithPopout(){\",\n replacement: [\n // Use Decor avatar decoration hook\n {\n match: /(?<=getAvatarDecorationURL\\)\\({avatarDecoration:)(\\i).avatarDecoration(?=,)/,\n replace: \"$self.useUserDecorAvatarDecoration($1)??$&\"\n }\n ]\n }\n ],\n settings,\n\n flux: {\n CONNECTION_OPEN: () => {\n useAuthorizationStore.getState().init();\n useCurrentUserDecorationsStore.getState().clear();\n useUsersDecorationsStore.getState().fetch(UserStore.getCurrentUser().id, true);\n },\n USER_PROFILE_MODAL_OPEN: data => {\n useUsersDecorationsStore.getState().fetch(data.userId, true);\n },\n },\n\n set DecorationGridItem(e: any) {\n setDecorationGridItem(e);\n },\n\n set DecorationGridDecoration(e: any) {\n setDecorationGridDecoration(e);\n },\n\n SKU_ID,\n\n useUserDecorAvatarDecoration,\n\n async start() {\n useUsersDecorationsStore.getState().fetch(UserStore.getCurrentUser().id, true);\n },\n\n getDecorAvatarDecorationURL({ avatarDecoration, canAnimate }: { avatarDecoration: AvatarDecoration | null; canAnimate?: boolean; }) {\n // Only Decor avatar decorations have this SKU ID\n if (avatarDecoration?.skuId === SKU_ID) {\n const url = new URL(`${CDN_URL}/${avatarDecoration.asset}.png`);\n url.searchParams.set(\"animate\", (!!canAnimate && isAnimatedAvatarDecoration(avatarDecoration.asset)).toString());\n return url.toString();\n } else if (avatarDecoration?.skuId === RAW_SKU_ID) {\n return avatarDecoration.asset;\n }\n },\n\n DecorSection: ErrorBoundary.wrap(DecorSection)\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\n\nexport default definePlugin({\n name: \"DisableDMCallIdle\",\n description: \"Disables automatically getting kicked from a DM voice call after 3 minutes.\",\n authors: [Devs.Nuckyz],\n patches: [\n {\n find: \".Messages.BOT_CALL_IDLE_DISCONNECT\",\n replacement: {\n match: /(?<=function \\i\\(\\){)(?=.{1,120}\\.Messages\\.BOT_CALL_IDLE_DISCONNECT)/,\n replace: \"return;\"\n }\n }\n ]\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { addContextMenuPatch, findGroupChildrenByChildId, NavContextMenuPatchCallback, removeContextMenuPatch } from \"@api/ContextMenu\";\nimport { CheckedTextInput } from \"@components/CheckedTextInput\";\nimport { Devs } from \"@utils/constants\";\nimport { Logger } from \"@utils/Logger\";\nimport { Margins } from \"@utils/margins\";\nimport { ModalContent, ModalHeader, ModalRoot, openModalLazy } from \"@utils/modal\";\nimport definePlugin from \"@utils/types\";\nimport { findByPropsLazy, findStoreLazy } from \"@webpack\";\nimport { EmojiStore, FluxDispatcher, Forms, GuildStore, Menu, PermissionsBits, PermissionStore, React, RestAPI, Toasts, Tooltip, UserStore } from \"@webpack/common\";\nimport { Promisable } from \"type-fest\";\n\nconst StickersStore = findStoreLazy(\"StickersStore\");\nconst EmojiManager = findByPropsLazy(\"fetchEmoji\", \"uploadEmoji\", \"deleteEmoji\");\n\ninterface Sticker {\n t: \"Sticker\";\n description: string;\n format_type: number;\n guild_id: string;\n id: string;\n name: string;\n tags: string;\n type: number;\n}\n\ninterface Emoji {\n t: \"Emoji\";\n id: string;\n name: string;\n isAnimated: boolean;\n}\n\ntype Data = Emoji | Sticker;\n\nconst StickerExt = [, \"png\", \"png\", \"json\", \"gif\"] as const;\n\nfunction getUrl(data: Data) {\n if (data.t === \"Emoji\")\n return `${location.protocol}//${window.GLOBAL_ENV.CDN_HOST}/emojis/${data.id}.${data.isAnimated ? \"gif\" : \"png\"}`;\n\n return `${location.origin}/stickers/${data.id}.${StickerExt[data.format_type]}`;\n}\n\nasync function fetchSticker(id: string) {\n const cached = StickersStore.getStickerById(id);\n if (cached) return cached;\n\n const { body } = await RestAPI.get({\n url: `/stickers/${id}`\n });\n\n FluxDispatcher.dispatch({\n type: \"STICKER_FETCH_SUCCESS\",\n sticker: body\n });\n\n return body as Sticker;\n}\n\nasync function cloneSticker(guildId: string, sticker: Sticker) {\n const data = new FormData();\n data.append(\"name\", sticker.name);\n data.append(\"tags\", sticker.tags);\n data.append(\"description\", sticker.description);\n data.append(\"file\", await fetchBlob(getUrl(sticker)));\n\n const { body } = await RestAPI.post({\n url: `/guilds/${guildId}/stickers`,\n body: data,\n });\n\n FluxDispatcher.dispatch({\n type: \"GUILD_STICKERS_CREATE_SUCCESS\",\n guildId,\n sticker: {\n ...body,\n user: UserStore.getCurrentUser()\n }\n });\n}\n\nasync function cloneEmoji(guildId: string, emoji: Emoji) {\n const data = await fetchBlob(getUrl(emoji));\n\n const dataUrl = await new Promise<string>(resolve => {\n const reader = new FileReader();\n reader.onload = () => resolve(reader.result as string);\n reader.readAsDataURL(data);\n });\n\n return EmojiManager.uploadEmoji({\n guildId,\n name: emoji.name.split(\"~\")[0],\n image: dataUrl\n });\n}\n\nfunction getGuildCandidates(data: Data) {\n const meId = UserStore.getCurrentUser().id;\n\n return Object.values(GuildStore.getGuilds()).filter(g => {\n const canCreate = g.ownerId === meId ||\n (PermissionStore.getGuildPermissions({ id: g.id }) & PermissionsBits.CREATE_GUILD_EXPRESSIONS) === PermissionsBits.CREATE_GUILD_EXPRESSIONS;\n if (!canCreate) return false;\n\n if (data.t === \"Sticker\") return true;\n\n const { isAnimated } = data as Emoji;\n\n const emojiSlots = g.getMaxEmojiSlots();\n const { emojis } = EmojiStore.getGuilds()[g.id];\n\n let count = 0;\n for (const emoji of emojis)\n if (emoji.animated === isAnimated) count++;\n return count < emojiSlots;\n }).sort((a, b) => a.name.localeCompare(b.name));\n}\n\nasync function fetchBlob(url: string) {\n const res = await fetch(url);\n if (!res.ok)\n throw new Error(`Failed to fetch ${url} - ${res.status}`);\n\n return res.blob();\n}\n\nasync function doClone(guildId: string, data: Sticker | Emoji) {\n try {\n if (data.t === \"Sticker\")\n await cloneSticker(guildId, data);\n else\n await cloneEmoji(guildId, data);\n\n Toasts.show({\n message: `Successfully cloned ${data.name} to ${GuildStore.getGuild(guildId)?.name ?? \"your server\"}!`,\n type: Toasts.Type.SUCCESS,\n id: Toasts.genId()\n });\n } catch (e: any) {\n let message = \"Something went wrong (check console!)\";\n try {\n message = JSON.parse(e.text).message;\n } catch { }\n\n new Logger(\"EmoteCloner\").error(\"Failed to clone\", data.name, \"to\", guildId, e);\n Toasts.show({\n message: \"Failed to clone: \" + message,\n type: Toasts.Type.FAILURE,\n id: Toasts.genId()\n });\n }\n}\n\nconst getFontSize = (s: string) => {\n // [18, 18, 16, 16, 14, 12, 10]\n const sizes = [20, 20, 18, 18, 16, 14, 12];\n return sizes[s.length] ?? 4;\n};\n\nconst nameValidator = /^\\w+$/i;\n\nfunction CloneModal({ data }: { data: Sticker | Emoji; }) {\n const [isCloning, setIsCloning] = React.useState(false);\n const [name, setName] = React.useState(data.name);\n\n const [x, invalidateMemo] = React.useReducer(x => x + 1, 0);\n\n const guilds = React.useMemo(() => getGuildCandidates(data), [data.id, x]);\n\n return (\n <>\n <Forms.FormTitle className={Margins.top20}>Custom Name</Forms.FormTitle>\n <CheckedTextInput\n value={name}\n onChange={v => {\n data.name = v;\n setName(v);\n }}\n validate={v =>\n (data.t === \"Emoji\" && v.length > 2 && v.length < 32 && nameValidator.test(v))\n || (data.t === \"Sticker\" && v.length > 2 && v.length < 30)\n || \"Name must be between 2 and 32 characters and only contain alphanumeric characters\"\n }\n />\n <div style={{\n display: \"flex\",\n flexWrap: \"wrap\",\n gap: \"1em\",\n padding: \"1em 0.5em\",\n justifyContent: \"center\",\n alignItems: \"center\"\n }}>\n {guilds.map(g => (\n <Tooltip text={g.name}>\n {({ onMouseLeave, onMouseEnter }) => (\n <div\n onMouseLeave={onMouseLeave}\n onMouseEnter={onMouseEnter}\n role=\"button\"\n aria-label={\"Clone to \" + g.name}\n aria-disabled={isCloning}\n style={{\n borderRadius: \"50%\",\n backgroundColor: \"var(--background-secondary)\",\n display: \"inline-flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n width: \"4em\",\n height: \"4em\",\n cursor: isCloning ? \"not-allowed\" : \"pointer\",\n filter: isCloning ? \"brightness(50%)\" : \"none\"\n }}\n onClick={isCloning ? void 0 : async () => {\n setIsCloning(true);\n doClone(g.id, data).finally(() => {\n invalidateMemo();\n setIsCloning(false);\n });\n }}\n >\n {g.icon ? (\n <img\n aria-hidden\n style={{\n borderRadius: \"50%\",\n width: \"100%\",\n height: \"100%\",\n }}\n src={g.getIconURL(512, true)}\n alt={g.name}\n />\n ) : (\n <Forms.FormText\n style={{\n fontSize: getFontSize(g.acronym),\n width: \"100%\",\n overflow: \"hidden\",\n whiteSpace: \"nowrap\",\n textAlign: \"center\",\n cursor: isCloning ? \"not-allowed\" : \"pointer\",\n }}\n >\n {g.acronym}\n </Forms.FormText>\n )}\n </div>\n )}\n </Tooltip>\n ))}\n </div>\n </>\n );\n}\n\nfunction buildMenuItem(type: \"Emoji\" | \"Sticker\", fetchData: () => Promisable<Omit<Sticker | Emoji, \"t\">>) {\n return (\n <Menu.MenuItem\n id=\"emote-cloner\"\n key=\"emote-cloner\"\n label={`Clone ${type}`}\n action={() =>\n openModalLazy(async () => {\n const res = await fetchData();\n const data = { t: type, ...res } as Sticker | Emoji;\n const url = getUrl(data);\n\n return modalProps => (\n <ModalRoot {...modalProps}>\n <ModalHeader>\n <img\n role=\"presentation\"\n aria-hidden\n src={url}\n alt=\"\"\n height={24}\n width={24}\n style={{ marginRight: \"0.5em\" }}\n />\n <Forms.FormText>Clone {data.name}</Forms.FormText>\n </ModalHeader>\n <ModalContent>\n <CloneModal data={data} />\n </ModalContent>\n </ModalRoot>\n );\n })\n }\n />\n );\n}\n\nfunction isGifUrl(url: string) {\n return new URL(url).pathname.endsWith(\".gif\");\n}\n\nconst messageContextMenuPatch: NavContextMenuPatchCallback = (children, props) => () => {\n const { favoriteableId, itemHref, itemSrc, favoriteableType } = props ?? {};\n\n if (!favoriteableId) return;\n\n const menuItem = (() => {\n switch (favoriteableType) {\n case \"emoji\":\n const match = props.message.content.match(RegExp(`<a?:(\\\\w+)(?:~\\\\d+)?:${favoriteableId}>|https://cdn\\\\.discordapp\\\\.com/emojis/${favoriteableId}\\\\.`));\n if (!match) return;\n const name = match[1] ?? \"FakeNitroEmoji\";\n\n return buildMenuItem(\"Emoji\", () => ({\n id: favoriteableId,\n name,\n isAnimated: isGifUrl(itemHref ?? itemSrc)\n }));\n case \"sticker\":\n const sticker = props.message.stickerItems.find(s => s.id === favoriteableId);\n if (sticker?.format_type === 3 /* LOTTIE */) return;\n\n return buildMenuItem(\"Sticker\", () => fetchSticker(favoriteableId));\n }\n })();\n\n if (menuItem)\n findGroupChildrenByChildId(\"copy-link\", children)?.push(menuItem);\n};\n\nconst expressionPickerPatch: NavContextMenuPatchCallback = (children, props: { target: HTMLElement; }) => () => {\n const { id, name, type } = props?.target?.dataset ?? {};\n if (!id) return;\n\n if (type === \"emoji\" && name) {\n const firstChild = props.target.firstChild as HTMLImageElement;\n\n children.push(buildMenuItem(\"Emoji\", () => ({\n id,\n name,\n isAnimated: firstChild && isGifUrl(firstChild.src)\n })));\n } else if (type === \"sticker\" && !props.target.className?.includes(\"lottieCanvas\")) {\n children.push(buildMenuItem(\"Sticker\", () => fetchSticker(id)));\n }\n};\n\nexport default definePlugin({\n name: \"EmoteCloner\",\n description: \"Allows you to clone Emotes & Stickers to your own server (right click them)\",\n tags: [\"StickerCloner\"],\n authors: [Devs.Ven, Devs.Nuckyz],\n\n start() {\n addContextMenuPatch(\"message\", messageContextMenuPatch);\n addContextMenuPatch(\"expression-picker\", expressionPickerPatch);\n },\n\n stop() {\n removeContextMenuPatch(\"message\", messageContextMenuPatch);\n removeContextMenuPatch(\"expression-picker\", expressionPickerPatch);\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { definePluginSettings } from \"@api/Settings\";\nimport ErrorBoundary from \"@components/ErrorBoundary\";\nimport { ErrorCard } from \"@components/ErrorCard\";\nimport { Devs } from \"@utils/constants\";\nimport { Margins } from \"@utils/margins\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { findByPropsLazy } from \"@webpack\";\nimport { Forms, React } from \"@webpack/common\";\n\nconst KbdStyles = findByPropsLazy(\"key\", \"removeBuildOverride\");\n\nconst settings = definePluginSettings({\n enableIsStaff: {\n description: \"Enable isStaff\",\n type: OptionType.BOOLEAN,\n default: false,\n restartNeeded: true\n }\n});\n\nexport default definePlugin({\n name: \"Experiments\",\n description: \"Enable Access to Experiments in Discord!\",\n authors: [\n Devs.Megu,\n Devs.Ven,\n Devs.Nickyux,\n Devs.BanTheNons,\n Devs.Nuckyz\n ],\n settings,\n\n patches: [\n {\n find: \"Object.defineProperties(this,{isDeveloper\",\n replacement: {\n match: /(?<={isDeveloper:\\{[^}]+?,get:\\(\\)=>)\\i/,\n replace: \"true\"\n }\n },\n {\n find: 'type:\"user\",revision',\n replacement: {\n match: /!(\\i)&&\"CONNECTION_OPEN\".+?;/g,\n replace: \"$1=!0;\"\n }\n },\n {\n find: \".isStaff=()\",\n predicate: () => settings.store.enableIsStaff,\n replacement: [\n {\n match: /=>*?(\\i)\\.hasFlag\\((\\i\\.\\i)\\.STAFF\\)}/,\n replace: (_, user, flags) => `=>Vencord.Webpack.Common.UserStore.getCurrentUser()?.id===${user}.id||${user}.hasFlag(${flags}.STAFF)}`\n },\n {\n match: /hasFreePremium\\(\\){return this.isStaff\\(\\)\\s*?\\|\\|/,\n replace: \"hasFreePremium(){return \",\n }\n ]\n },\n {\n find: 'H1,title:\"Experiments\"',\n replacement: {\n match: 'title:\"Experiments\",children:[',\n replace: \"$&$self.WarningCard(),\"\n }\n }\n ],\n\n settingsAboutComponent: () => {\n const isMacOS = navigator.platform.includes(\"Mac\");\n const modKey = isMacOS ? \"cmd\" : \"ctrl\";\n const altKey = isMacOS ? \"opt\" : \"alt\";\n return (\n <React.Fragment>\n <Forms.FormTitle tag=\"h3\">More Information</Forms.FormTitle>\n <Forms.FormText variant=\"text-md/normal\">\n You can enable client DevTools{\" \"}\n <kbd className={KbdStyles.key}>{modKey}</kbd> +{\" \"}\n <kbd className={KbdStyles.key}>{altKey}</kbd> +{\" \"}\n <kbd className={KbdStyles.key}>O</kbd>{\" \"}\n after enabling <code>isStaff</code> below\n </Forms.FormText>\n <Forms.FormText>\n and then toggling <code>Enable DevTools</code> in the <code>Developer Options</code> tab in settings.\n </Forms.FormText>\n </React.Fragment>\n );\n },\n\n WarningCard: ErrorBoundary.wrap(() => (\n <ErrorCard id=\"vc-experiments-warning-card\" className={Margins.bottom16}>\n <Forms.FormTitle tag=\"h2\">Hold on!!</Forms.FormTitle>\n\n <Forms.FormText>\n Experiments are unreleased Discord features. They might not work, or even break your client or get your account disabled.\n </Forms.FormText>\n\n <Forms.FormText className={Margins.top8}>\n Only use experiments if you know what you're doing. Vencord is not responsible for any damage caused by enabling experiments.\n </Forms.FormText>\n </ErrorCard>\n ), { noop: true })\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\n\nexport default definePlugin({\n name: \"F8Break\",\n description: \"Pause the client when you press F8 with DevTools (+ breakpoints) open.\",\n authors: [Devs.lewisakura],\n\n start() {\n window.addEventListener(\"keydown\", this.event);\n },\n\n stop() {\n window.removeEventListener(\"keydown\", this.event);\n },\n\n event(e: KeyboardEvent) {\n if (e.code === \"F8\") {\n // Hi! You've just paused the client. Pressing F8 in DevTools or in the main window will unpause it again.\n // It's up to you on what to do, friend. Happy travels!\n debugger;\n }\n }\n});\n", "/*\n * Vencord, a Discord client mod\n * Copyright (c) 2023 Vendicated and contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nexport let EXTENSION_BASE_URL: string;\nexport let EXTENSION_VERSION: string;\n\nif (IS_EXTENSION) {\n const script = document.querySelector(\"#vencord-script\") as HTMLScriptElement;\n EXTENSION_BASE_URL = script.dataset.extensionBaseUrl!;\n EXTENSION_VERSION = script.dataset.version!;\n}\n", "/* eslint-disable */\n\nconst self = module.exports;\n/**\n * apng-canvas v2.1.2\n *\n * @copyright 2011-2019 David Mzareulyan\n * @link https://github.com/davidmz/apng-canvas\n * @license MIT\n */\n!(function i(o, a, s) {\n function u(n, t) {\n if (!a[n]) {\n if (!o[n]) {\n var e = \"function\" == typeof require && require;\n if (!t && e) return e(n, !0);\n if (c) return c(n, !0);\n throw new Error(\"Cannot find module '\" + n + \"'\");\n }\n var r = (a[n] = { exports: {} });\n o[n][0].call(\n r.exports,\n function (t) {\n var e = o[n][1][t];\n return u(e || t);\n },\n r,\n r.exports,\n i,\n o,\n a,\n s\n );\n }\n return a[n].exports;\n }\n for (\n var c = \"function\" == typeof require && require, t = 0;\n t < s.length;\n t++\n )\n u(s[t]);\n return u;\n})(\n {\n 1: [\n function (Y, n, r) {\n (function (G, q) {\n var t, e;\n (t = this),\n (e = function () {\n \"use strict\";\n function u(t) {\n return \"function\" == typeof t;\n }\n var n = Array.isArray\n ? Array.isArray\n : function (t) {\n return (\n \"[object Array]\" ===\n Object.prototype.toString.call(t)\n );\n },\n r = 0,\n e = void 0,\n i = void 0,\n a = function (t, e) {\n (l[r] = t),\n (l[r + 1] = e),\n 2 === (r += 2) && (i ? i(d) : g());\n };\n var t =\n \"undefined\" != typeof window\n ? window\n : void 0,\n o = t || {},\n s =\n o.MutationObserver ||\n o.WebKitMutationObserver,\n c =\n \"undefined\" == typeof self &&\n void 0 !== G &&\n \"[object process]\" === {}.toString.call(G),\n f =\n \"undefined\" != typeof Uint8ClampedArray &&\n \"undefined\" != typeof importScripts &&\n \"undefined\" != typeof MessageChannel;\n function h() {\n var t = setTimeout;\n return function () {\n return t(d, 1);\n };\n }\n var l = new Array(1e3);\n function d() {\n for (var t = 0; t < r; t += 2) {\n (0, l[t])(l[t + 1]),\n (l[t] = void 0),\n (l[t + 1] = void 0);\n }\n r = 0;\n }\n var p,\n v,\n A,\n m,\n g = void 0;\n function w(t, e) {\n var n = this,\n r = new this.constructor(b);\n void 0 === r[_] && j(r);\n var i = n._state;\n if (i) {\n var o = arguments[i - 1];\n a(function () {\n return L(i, r, o, n._result);\n });\n } else U(n, r, t, e);\n return r;\n }\n function y(t) {\n if (\n t &&\n \"object\" == typeof t &&\n t.constructor === this\n )\n return t;\n var e = new this(b);\n return T(e, t), e;\n }\n g = c\n ? function () {\n return G.nextTick(d);\n }\n : s\n ? ((v = 0),\n (A = new s(d)),\n (m = document.createTextNode(\"\")),\n A.observe(m, { characterData: !0 }),\n function () {\n m.data = v = ++v % 2;\n })\n : f\n ? (((p = new MessageChannel()).port1.onmessage =\n d),\n function () {\n return p.port2.postMessage(0);\n })\n : void 0 === t && \"function\" == typeof Y\n ? (function () {\n try {\n var t =\n Function(\"return this\")().require(\n \"vertx\"\n );\n return void 0 !==\n (e =\n t.runOnLoop || t.runOnContext)\n ? function () {\n e(d);\n }\n : h();\n } catch (t) {\n return h();\n }\n })()\n : h();\n var _ = Math.random().toString(36).substring(2);\n function b() { }\n var E = void 0,\n P = 1,\n x = 2;\n function N(t, r, i) {\n a(function (e) {\n var n = !1,\n t = (function (t, e, n, r) {\n try {\n t.call(e, n, r);\n } catch (t) {\n return t;\n }\n })(\n i,\n r,\n function (t) {\n n ||\n ((n = !0),\n r !== t\n ? T(e, t)\n : O(e, t));\n },\n function (t) {\n n || ((n = !0), R(e, t));\n },\n e._label\n );\n !n && t && ((n = !0), R(e, t));\n }, t);\n }\n function C(t, e, n) {\n e.constructor === t.constructor &&\n n === w &&\n e.constructor.resolve === y\n ? (function (e, t) {\n t._state === P\n ? O(e, t._result)\n : t._state === x\n ? R(e, t._result)\n : U(\n t,\n void 0,\n function (t) {\n return T(e, t);\n },\n function (t) {\n return R(e, t);\n }\n );\n })(t, e)\n : void 0 === n\n ? O(t, e)\n : u(n)\n ? N(t, e, n)\n : O(t, e);\n }\n function T(e, t) {\n if (e === t)\n R(\n e,\n new TypeError(\n \"You cannot resolve a promise with itself\"\n )\n );\n else if (\n (function (t) {\n var e = typeof t;\n return (\n null !== t &&\n (\"object\" == e || \"function\" == e)\n );\n })(t)\n ) {\n var n = void 0;\n try {\n n = t.then;\n } catch (t) {\n return void R(e, t);\n }\n C(e, t, n);\n } else O(e, t);\n }\n function B(t) {\n t._onerror && t._onerror(t._result), I(t);\n }\n function O(t, e) {\n t._state === E &&\n ((t._result = e),\n (t._state = P),\n 0 !== t._subscribers.length && a(I, t));\n }\n function R(t, e) {\n t._state === E &&\n ((t._state = x), (t._result = e), a(B, t));\n }\n function U(t, e, n, r) {\n var i = t._subscribers,\n o = i.length;\n (t._onerror = null),\n (i[o] = e),\n (i[o + P] = n),\n (i[o + x] = r),\n 0 === o && t._state && a(I, t);\n }\n function I(t) {\n var e = t._subscribers,\n n = t._state;\n if (0 !== e.length) {\n for (\n var r = void 0,\n i = void 0,\n o = t._result,\n a = 0;\n a < e.length;\n a += 3\n )\n (r = e[a]),\n (i = e[a + n]),\n r ? L(n, r, i, o) : i(o);\n t._subscribers.length = 0;\n }\n }\n function L(t, e, n, r) {\n var i = u(n),\n o = void 0,\n a = void 0,\n s = !0;\n if (i) {\n try {\n o = n(r);\n } catch (t) {\n (s = !1), (a = t);\n }\n if (e === o)\n return void R(\n e,\n new TypeError(\n \"A promises callback cannot return that same promise.\"\n )\n );\n } else o = r;\n e._state !== E ||\n (i && s\n ? T(e, o)\n : !1 === s\n ? R(e, a)\n : t === P\n ? O(e, o)\n : t === x && R(e, o));\n }\n var D = 0;\n function j(t) {\n (t[_] = D++),\n (t._state = void 0),\n (t._result = void 0),\n (t._subscribers = []);\n }\n var k =\n ((F.prototype._enumerate = function (t) {\n for (\n var e = 0;\n this._state === E && e < t.length;\n e++\n )\n this._eachEntry(t[e], e);\n }),\n (F.prototype._eachEntry = function (e, t) {\n var n = this._instanceConstructor,\n r = n.resolve;\n if (r === y) {\n var i = void 0,\n o = void 0,\n a = !1;\n try {\n i = e.then;\n } catch (t) {\n (a = !0), (o = t);\n }\n if (i === w && e._state !== E)\n this._settledAt(\n e._state,\n t,\n e._result\n );\n else if (\"function\" != typeof i)\n this._remaining--,\n (this._result[t] = e);\n else if (n === S) {\n var s = new n(b);\n a ? R(s, o) : C(s, e, i),\n this._willSettleAt(s, t);\n } else\n this._willSettleAt(\n new n(function (t) {\n return t(e);\n }),\n t\n );\n } else this._willSettleAt(r(e), t);\n }),\n (F.prototype._settledAt = function (t, e, n) {\n var r = this.promise;\n r._state === E &&\n (this._remaining--,\n t === x\n ? R(r, n)\n : (this._result[e] = n)),\n 0 === this._remaining &&\n O(r, this._result);\n }),\n (F.prototype._willSettleAt = function (t, e) {\n var n = this;\n U(\n t,\n void 0,\n function (t) {\n return n._settledAt(P, e, t);\n },\n function (t) {\n return n._settledAt(x, e, t);\n }\n );\n }),\n F);\n function F(t, e) {\n (this._instanceConstructor = t),\n (this.promise = new t(b)),\n this.promise[_] || j(this.promise),\n n(e)\n ? ((this.length = e.length),\n (this._remaining = e.length),\n (this._result = new Array(\n this.length\n )),\n 0 === this.length\n ? O(this.promise, this._result)\n : ((this.length =\n this.length || 0),\n this._enumerate(e),\n 0 === this._remaining &&\n O(\n this.promise,\n this._result\n )))\n : R(\n this.promise,\n new Error(\n \"Array Methods must be provided an Array\"\n )\n );\n }\n var S =\n ((M.prototype.catch = function (t) {\n return this.then(null, t);\n }),\n (M.prototype.finally = function (e) {\n var n = this.constructor;\n return u(e)\n ? this.then(\n function (t) {\n return n\n .resolve(e())\n .then(function () {\n return t;\n });\n },\n function (t) {\n return n\n .resolve(e())\n .then(function () {\n throw t;\n });\n }\n )\n : this.then(e, e);\n }),\n M);\n function M(t) {\n (this[_] = D++),\n (this._result = this._state = void 0),\n (this._subscribers = []),\n b !== t &&\n (\"function\" != typeof t &&\n (function () {\n throw new TypeError(\n \"You must pass a resolver function as the first argument to the promise constructor\"\n );\n })(),\n this instanceof M\n ? (function (e, t) {\n try {\n t(\n function (t) {\n T(e, t);\n },\n function (t) {\n R(e, t);\n }\n );\n } catch (t) {\n R(e, t);\n }\n })(this, t)\n : (function () {\n throw new TypeError(\n \"Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.\"\n );\n })());\n }\n return (\n (S.prototype.then = w),\n (S.all = function (t) {\n return new k(this, t).promise;\n }),\n (S.race = function (i) {\n var o = this;\n return n(i)\n ? new o(function (t, e) {\n for (\n var n = i.length, r = 0;\n r < n;\n r++\n )\n o.resolve(i[r]).then(t, e);\n })\n : new o(function (t, e) {\n return e(\n new TypeError(\n \"You must pass an array to race.\"\n )\n );\n });\n }),\n (S.resolve = y),\n (S.reject = function (t) {\n var e = new this(b);\n return R(e, t), e;\n }),\n (S._setScheduler = function (t) {\n i = t;\n }),\n (S._setAsap = function (t) {\n a = t;\n }),\n (S._asap = a),\n (S.polyfill = function () {\n var t = void 0;\n if (void 0 !== q) t = q;\n else if (\"undefined\" != typeof self)\n t = self;\n else\n try {\n t = Function(\"return this\")();\n } catch (t) {\n throw new Error(\n \"polyfill failed because global object is unavailable in this environment\"\n );\n }\n var e = t.Promise;\n if (e) {\n var n = null;\n try {\n n = Object.prototype.toString.call(\n e.resolve()\n );\n } catch (t) { }\n if (\"[object Promise]\" === n && !e.cast)\n return;\n }\n t.Promise = S;\n }),\n (S.Promise = S)\n );\n }),\n \"object\" == typeof r && void 0 !== n\n ? (n.exports = e())\n : \"function\" == typeof define && define.amd\n ? define(e)\n : (t.ES6Promise = e());\n }).call(\n this,\n Y(\"VCmEsw\"),\n \"undefined\" != typeof self\n ? self\n : \"undefined\" != typeof window\n ? window\n : {}\n );\n },\n { VCmEsw: 2 },\n ],\n 2: [\n function (t, e, n) {\n var r = (e.exports = {});\n function i() { }\n (r.nextTick = (function () {\n var t = \"undefined\" != typeof window && window.setImmediate,\n e =\n \"undefined\" != typeof window &&\n window.postMessage &&\n window.addEventListener;\n if (t)\n return function (t) {\n return window.setImmediate(t);\n };\n if (e) {\n var n = [];\n return (\n window.addEventListener(\n \"message\",\n function (t) {\n var e = t.source;\n (e !== window && null !== e) ||\n \"process-tick\" !== t.data ||\n (t.stopPropagation(),\n 0 < n.length && n.shift()());\n },\n !0\n ),\n function (t) {\n n.push(t),\n window.postMessage(\"process-tick\", \"*\");\n }\n );\n }\n return function (t) {\n setTimeout(t, 0);\n };\n })()),\n (r.title = \"browser\"),\n (r.browser = !0),\n (r.env = {}),\n (r.argv = []),\n (r.on = i),\n (r.addListener = i),\n (r.once = i),\n (r.off = i),\n (r.removeListener = i),\n (r.removeAllListeners = i),\n (r.emit = i),\n (r.binding = function (t) {\n throw new Error(\"process.binding is not supported\");\n }),\n (r.cwd = function () {\n return \"/\";\n }),\n (r.chdir = function (t) {\n throw new Error(\"process.chdir is not supported\");\n });\n },\n {},\n ],\n 3: [\n function (t, e, n) {\n \"use strict\";\n e.exports = function () {\n (this.width = 0),\n (this.height = 0),\n (this.numPlays = 0),\n (this.playTime = 0),\n (this.frames = []),\n (this.play = function () {\n s ||\n u ||\n (this.rewind(),\n (s = !0),\n requestAnimationFrame(e));\n }),\n (this.rewind = function () {\n (o = i = 0), (a = null), (u = s = !1);\n }),\n (this.addContext = function (t) {\n if (0 < c.length) {\n var e = c[0].getImageData(\n 0,\n 0,\n this.width,\n this.height\n );\n t.putImageData(e, 0, 0);\n }\n c.push(t), (t._apng_animation = this);\n }),\n (this.removeContext = function (t) {\n var e = c.indexOf(t);\n -1 !== e &&\n (c.splice(e, 1),\n 0 === c.length && this.rewind(),\n \"_apng_animation\" in t &&\n delete t._apng_animation);\n }),\n (this.isPlayed = function () {\n return s;\n }),\n (this.isFinished = function () {\n return u;\n });\n var r = this,\n i = 0,\n o = 0,\n a = null,\n s = !1,\n u = !1,\n c = [],\n e = function (t) {\n for (; s && i <= t;) n(t);\n s && requestAnimationFrame(e);\n },\n n = function (t) {\n var e = o++ % r.frames.length,\n n = r.frames[e];\n if (\n 0 == r.numPlays ||\n o / r.frames.length <= r.numPlays\n ) {\n for (\n 0 == e &&\n (c.forEach(function (t) {\n t.clearRect(\n 0,\n 0,\n r.width,\n r.height\n );\n }),\n (a = null),\n 2 == n.disposeOp && (n.disposeOp = 1)),\n a && 1 == a.disposeOp\n ? c.forEach(function (t) {\n t.clearRect(\n a.left,\n a.top,\n a.width,\n a.height\n );\n })\n : a &&\n 2 == a.disposeOp &&\n c.forEach(function (t) {\n t.putImageData(\n a.iData,\n a.left,\n a.top\n );\n }),\n (a = n).iData = null,\n 2 == a.disposeOp &&\n (a.iData = c[0].getImageData(\n n.left,\n n.top,\n n.width,\n n.height\n )),\n 0 == n.blendOp &&\n c.forEach(function (t) {\n t.clearRect(\n n.left,\n n.top,\n n.width,\n n.height\n );\n }),\n c.forEach(function (t) {\n t.drawImage(n.img, n.left, n.top);\n }),\n 0 == i && (i = t);\n t > i + r.playTime;\n\n )\n i += r.playTime;\n i += n.delay;\n } else u = !(s = !1);\n };\n };\n },\n {},\n ],\n 4: [\n function (t, e, n) {\n \"use strict\";\n for (var a = new Uint32Array(256), r = 0; r < 256; r++) {\n for (var i = r, o = 0; o < 8; o++)\n i = 1 & i ? 3988292384 ^ (i >>> 1) : i >>> 1;\n a[r] = i;\n }\n e.exports = function (t, e, n) {\n for (\n var r = -1,\n i = (e = e || 0),\n o = e + (n = n || t.length - e);\n i < o;\n i++\n )\n r = (r >>> 8) ^ a[255 & (r ^ t[i])];\n return -1 ^ r;\n };\n },\n {},\n ],\n 5: [\n function (a, t, e) {\n (function (t) {\n \"use strict\";\n var e = a(\"./support-test\"),\n n = a(\"./parser\"),\n r = a(\"./loader\"),\n i = (t.APNG = {});\n (i.checkNativeFeatures = e.checkNativeFeatures),\n (i.ifNeeded = e.ifNeeded),\n (i.parseBuffer = function (t) {\n return n(t);\n });\n var o = {};\n (i.parseURL = function (t) {\n return t in o || (o[t] = r(t).then(n)), o[t];\n }),\n (i.animateContext = function (t, e) {\n return i.parseURL(t).then(function (t) {\n return t.addContext(e), t.play(), t;\n });\n }),\n (i.animateImage = function (s) {\n return (\n s.setAttribute(\"data-is-apng\", \"progress\"),\n i.parseURL(s.src).then(\n function (t) {\n s.setAttribute(\"data-is-apng\", \"yes\");\n var e =\n document.createElement(\"canvas\");\n (e.width = t.width),\n (e.height = t.height),\n Array.prototype.slice\n .call(s.attributes)\n .forEach(function (t) {\n -1 ==\n [\n \"alt\",\n \"src\",\n \"usemap\",\n \"ismap\",\n \"data-is-apng\",\n \"width\",\n \"height\",\n ].indexOf(t.nodeName) &&\n e.setAttributeNode(\n t.cloneNode(!1)\n );\n }),\n e.setAttribute(\n \"data-apng-src\",\n s.src\n ),\n \"\" != s.alt &&\n e.appendChild(\n document.createTextNode(\n s.alt\n )\n );\n var n = \"\",\n r = \"\",\n i = 0,\n o = \"\";\n \"\" != s.style.width &&\n \"auto\" != s.style.width\n ? (n = s.style.width)\n : s.hasAttribute(\"width\") &&\n (n =\n s.getAttribute(\"width\") +\n \"px\"),\n \"\" != s.style.height &&\n \"auto\" != s.style.height\n ? (r = s.style.height)\n : s.hasAttribute(\"height\") &&\n (r =\n s.getAttribute(\"height\") +\n \"px\"),\n \"\" != n &&\n \"\" == r &&\n ((i = parseFloat(n)),\n (o = n.match(/\\D+$/)[0]),\n (r =\n Math.round(\n (e.height * i) / e.width\n ) + o)),\n \"\" != r &&\n \"\" == n &&\n ((i = parseFloat(r)),\n (o = r.match(/\\D+$/)[0]),\n (n =\n Math.round(\n (e.width * i) / e.height\n ) + o)),\n (e.style.width = n),\n (e.style.height = r);\n var a = s.parentNode;\n a.insertBefore(e, s),\n a.removeChild(s),\n t.addContext(e.getContext(\"2d\")),\n t.play();\n },\n function () {\n s.setAttribute(\"data-is-apng\", \"no\");\n }\n )\n );\n }),\n (i.releaseCanvas = function (t) {\n var e = t.getContext(\"2d\");\n \"_apng_animation\" in e &&\n e._apng_animation.removeContext(e);\n });\n }).call(\n this,\n \"undefined\" != typeof self\n ? self\n : \"undefined\" != typeof window\n ? window\n : {}\n );\n },\n { \"./loader\": 6, \"./parser\": 7, \"./support-test\": 8 },\n ],\n 6: [\n function (t, e, n) {\n \"use strict\";\n var i = i || t(\"es6-promise\").Promise;\n e.exports = function (r) {\n return new i(function (t, e) {\n var n = new XMLHttpRequest();\n n.open(\"GET\", r),\n (n.responseType = \"arraybuffer\"),\n (n.onload = function () {\n 200 == this.status ? t(this.response) : e(this);\n }),\n n.send();\n });\n };\n },\n { \"es6-promise\": 1 },\n ],\n 7: [\n function (t, e, n) {\n \"use strict\";\n var r = r || t(\"es6-promise\").Promise,\n m = t(\"./animation\"),\n o = t(\"./crc32\"),\n g = new Uint8Array([137, 80, 78, 71, 13, 10, 26, 10]);\n e.exports = function (t) {\n var A = new Uint8Array(t);\n return new r(function (t, e) {\n for (var n = 0; n < g.length; n++)\n if (g[n] != A[n])\n return void e(\n \"Not a PNG file (invalid file signature)\"\n );\n var r = !1;\n if (\n (w(A, function (t) {\n return \"acTL\" != t || !(r = !0);\n }),\n r)\n ) {\n var a = [],\n s = [],\n u = null,\n c = null,\n f = new m();\n if (\n (w(A, function (t, e, n, r) {\n switch (t) {\n case \"IHDR\":\n (u = e.subarray(n + 8, n + 8 + r)),\n (f.width = y(e, n + 8)),\n (f.height = y(e, n + 12));\n break;\n case \"acTL\":\n f.numPlays = y(e, n + 8 + 4);\n break;\n case \"fcTL\":\n c && f.frames.push(c),\n ((c = {}).width = y(\n e,\n n + 8 + 4\n )),\n (c.height = y(e, n + 8 + 8)),\n (c.left = y(e, n + 8 + 12)),\n (c.top = y(e, n + 8 + 16));\n var i = _(e, n + 8 + 20),\n o = _(e, n + 8 + 22);\n 0 == o && (o = 100),\n (c.delay = (1e3 * i) / o),\n c.delay <= 10 &&\n (c.delay = 100),\n (f.playTime += c.delay),\n (c.disposeOp = b(\n e,\n n + 8 + 24\n )),\n (c.blendOp = b(e, n + 8 + 25)),\n (c.dataParts = []);\n break;\n case \"fdAT\":\n c &&\n c.dataParts.push(\n e.subarray(\n n + 8 + 4,\n n + 8 + r\n )\n );\n break;\n case \"IDAT\":\n c &&\n c.dataParts.push(\n e.subarray(n + 8, n + 8 + r)\n );\n break;\n case \"IEND\":\n s.push(E(e, n, 12 + r));\n break;\n default:\n a.push(E(e, n, 12 + r));\n }\n }),\n c && f.frames.push(c),\n 0 != f.frames.length)\n )\n for (\n var i = 0,\n o = new Blob(a),\n h = new Blob(s),\n l = 0;\n l < f.frames.length;\n l++\n ) {\n c = f.frames[l];\n var d = [];\n d.push(g),\n u.set(P(c.width), 0),\n u.set(P(c.height), 4),\n d.push(x(\"IHDR\", u)),\n d.push(o);\n for (var p = 0; p < c.dataParts.length; p++)\n d.push(x(\"IDAT\", c.dataParts[p]));\n d.push(h);\n var v = URL.createObjectURL(\n new Blob(d, { type: \"image/png\" })\n );\n delete c.dataParts,\n (d = null),\n (c.img = document.createElement(\"img\")),\n (c.img.onload = function () {\n URL.revokeObjectURL(this.src),\n ++i == f.frames.length && t(f);\n }),\n (c.img.onerror = function () {\n e(\"Image creation error\");\n }),\n (c.img.src = v);\n }\n else e(\"Not an animated PNG\");\n } else e(\"Not an animated PNG\");\n });\n };\n var w = function (t, e) {\n var n = 8;\n do {\n var r = y(t, n),\n i = a(t, n + 4, 4),\n o = e(i, t, n, r);\n n += 12 + r;\n } while (!1 !== o && \"IEND\" != i && n < t.length);\n },\n y = function (t, e) {\n var n = 0;\n n += (t[0 + e] << 24) >>> 0;\n for (var r = 1; r < 4; r++)\n n += t[r + e] << (8 * (3 - r));\n return n;\n },\n _ = function (t, e) {\n for (var n = 0, r = 0; r < 2; r++)\n n += t[r + e] << (8 * (1 - r));\n return n;\n },\n b = function (t, e) {\n return t[e];\n },\n E = function (t, e, n) {\n var r = new Uint8Array(n);\n return r.set(t.subarray(e, e + n)), r;\n },\n a = function (t, e, n) {\n var r = Array.prototype.slice.call(\n t.subarray(e, e + n)\n );\n return String.fromCharCode.apply(String, r);\n },\n P = function (t) {\n return [\n (t >>> 24) & 255,\n (t >>> 16) & 255,\n (t >>> 8) & 255,\n 255 & t,\n ];\n },\n x = function (t, e) {\n var n = t.length + e.length,\n r = new Uint8Array(new ArrayBuffer(n + 8));\n r.set(P(e.length), 0),\n r.set(\n (function (t) {\n for (var e = [], n = 0; n < t.length; n++)\n e.push(t.charCodeAt(n));\n return e;\n })(t),\n 4\n ),\n r.set(e, 8);\n var i = o(r, 4, n);\n return r.set(P(i), n + 4), r;\n };\n },\n { \"./animation\": 3, \"./crc32\": 4, \"es6-promise\": 1 },\n ],\n 8: [\n function (o, a, t) {\n (function (t) {\n \"use strict\";\n var e,\n n,\n r = r || o(\"es6-promise\").Promise,\n i =\n ((e = function (e) {\n var n = document.createElement(\"canvas\"),\n r = {\n TypedArrays: \"ArrayBuffer\" in t,\n BlobURLs: \"URL\" in t,\n requestAnimationFrame:\n \"requestAnimationFrame\" in t,\n pageProtocol:\n \"http:\" == location.protocol ||\n \"https:\" == location.protocol,\n canvas:\n \"getContext\" in\n document.createElement(\"canvas\"),\n APNG: !1,\n };\n if (r.canvas) {\n var i = new Image();\n (i.onload = function () {\n var t = n.getContext(\"2d\");\n t.drawImage(i, 0, 0),\n (r.APNG =\n 0 ===\n t.getImageData(0, 0, 1, 1)\n .data[3]),\n e(r);\n }),\n (i.src =\n \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACGFjVEwAAAABAAAAAcMq2TYAAAANSURBVAiZY2BgYPgPAAEEAQB9ssjfAAAAGmZjVEwAAAAAAAAAAQAAAAEAAAAAAAAAAAD6A+gBAbNU+2sAAAARZmRBVAAAAAEImWNgYGBgAAAABQAB6MzFdgAAAABJRU5ErkJggg==\");\n } else e(r);\n }),\n (n = null),\n function (t) {\n return (n = n || new r(e)), t && n.then(t), n;\n });\n a.exports = {\n checkNativeFeatures: i,\n ifNeeded: function (r) {\n return (\n void 0 === r && (r = !1),\n i().then(function (t) {\n if (t.APNG && !r) reject();\n else {\n var e = !0;\n for (var n in t)\n t.hasOwnProperty(n) &&\n \"APNG\" != n &&\n (e = e && t[n]);\n }\n })\n );\n },\n };\n }).call(\n this,\n \"undefined\" != typeof self\n ? self\n : \"undefined\" != typeof window\n ? window\n : {}\n );\n },\n { \"es6-promise\": 1 },\n ],\n },\n {},\n [5]\n);\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { makeLazy } from \"./lazy\";\nimport { EXTENSION_BASE_URL } from \"./web-metadata\";\n\n/*\n Add dynamically loaded dependencies for plugins here.\n */\n\n// needed to parse APNGs in the nitroBypass plugin\nexport const importApngJs = makeLazy(() => {\n return require(\"./apng-canvas\").APNG as { parseURL(url: string): Promise<ApngFrameData>; };\n});\n\n// https://wiki.mozilla.org/APNG_Specification#.60fcTL.60:_The_Frame_Control_Chunk\nexport const enum ApngDisposeOp {\n /**\n * no disposal is done on this frame before rendering the next; the contents of the output buffer are left as is.\n */\n NONE,\n /**\n * the frame's region of the output buffer is to be cleared to fully transparent black before rendering the next frame.\n */\n BACKGROUND,\n /**\n * the frame's region of the output buffer is to be reverted to the previous contents before rendering the next frame.\n */\n PREVIOUS\n}\n\n// TODO: Might need to somehow implement this\nexport const enum ApngBlendOp {\n SOURCE,\n OVER\n}\nexport interface ApngFrame {\n left: number;\n top: number;\n width: number;\n height: number;\n img: HTMLImageElement;\n delay: number;\n blendOp: ApngBlendOp;\n disposeOp: ApngDisposeOp;\n}\n\nexport interface ApngFrameData {\n width: number;\n height: number;\n frames: ApngFrame[];\n playTime: number;\n}\n\n// On web (extensions), use extension uri as basepath (load files from extension)\n// On desktop (electron), load from cdn\nexport const rnnoiseDist = IS_EXTENSION\n ? new URL(\"/third-party/rnnoise\", EXTENSION_BASE_URL).toString()\n : \"https://unpkg.com/@sapphi-red/web-noise-suppressor@0.3.3/dist\";\nexport const rnnoiseWasmSrc = (simd = false) => `${rnnoiseDist}/rnnoise${simd ? \"_simd\" : \"\"}.wasm`;\nexport const rnnoiseWorkletSrc = `${rnnoiseDist}/rnnoise/workletProcessor.js`;\n\n\n// The below code is only used on the Desktop (electron) build of Vencord.\n// Browser (extension) builds do not contain these remote imports.\n\nexport const shikiWorkerSrc = `https://unpkg.com/@vap/shiki-worker@0.0.8/dist/${IS_DEV ? \"index.js\" : \"index.min.js\"}`;\nexport const shikiOnigasmSrc = \"https://unpkg.com/@vap/shiki@0.10.3/dist/onig.wasm\";\n\n// @ts-expect-error\nexport const getStegCloak = /* #__PURE__*/ makeLazy(() => import(\"https://unpkg.com/stegcloak-dist@1.0.0/index.js\"));\n", "import constants from \"./constants.js\";\nimport lzwEncode from \"./lzwEncode.js\";\nimport createStream from \"./stream.js\";\nimport quantize from \"./pnnquant2.js\";\n\nimport {\n prequantize,\n applyPalette,\n nearestColorIndex,\n nearestColor,\n nearestColorIndexWithDistance,\n snapColorsToPalette,\n} from \"./palettize.js\";\n\nfunction GIFEncoder(opt = {}) {\n const { initialCapacity = 4096, auto = true } = opt;\n\n // Stream all encoded data into this buffer\n const stream = createStream(initialCapacity);\n\n // Shared array data across all frames\n const HSIZE = 5003; // 80% occupancy\n const accum = new Uint8Array(256);\n const htab = new Int32Array(HSIZE);\n const codetab = new Int32Array(HSIZE);\n\n let hasInit = false;\n\n return {\n reset() {\n stream.reset();\n hasInit = false;\n },\n finish() {\n stream.writeByte(constants.trailer);\n },\n bytes() {\n return stream.bytes();\n },\n bytesView() {\n return stream.bytesView();\n },\n get buffer() {\n return stream.buffer;\n },\n get stream() {\n return stream;\n },\n writeHeader,\n writeFrame(index, width, height, opts = {}) {\n const {\n transparent = false,\n transparentIndex = 0x00,\n delay = 0,\n palette = null,\n repeat = 0, // -1=once, 0=forever, >0=count\n colorDepth = 8,\n dispose = -1,\n } = opts;\n\n let first = false;\n if (auto) {\n // In 'auto' mode, the first time we write a frame\n // we will write LSD/GCT/EXT\n if (!hasInit) {\n // have not yet init, we can consider this our first frame\n first = true;\n // in 'auto' mode, we also encode a header on first frame\n // this is different than manual mode where you must encode\n // header yoursef (or perhaps not write header altogether)\n writeHeader();\n hasInit = true;\n }\n } else {\n // in manual mode, the first frame is determined by the options only\n first = Boolean(opts.first);\n }\n\n width = Math.max(0, Math.floor(width));\n height = Math.max(0, Math.floor(height));\n\n // Write pre-frame details such as repeat count and global palette\n if (first) {\n if (!palette) {\n throw new Error(\"First frame must include a { palette } option\");\n }\n encodeLogicalScreenDescriptor(\n stream,\n width,\n height,\n palette,\n colorDepth\n );\n encodeColorTable(stream, palette);\n if (repeat >= 0) {\n encodeNetscapeExt(stream, repeat);\n }\n }\n\n const delayTime = Math.round(delay / 10);\n encodeGraphicControlExt(\n stream,\n dispose,\n delayTime,\n transparent,\n transparentIndex\n );\n\n const useLocalColorTable = Boolean(palette) && !first;\n encodeImageDescriptor(\n stream,\n width,\n height,\n useLocalColorTable ? palette : null\n );\n if (useLocalColorTable) encodeColorTable(stream, palette);\n encodePixels(\n stream,\n index,\n width,\n height,\n colorDepth,\n accum,\n htab,\n codetab\n );\n },\n };\n\n function writeHeader() {\n writeUTFBytes(stream, \"GIF89a\");\n }\n}\n\nfunction encodeGraphicControlExt(\n stream,\n dispose,\n delay,\n transparent,\n transparentIndex\n) {\n stream.writeByte(0x21); // extension introducer\n stream.writeByte(0xf9); // GCE label\n stream.writeByte(4); // data block size\n\n if (transparentIndex < 0) {\n transparentIndex = 0x00;\n transparent = false;\n }\n\n var transp, disp;\n if (!transparent) {\n transp = 0;\n disp = 0; // dispose = no action\n } else {\n transp = 1;\n disp = 2; // force clear if using transparent color\n }\n\n if (dispose >= 0) {\n disp = dispose & 7; // user override\n }\n\n disp <<= 2;\n\n const userInput = 0;\n\n // packed fields\n stream.writeByte(\n 0 | // 1:3 reserved\n disp | // 4:6 disposal\n userInput | // 7 user input - 0 = none\n transp // 8 transparency flag\n );\n\n writeUInt16(stream, delay); // delay x 1/100 sec\n stream.writeByte(transparentIndex || 0x00); // transparent color index\n stream.writeByte(0); // block terminator\n}\n\nfunction encodeLogicalScreenDescriptor(\n stream,\n width,\n height,\n palette,\n colorDepth = 8\n) {\n const globalColorTableFlag = 1;\n const sortFlag = 0;\n const globalColorTableSize = colorTableSize(palette.length) - 1;\n const fields =\n (globalColorTableFlag << 7) |\n ((colorDepth - 1) << 4) |\n (sortFlag << 3) |\n globalColorTableSize;\n const backgroundColorIndex = 0;\n const pixelAspectRatio = 0;\n writeUInt16(stream, width);\n writeUInt16(stream, height);\n stream.writeBytes([fields, backgroundColorIndex, pixelAspectRatio]);\n}\n\nfunction encodeNetscapeExt(stream, repeat) {\n stream.writeByte(0x21); // extension introducer\n stream.writeByte(0xff); // app extension label\n stream.writeByte(11); // block size\n writeUTFBytes(stream, \"NETSCAPE2.0\"); // app id + auth code\n stream.writeByte(3); // sub-block size\n stream.writeByte(1); // loop sub-block id\n writeUInt16(stream, repeat); // loop count (extra iterations, 0=repeat forever)\n stream.writeByte(0); // block terminator\n}\n\nfunction encodeColorTable(stream, palette) {\n const colorTableLength = 1 << colorTableSize(palette.length);\n for (let i = 0; i < colorTableLength; i++) {\n let color = [0, 0, 0];\n if (i < palette.length) {\n color = palette[i];\n }\n stream.writeByte(color[0]);\n stream.writeByte(color[1]);\n stream.writeByte(color[2]);\n }\n}\n\nfunction encodeImageDescriptor(stream, width, height, localPalette) {\n stream.writeByte(0x2c); // image separator\n\n writeUInt16(stream, 0); // x position\n writeUInt16(stream, 0); // y position\n writeUInt16(stream, width); // image size\n writeUInt16(stream, height);\n\n if (localPalette) {\n const interlace = 0;\n const sorted = 0;\n const palSize = colorTableSize(localPalette.length) - 1;\n // local palette\n stream.writeByte(\n 0x80 | // 1 local color table 1=yes\n interlace | // 2 interlace - 0=no\n sorted | // 3 sorted - 0=no\n 0 | // 4-5 reserved\n palSize // 6-8 size of color table\n );\n } else {\n // global palette\n stream.writeByte(0);\n }\n}\n\nfunction encodePixels(\n stream,\n index,\n width,\n height,\n colorDepth = 8,\n accum,\n htab,\n codetab\n) {\n lzwEncode(width, height, index, colorDepth, stream, accum, htab, codetab);\n}\n\n// Utilities\n\nfunction writeUInt16(stream, short) {\n stream.writeByte(short & 0xff);\n stream.writeByte((short >> 8) & 0xff);\n}\n\nfunction writeUTFBytes(stream, text) {\n for (var i = 0; i < text.length; i++) {\n stream.writeByte(text.charCodeAt(i));\n }\n}\n\nfunction colorTableSize(length) {\n return Math.max(Math.ceil(Math.log2(length)), 1);\n}\n\nexport {\n GIFEncoder,\n quantize,\n prequantize,\n applyPalette,\n nearestColorIndex,\n nearestColor,\n nearestColorIndexWithDistance,\n snapColorsToPalette,\n};\n\nexport default GIFEncoder;\n", "export default {\n signature: \"GIF\",\n version: \"89a\",\n trailer: 0x3B,\n extensionIntroducer: 0x21,\n applicationExtensionLabel: 0xFF,\n graphicControlExtensionLabel: 0xF9,\n imageSeparator: 0x2C,\n // Header\n signatureSize: 3,\n versionSize: 3,\n globalColorTableFlagMask: 0b10000000,\n colorResolutionMask: 0b01110000,\n sortFlagMask: 0b00001000,\n globalColorTableSizeMask: 0b00000111,\n // Application extension\n applicationIdentifierSize: 8,\n applicationAuthCodeSize: 3,\n // Graphic control extension\n disposalMethodMask: 0b00011100,\n userInputFlagMask: 0b00000010,\n transparentColorFlagMask: 0b00000001,\n // Image descriptor\n localColorTableFlagMask: 0b10000000,\n interlaceFlagMask: 0b01000000,\n idSortFlagMask: 0b00100000,\n localColorTableSizeMask: 0b00000111\n}\n", "export default function createStream(initialCapacity = 256) {\n let cursor = 0;\n let contents = new Uint8Array(initialCapacity);\n\n return {\n get buffer() {\n return contents.buffer;\n },\n reset() {\n cursor = 0;\n },\n bytesView() {\n return contents.subarray(0, cursor);\n },\n bytes() {\n return contents.slice(0, cursor);\n },\n writeByte(byte) {\n expand(cursor + 1);\n contents[cursor] = byte;\n cursor++;\n },\n writeBytes(data, offset = 0, byteLength = data.length) {\n expand(cursor + byteLength);\n for (let i = 0; i < byteLength; i++) {\n contents[cursor++] = data[i + offset];\n }\n },\n writeBytesView(data, offset = 0, byteLength = data.byteLength) {\n expand(cursor + byteLength);\n contents.set(data.subarray(offset, offset + byteLength), cursor);\n cursor += byteLength;\n },\n };\n\n function expand(newCapacity) {\n var prevCapacity = contents.length;\n if (prevCapacity >= newCapacity) return; // No need to expand, the storage was already large enough.\n // Don't expand strictly to the given requested limit if it's only a very small increase, but instead geometrically grow capacity.\n // For small filesizes (<1MB), perform size*2 geometric increase, but for large sizes, do a much more conservative size*1.125 increase to\n // avoid overshooting the allocation cap by a very large margin.\n var CAPACITY_DOUBLING_MAX = 1024 * 1024;\n newCapacity = Math.max(\n newCapacity,\n (prevCapacity * (prevCapacity < CAPACITY_DOUBLING_MAX ? 2.0 : 1.125)) >>>\n 0\n );\n if (prevCapacity != 0) newCapacity = Math.max(newCapacity, 256); // At minimum allocate 256b for each file when expanding.\n const oldContents = contents;\n contents = new Uint8Array(newCapacity); // Allocate new storage.\n if (cursor > 0) contents.set(oldContents.subarray(0, cursor), 0);\n }\n}\n", "/*\n LZWEncoder.js\n Authors\n Kevin Weiner (original Java version - kweiner@fmsware.com)\n Thibault Imbert (AS3 version - bytearray.org)\n Johan Nordberg (JS version - code@johan-nordberg.com)\n Acknowledgements\n GIFCOMPR.C - GIF Image compression routines\n Lempel-Ziv compression based on 'compress'. GIF modifications by\n David Rowley (mgardi@watdcsu.waterloo.edu)\n GIF Image compression - modified 'compress'\n Based on: compress.c - File compression ala IEEE Computer, June 1984.\n By Authors: Spencer W. Thomas (decvax!harpo!utah-cs!utah-gr!thomas)\n Jim McKie (decvax!mcvax!jim)\n Steve Davies (decvax!vax135!petsd!peora!srd)\n Ken Turkowski (decvax!decwrl!turtlevax!ken)\n James A. Woods (decvax!ihnp4!ames!jaw)\n Joe Orost (decvax!vax135!petsd!joe)\n Matt DesLauriers (@mattdesl - V8/JS optimizations)\n Mathieu Henri (@p01 - JS optimization)\n*/\n\nimport createStream from \"./stream.js\";\n\nconst EOF = -1;\nconst BITS = 12;\nconst DEFAULT_HSIZE = 5003; // 80% occupancy\nconst MASKS = [\n 0x0000,\n 0x0001,\n 0x0003,\n 0x0007,\n 0x000f,\n 0x001f,\n 0x003f,\n 0x007f,\n 0x00ff,\n 0x01ff,\n 0x03ff,\n 0x07ff,\n 0x0fff,\n 0x1fff,\n 0x3fff,\n 0x7fff,\n 0xffff,\n];\n\nfunction lzwEncode(\n width,\n height,\n pixels,\n colorDepth,\n outStream = createStream(512),\n accum = new Uint8Array(256),\n htab = new Int32Array(DEFAULT_HSIZE),\n codetab = new Int32Array(DEFAULT_HSIZE)\n) {\n const hsize = htab.length;\n const initCodeSize = Math.max(2, colorDepth);\n\n accum.fill(0);\n codetab.fill(0);\n htab.fill(-1);\n\n let cur_accum = 0;\n let cur_bits = 0;\n\n // Algorithm: use open addressing double hashing (no chaining) on the\n // prefix code / next character combination. We do a variant of Knuth's\n // algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime\n // secondary probe. Here, the modular division first probe is gives way\n // to a faster exclusive-or manipulation. Also do block compression with\n // an adaptive reset, whereby the code table is cleared when the compression\n // ratio decreases, but after the table fills. The variable-length output\n // codes are re-sized at this point, and a special CLEAR code is generated\n // for the decompressor. Late addition: construct the table according to\n // file size for noticeable speed improvement on small files. Please direct\n // questions about this implementation to ames!jaw.\n\n // compress and write the pixel data\n const init_bits = initCodeSize + 1;\n\n // Set up the globals: g_init_bits - initial number of bits\n const g_init_bits = init_bits;\n\n // Set up the necessary values\n\n // block compression parameters -- after all codes are used up,\n // and compression rate changes, start over.\n let clear_flg = false;\n let n_bits = g_init_bits;\n let maxcode = (1 << n_bits) - 1;\n\n const ClearCode = 1 << (init_bits - 1);\n const EOFCode = ClearCode + 1;\n let free_ent = ClearCode + 2;\n let a_count = 0; // clear packet\n\n let ent = pixels[0];\n\n let hshift = 0;\n for (let fcode = hsize; fcode < 65536; fcode *= 2) {\n ++hshift;\n }\n hshift = 8 - hshift; // set hash code range bound\n\n outStream.writeByte(initCodeSize); // write \"initial code size\" byte\n\n output(ClearCode);\n\n const length = pixels.length;\n for (let idx = 1; idx < length; idx++) {\n next_block: {\n const c = pixels[idx];\n const fcode = (c << BITS) + ent;\n let i = (c << hshift) ^ ent; // xor hashing\n if (htab[i] === fcode) {\n ent = codetab[i];\n break next_block;\n }\n\n const disp = i === 0 ? 1 : hsize - i; // secondary hash (after G. Knott)\n while (htab[i] >= 0) {\n // non-empty slot\n i -= disp;\n if (i < 0) i += hsize;\n if (htab[i] === fcode) {\n ent = codetab[i];\n break next_block;\n }\n }\n output(ent);\n ent = c;\n if (free_ent < 1 << BITS) {\n codetab[i] = free_ent++; // code -> hashtable\n htab[i] = fcode;\n } else {\n // Clear out the hash table\n // table clear for block compress\n htab.fill(-1);\n free_ent = ClearCode + 2;\n clear_flg = true;\n output(ClearCode);\n }\n }\n }\n\n // Put out the final code.\n output(ent);\n output(EOFCode);\n\n outStream.writeByte(0); // write block terminator\n return outStream.bytesView();\n\n function output(code) {\n cur_accum &= MASKS[cur_bits];\n\n if (cur_bits > 0) cur_accum |= code << cur_bits;\n else cur_accum = code;\n\n cur_bits += n_bits;\n\n while (cur_bits >= 8) {\n // Add a character to the end of the current packet, and if it is 254\n // characters, flush the packet to disk.\n accum[a_count++] = cur_accum & 0xff;\n if (a_count >= 254) {\n outStream.writeByte(a_count);\n outStream.writeBytesView(accum, 0, a_count);\n a_count = 0;\n }\n cur_accum >>= 8;\n cur_bits -= 8;\n }\n\n // If the next entry is going to be too big for the code size,\n // then increase it, if possible.\n if (free_ent > maxcode || clear_flg) {\n if (clear_flg) {\n n_bits = g_init_bits;\n maxcode = (1 << n_bits) - 1;\n clear_flg = false;\n } else {\n ++n_bits;\n maxcode = n_bits === BITS ? (1 << n_bits) : (1 << n_bits) - 1;\n }\n }\n\n if (code == EOFCode) {\n // At EOF, write the rest of the buffer.\n while (cur_bits > 0) {\n // Add a character to the end of the current packet, and if it is 254\n // characters, flush the packet to disk.\n accum[a_count++] = cur_accum & 0xff;\n if (a_count >= 254) {\n outStream.writeByte(a_count);\n outStream.writeBytesView(accum, 0, a_count);\n a_count = 0;\n }\n cur_accum >>= 8;\n cur_bits -= 8;\n }\n // Flush the packet to disk, and reset the accumulator\n if (a_count > 0) {\n outStream.writeByte(a_count);\n outStream.writeBytesView(accum, 0, a_count);\n a_count = 0;\n }\n }\n }\n}\n\nexport default lzwEncode;\n", "export function uint32_to_rgba(color) {\n var a = (color >> 24) & 0xff;\n var b = (color >> 16) & 0xff;\n var g = (color >> 8) & 0xff;\n var r = color & 0xff;\n return [r, g, b, a];\n}\n\nexport function rgba_to_uint32(r, g, b, a) {\n return (a << 24) | (b << 16) | (g << 8) | r;\n}\n\nexport function rgb888_to_rgb565(r, g, b) {\n return ((r << 8) & 0xf800) | ((g << 2) & 0x03e0) | (b >> 3);\n}\n\nexport function rgba8888_to_rgba4444(r, g, b, a) {\n return (r >> 4) | (g & 0xf0) | ((b & 0xf0) << 4) | ((a & 0xf0) << 8);\n}\n\nexport function rgb888_to_rgb444(r, g, b) {\n return ((r >> 4) << 8) | (g & 0xf0) | (b >> 4);\n}\n\n// Alternative 565 ?\n// return ((r & 0xf8) << 8) + ((g & 0xfc) << 3) + (b >> 3);\n\n// Alternative 4444 ?\n// ((a & 0xf0) << 8) | ((r & 0xf0) << 4) | (g & 0xf0) | (b >> 4);\n", "// Modified from:\n// https://github.com/mcychan/PnnQuant.js/blob/master/src/pnnquant.js\n\n/* Fast pairwise nearest neighbor based algorithm for multilevel thresholding\nCopyright (C) 2004-2019 Mark Tyler and Dmitry Groshev\nCopyright (c) 2018-2021 Miller Cy Chan\n* error measure; time used is proportional to number of bins squared - WJ */\n\nimport {\n rgb888_to_rgb565,\n rgb888_to_rgb444,\n rgba8888_to_rgba4444,\n} from \"./rgb-packing.js\";\n\nfunction clamp(value, min, max) {\n return value < min ? min : value > max ? max : value;\n}\n\nfunction sqr(value) {\n return value * value;\n}\n\nfunction find_nn(bins, idx, hasAlpha) {\n var nn = 0;\n var err = 1e100;\n\n const bin1 = bins[idx];\n const n1 = bin1.cnt;\n const wa = bin1.ac;\n const wr = bin1.rc;\n const wg = bin1.gc;\n const wb = bin1.bc;\n for (var i = bin1.fw; i != 0; i = bins[i].fw) {\n const bin = bins[i];\n const n2 = bin.cnt;\n const nerr2 = (n1 * n2) / (n1 + n2);\n if (nerr2 >= err) continue;\n\n var nerr = 0;\n if (hasAlpha) {\n nerr += nerr2 * sqr(bin.ac - wa);\n if (nerr >= err) continue;\n }\n\n nerr += nerr2 * sqr(bin.rc - wr);\n if (nerr >= err) continue;\n\n nerr += nerr2 * sqr(bin.gc - wg);\n if (nerr >= err) continue;\n\n nerr += nerr2 * sqr(bin.bc - wb);\n if (nerr >= err) continue;\n err = nerr;\n nn = i;\n }\n bin1.err = err;\n bin1.nn = nn;\n}\n\nfunction create_bin() {\n return {\n ac: 0,\n rc: 0,\n gc: 0,\n bc: 0,\n cnt: 0,\n nn: 0,\n fw: 0,\n bk: 0,\n tm: 0,\n mtm: 0,\n err: 0,\n };\n}\n\nfunction bin_add_rgb(bin, r, g, b) {\n bin.rc += r;\n bin.gc += g;\n bin.bc += b;\n bin.cnt++;\n}\n\nfunction create_bin_list(data, format) {\n const bincount = format === \"rgb444\" ? 4096 : 65536;\n const bins = new Array(bincount);\n const size = data.length;\n\n /* Build histogram */\n // Note: Instead of introducing branching/conditions\n // within a very hot per-pixel iteration, we just duplicate the code\n // for each new condition\n if (format === \"rgba4444\") {\n for (let i = 0; i < size; ++i) {\n const color = data[i];\n const a = (color >> 24) & 0xff;\n const b = (color >> 16) & 0xff;\n const g = (color >> 8) & 0xff;\n const r = color & 0xff;\n\n // reduce to rgb4444 16-bit uint\n const index = rgba8888_to_rgba4444(r, g, b, a);\n let bin = index in bins ? bins[index] : (bins[index] = create_bin());\n bin.rc += r;\n bin.gc += g;\n bin.bc += b;\n bin.ac += a;\n bin.cnt++;\n }\n }\n \n else if (format === \"rgb444\") {\n for (let i = 0; i < size; ++i) {\n const color = data[i];\n const b = (color >> 16) & 0xff;\n const g = (color >> 8) & 0xff;\n const r = color & 0xff;\n\n // reduce to rgb444 12-bit uint\n const index = rgb888_to_rgb444(r, g, b);\n let bin = index in bins ? bins[index] : (bins[index] = create_bin());\n bin.rc += r;\n bin.gc += g;\n bin.bc += b;\n bin.cnt++;\n }\n } else {\n for (let i = 0; i < size; ++i) {\n const color = data[i];\n const b = (color >> 16) & 0xff;\n const g = (color >> 8) & 0xff;\n const r = color & 0xff;\n\n // reduce to rgb565 16-bit uint\n const index = rgb888_to_rgb565(r, g, b);\n let bin = index in bins ? bins[index] : (bins[index] = create_bin());\n bin.rc += r;\n bin.gc += g;\n bin.bc += b;\n bin.cnt++;\n }\n }\n return bins;\n}\n\nexport default function quantize(rgba, maxColors, opts = {}) {\n const {\n format = \"rgb565\",\n clearAlpha = true,\n clearAlphaColor = 0x00,\n clearAlphaThreshold = 0,\n oneBitAlpha = false,\n } = opts;\n\n if (!rgba || !rgba.buffer) {\n throw new Error('quantize() expected RGBA Uint8Array data');\n }\n if (!(rgba instanceof Uint8Array) && !(rgba instanceof Uint8ClampedArray)) {\n throw new Error('quantize() expected RGBA Uint8Array data');\n }\n \n const data = new Uint32Array(rgba.buffer);\n\n let useSqrt = opts.useSqrt !== false;\n\n // format can be:\n // rgb565 (default)\n // rgb444\n // rgba4444\n\n const hasAlpha = format === \"rgba4444\";\n const bins = create_bin_list(data, format);\n const bincount = bins.length;\n const bincountMinusOne = bincount - 1;\n const heap = new Uint32Array(bincount + 1);\n\n /* Cluster nonempty bins at one end of array */\n var maxbins = 0;\n for (var i = 0; i < bincount; ++i) {\n const bin = bins[i];\n if (bin != null) {\n var d = 1.0 / bin.cnt;\n if (hasAlpha) bin.ac *= d;\n bin.rc *= d;\n bin.gc *= d;\n bin.bc *= d;\n bins[maxbins++] = bin;\n }\n }\n\n if (sqr(maxColors) / maxbins < 0.022) {\n useSqrt = false;\n }\n\n var i = 0;\n for (; i < maxbins - 1; ++i) {\n bins[i].fw = i + 1;\n bins[i + 1].bk = i;\n if (useSqrt) bins[i].cnt = Math.sqrt(bins[i].cnt);\n }\n if (useSqrt) bins[i].cnt = Math.sqrt(bins[i].cnt);\n\n var h, l, l2;\n /* Initialize nearest neighbors and build heap of them */\n for (i = 0; i < maxbins; ++i) {\n find_nn(bins, i, false);\n /* Push slot on heap */\n var err = bins[i].err;\n for (l = ++heap[0]; l > 1; l = l2) {\n l2 = l >> 1;\n if (bins[(h = heap[l2])].err <= err) break;\n heap[l] = h;\n }\n heap[l] = i;\n }\n\n /* Merge bins which increase error the least */\n var extbins = maxbins - maxColors;\n for (i = 0; i < extbins; ) {\n var tb;\n /* Use heap to find which bins to merge */\n for (;;) {\n var b1 = heap[1];\n tb = bins[b1]; /* One with least error */\n /* Is stored error up to date? */\n if (tb.tm >= tb.mtm && bins[tb.nn].mtm <= tb.tm) break;\n if (tb.mtm == bincountMinusOne)\n /* Deleted node */ b1 = heap[1] = heap[heap[0]--];\n /* Too old error value */ else {\n find_nn(bins, b1, false);\n tb.tm = i;\n }\n /* Push slot down */\n var err = bins[b1].err;\n for (l = 1; (l2 = l + l) <= heap[0]; l = l2) {\n if (l2 < heap[0] && bins[heap[l2]].err > bins[heap[l2 + 1]].err) l2++;\n if (err <= bins[(h = heap[l2])].err) break;\n heap[l] = h;\n }\n heap[l] = b1;\n }\n\n /* Do a merge */\n var nb = bins[tb.nn];\n var n1 = tb.cnt;\n var n2 = nb.cnt;\n var d = 1.0 / (n1 + n2);\n if (hasAlpha) tb.ac = d * (n1 * tb.ac + n2 * nb.ac);\n tb.rc = d * (n1 * tb.rc + n2 * nb.rc);\n tb.gc = d * (n1 * tb.gc + n2 * nb.gc);\n tb.bc = d * (n1 * tb.bc + n2 * nb.bc);\n tb.cnt += nb.cnt;\n tb.mtm = ++i;\n\n /* Unchain deleted bin */\n bins[nb.bk].fw = nb.fw;\n bins[nb.fw].bk = nb.bk;\n nb.mtm = bincountMinusOne;\n }\n\n // let palette = new Uint32Array(maxColors);\n let palette = [];\n\n /* Fill palette */\n var k = 0;\n for (i = 0; ; ++k) {\n let r = clamp(Math.round(bins[i].rc), 0, 0xff);\n let g = clamp(Math.round(bins[i].gc), 0, 0xff);\n let b = clamp(Math.round(bins[i].bc), 0, 0xff);\n\n let a = 0xff;\n if (hasAlpha) {\n a = clamp(Math.round(bins[i].ac), 0, 0xff);\n if (oneBitAlpha) {\n const threshold = typeof oneBitAlpha === \"number\" ? oneBitAlpha : 127;\n a = a <= threshold ? 0x00 : 0xff;\n }\n if (clearAlpha && a <= clearAlphaThreshold) {\n r = g = b = clearAlphaColor;\n a = 0x00;\n }\n }\n\n const color = hasAlpha ? [r, g, b, a] : [r, g, b];\n const exists = existsInPalette(palette, color);\n if (!exists) palette.push(color);\n if ((i = bins[i].fw) == 0) break;\n }\n\n return palette;\n}\n\nfunction existsInPalette(palette, color) {\n for (let i = 0; i < palette.length; i++) {\n const p = palette[i];\n let matchesRGB =\n p[0] === color[0] && p[1] === color[1] && p[2] === color[2];\n let matchesAlpha =\n p.length >= 4 && color.length >= 4 ? p[3] === color[3] : true;\n if (matchesRGB && matchesAlpha) return true;\n }\n return false;\n}\n\n// TODO: Further 'clean' palette by merging nearly-identical colors?\n", "function rgb2y(r, g, b) {\n return r * 0.29889531 + g * 0.58662247 + b * 0.11448223;\n}\nfunction rgb2i(r, g, b) {\n return r * 0.59597799 - g * 0.2741761 - b * 0.32180189;\n}\nfunction rgb2q(r, g, b) {\n return r * 0.21147017 - g * 0.52261711 + b * 0.31114694;\n}\n\nexport function colorDifferenceYIQSquared(yiqA, yiqB) {\n const y = yiqA[0] - yiqB[0];\n const i = yiqA[1] - yiqB[1];\n const q = yiqA[2] - yiqB[2];\n const a = alpha(yiqA) - alpha(yiqB);\n return y * y * 0.5053 + i * i * 0.299 + q * q * 0.1957 + a * a;\n}\n\nfunction alpha(array) {\n return array[3] != null ? array[3] : 0xff;\n}\n\nexport function colorDifferenceYIQ(yiqA, yiqB) {\n return Math.sqrt(colorDifferenceYIQSquared(yiqA, yiqB));\n}\n\nexport function colorDifferenceRGBToYIQSquared(rgb1, rgb2) {\n const [r1, g1, b1] = rgb1;\n const [r2, g2, b2] = rgb2;\n const y = rgb2y(r1, g1, b1) - rgb2y(r2, g2, b2),\n i = rgb2i(r1, g1, b1) - rgb2i(r2, g2, b2),\n q = rgb2q(r1, g1, b1) - rgb2q(r2, g2, b2);\n const a = alpha(rgb1) - alpha(rgb2);\n return y * y * 0.5053 + i * i * 0.299 + q * q * 0.1957 + a * a;\n}\n\nexport function colorDifferenceRGBToYIQ(rgb1, rgb2) {\n return Math.sqrt(colorDifferenceRGBToYIQSquared(rgb1, rgb2));\n}\n\nexport function euclideanDistanceSquared(a, b) {\n var sum = 0;\n var n;\n for (n = 0; n < a.length; n++) {\n const dx = a[n] - b[n];\n sum += dx * dx;\n }\n return sum;\n}\n\nexport function euclideanDistance(a, b) {\n return Math.sqrt(euclideanDistanceSquared(a, b));\n}\n", "import {\n rgb888_to_rgb444,\n rgb888_to_rgb565,\n rgba8888_to_rgba4444,\n} from \"./rgb-packing.js\";\n\nimport { euclideanDistanceSquared } from \"./color.js\";\n\nfunction roundStep(byte, step) {\n return step > 1 ? Math.round(byte / step) * step : byte;\n}\n\nexport function prequantize(\n rgba,\n { roundRGB = 5, roundAlpha = 10, oneBitAlpha = null } = {}\n) {\n const data = new Uint32Array(rgba.buffer);\n for (let i = 0; i < data.length; i++) {\n const color = data[i];\n let a = (color >> 24) & 0xff;\n let b = (color >> 16) & 0xff;\n let g = (color >> 8) & 0xff;\n let r = color & 0xff;\n\n a = roundStep(a, roundAlpha);\n if (oneBitAlpha) {\n const threshold = typeof oneBitAlpha === \"number\" ? oneBitAlpha : 127;\n a = a <= threshold ? 0x00 : 0xff;\n }\n r = roundStep(r, roundRGB);\n g = roundStep(g, roundRGB);\n b = roundStep(b, roundRGB);\n\n data[i] = (a << 24) | (b << 16) | (g << 8) | (r << 0);\n }\n}\n\nexport function applyPalette(rgba, palette, format = \"rgb565\") {\n if (!rgba || !rgba.buffer) {\n throw new Error('quantize() expected RGBA Uint8Array data');\n }\n if (!(rgba instanceof Uint8Array) && !(rgba instanceof Uint8ClampedArray)) {\n throw new Error('quantize() expected RGBA Uint8Array data');\n }\n if (palette.length > 256) {\n throw new Error('applyPalette() only works with 256 colors or less');\n }\n\n const data = new Uint32Array(rgba.buffer);\n const length = data.length;\n const bincount = format === \"rgb444\" ? 4096 : 65536;\n const index = new Uint8Array(length);\n const cache = new Array(bincount);\n const hasAlpha = format === \"rgba4444\";\n\n // Some duplicate code below due to very hot code path\n // Introducing branching/conditions shows some significant impact\n if (format === \"rgba4444\") {\n for (let i = 0; i < length; i++) {\n const color = data[i];\n const a = (color >> 24) & 0xff;\n const b = (color >> 16) & 0xff;\n const g = (color >> 8) & 0xff;\n const r = color & 0xff;\n const key = rgba8888_to_rgba4444(r, g, b, a);\n const idx = key in cache ? cache[key] : (cache[key] = nearestColorIndexRGBA(r, g, b, a, palette));\n index[i] = idx;\n }\n } else {\n const rgb888_to_key = format === \"rgb444\" ? rgb888_to_rgb444 : rgb888_to_rgb565;\n for (let i = 0; i < length; i++) {\n const color = data[i];\n const b = (color >> 16) & 0xff;\n const g = (color >> 8) & 0xff;\n const r = color & 0xff;\n const key = rgb888_to_key(r, g, b);\n const idx = key in cache ? cache[key] : (cache[key] = nearestColorIndexRGB(r, g, b, palette));\n index[i] = idx;\n }\n }\n\n return index;\n}\n\nfunction nearestColorIndexRGBA(r, g, b, a, palette) {\n let k = 0;\n let mindist = 1e100;\n for (let i = 0; i < palette.length; i++) {\n const px2 = palette[i];\n const a2 = px2[3];\n let curdist = sqr(a2 - a);\n if (curdist > mindist) continue;\n const r2 = px2[0];\n curdist += sqr(r2 - r);\n if (curdist > mindist) continue;\n const g2 = px2[1];\n curdist += sqr(g2 - g);\n if (curdist > mindist) continue;\n const b2 = px2[2];\n curdist += sqr(b2 - b);\n if (curdist > mindist) continue;\n mindist = curdist;\n k = i;\n }\n return k;\n}\n\nfunction nearestColorIndexRGB(r, g, b, palette) {\n let k = 0;\n let mindist = 1e100;\n for (let i = 0; i < palette.length; i++) {\n const px2 = palette[i];\n const r2 = px2[0];\n let curdist = sqr(r2 - r);\n if (curdist > mindist) continue;\n const g2 = px2[1];\n curdist += sqr(g2 - g);\n if (curdist > mindist) continue;\n const b2 = px2[2];\n curdist += sqr(b2 - b);\n if (curdist > mindist) continue;\n mindist = curdist;\n k = i;\n }\n return k;\n}\n\nexport function snapColorsToPalette(palette, knownColors, threshold = 5) {\n if (!palette.length || !knownColors.length) return;\n\n const paletteRGB = palette.map((p) => p.slice(0, 3));\n const thresholdSq = threshold * threshold;\n const dim = palette[0].length;\n for (let i = 0; i < knownColors.length; i++) {\n let color = knownColors[i];\n if (color.length < dim) {\n // palette is RGBA, known is RGB\n color = [color[0], color[1], color[2], 0xff];\n } else if (color.length > dim) {\n // palette is RGB, known is RGBA\n color = color.slice(0, 3);\n } else {\n // make sure we always copy known colors\n color = color.slice();\n }\n const r = nearestColorIndexWithDistance(\n paletteRGB,\n color.slice(0, 3),\n euclideanDistanceSquared\n );\n const idx = r[0];\n const distanceSq = r[1];\n if (distanceSq > 0 && distanceSq <= thresholdSq) {\n palette[idx] = color;\n }\n }\n}\n\nfunction sqr(a) {\n return a * a;\n}\n\nexport function nearestColorIndex(\n colors,\n pixel,\n distanceFn = euclideanDistanceSquared\n) {\n let minDist = Infinity;\n let minDistIndex = -1;\n for (let j = 0; j < colors.length; j++) {\n const paletteColor = colors[j];\n const dist = distanceFn(pixel, paletteColor);\n if (dist < minDist) {\n minDist = dist;\n minDistIndex = j;\n }\n }\n return minDistIndex;\n}\n\nexport function nearestColorIndexWithDistance(\n colors,\n pixel,\n distanceFn = euclideanDistanceSquared\n) {\n let minDist = Infinity;\n let minDistIndex = -1;\n for (let j = 0; j < colors.length; j++) {\n const paletteColor = colors[j];\n const dist = distanceFn(pixel, paletteColor);\n if (dist < minDist) {\n minDist = dist;\n minDistIndex = j;\n }\n }\n return [minDistIndex, minDist];\n}\n\nexport function nearestColor(\n colors,\n pixel,\n distanceFn = euclideanDistanceSquared\n) {\n return colors[nearestColorIndex(colors, pixel, distanceFn)];\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { addPreEditListener, addPreSendListener, removePreEditListener, removePreSendListener } from \"@api/MessageEvents\";\nimport { definePluginSettings, Settings } from \"@api/Settings\";\nimport { Devs } from \"@utils/constants\";\nimport { ApngBlendOp, ApngDisposeOp, importApngJs } from \"@utils/dependencies\";\nimport { getCurrentGuild } from \"@utils/discord\";\nimport { Logger } from \"@utils/Logger\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { findByPropsLazy, findStoreLazy, proxyLazyWebpack } from \"@webpack\";\nimport { ChannelStore, EmojiStore, FluxDispatcher, lodash, Parser, PermissionStore, UploadHandler, UserSettingsActionCreators, UserStore } from \"@webpack/common\";\nimport type { Message } from \"discord-types/general\";\nimport { applyPalette, GIFEncoder, quantize } from \"gifenc\";\nimport type { ReactElement, ReactNode } from \"react\";\n\nconst DRAFT_TYPE = 0;\nconst StickerStore = findStoreLazy(\"StickersStore\") as {\n getPremiumPacks(): StickerPack[];\n getAllGuildStickers(): Map<string, Sticker[]>;\n getStickerById(id: string): Sticker | undefined;\n};\n\nconst UserSettingsProtoStore = findStoreLazy(\"UserSettingsProtoStore\");\nconst ProtoUtils = findByPropsLazy(\"BINARY_READ_OPTIONS\");\n\nfunction searchProtoClassField(localName: string, protoClass: any) {\n const field = protoClass?.fields?.find((field: any) => field.localName === localName);\n if (!field) return;\n\n const fieldGetter = Object.values(field).find(value => typeof value === \"function\") as any;\n return fieldGetter?.();\n}\n\nconst PreloadedUserSettingsActionCreators = proxyLazyWebpack(() => UserSettingsActionCreators.PreloadedUserSettingsActionCreators);\nconst AppearanceSettingsActionCreators = proxyLazyWebpack(() => searchProtoClassField(\"appearance\", PreloadedUserSettingsActionCreators.ProtoClass));\nconst ClientThemeSettingsActionsCreators = proxyLazyWebpack(() => searchProtoClassField(\"clientThemeSettings\", AppearanceSettingsActionCreators));\n\nconst USE_EXTERNAL_EMOJIS = 1n << 18n;\nconst USE_EXTERNAL_STICKERS = 1n << 37n;\n\nconst enum EmojiIntentions {\n REACTION = 0,\n STATUS = 1,\n COMMUNITY_CONTENT = 2,\n CHAT = 3,\n GUILD_STICKER_RELATED_EMOJI = 4,\n GUILD_ROLE_BENEFIT_EMOJI = 5,\n COMMUNITY_CONTENT_ONLY = 6,\n SOUNDBOARD = 7\n}\n\nconst enum StickerType {\n PNG = 1,\n APNG = 2,\n LOTTIE = 3,\n // don't think you can even have gif stickers but the docs have it\n GIF = 4\n}\n\ninterface BaseSticker {\n available: boolean;\n description: string;\n format_type: number;\n id: string;\n name: string;\n tags: string;\n type: number;\n}\ninterface GuildSticker extends BaseSticker {\n guild_id: string;\n}\ninterface DiscordSticker extends BaseSticker {\n pack_id: string;\n}\ntype Sticker = GuildSticker | DiscordSticker;\n\ninterface StickerPack {\n id: string;\n name: string;\n sku_id: string;\n description: string;\n cover_sticker_id: string;\n banner_asset_id: string;\n stickers: Sticker[];\n}\n\nconst enum FakeNoticeType {\n Sticker,\n Emoji\n}\n\nconst fakeNitroEmojiRegex = /\\/emojis\\/(\\d+?)\\.(png|webp|gif)/;\nconst fakeNitroStickerRegex = /\\/stickers\\/(\\d+?)\\./;\nconst fakeNitroGifStickerRegex = /\\/attachments\\/\\d+?\\/\\d+?\\/(\\d+?)\\.gif/;\n\nconst settings = definePluginSettings({\n enableEmojiBypass: {\n description: \"Allow sending fake emojis\",\n type: OptionType.BOOLEAN,\n default: true,\n restartNeeded: true\n },\n emojiSize: {\n description: \"Size of the emojis when sending\",\n type: OptionType.SLIDER,\n default: 48,\n markers: [32, 48, 64, 128, 160, 256, 512]\n },\n transformEmojis: {\n description: \"Whether to transform fake emojis into real ones\",\n type: OptionType.BOOLEAN,\n default: true,\n restartNeeded: true\n },\n enableStickerBypass: {\n description: \"Allow sending fake stickers\",\n type: OptionType.BOOLEAN,\n default: true,\n restartNeeded: true\n },\n stickerSize: {\n description: \"Size of the stickers when sending\",\n type: OptionType.SLIDER,\n default: 160,\n markers: [32, 64, 128, 160, 256, 512]\n },\n transformStickers: {\n description: \"Whether to transform fake stickers into real ones\",\n type: OptionType.BOOLEAN,\n default: true,\n restartNeeded: true\n },\n transformCompoundSentence: {\n description: \"Whether to transform fake stickers and emojis in compound sentences (sentences with more content than just the fake emoji or sticker link)\",\n type: OptionType.BOOLEAN,\n default: false\n },\n enableStreamQualityBypass: {\n description: \"Allow streaming in nitro quality\",\n type: OptionType.BOOLEAN,\n default: true,\n restartNeeded: true\n }\n});\n\nexport default definePlugin({\n name: \"FakeNitro\",\n authors: [Devs.Arjix, Devs.D3SOX, Devs.Ven, Devs.obscurity, Devs.captain, Devs.Nuckyz, Devs.AutumnVN],\n description: \"Allows you to stream in nitro quality, send fake emojis/stickers and use client themes.\",\n dependencies: [\"MessageEventsAPI\"],\n\n settings,\n\n patches: [\n {\n find: \".PREMIUM_LOCKED;\",\n predicate: () => settings.store.enableEmojiBypass,\n replacement: [\n {\n // Create a variable for the intention of listing the emoji\n match: /(?<=,intention:(\\i).+?;)/,\n replace: (_, intention) => `let fakeNitroIntention=${intention};`\n },\n {\n // Send the intention of listing the emoji to the nitro permission check functions\n match: /\\.(?:canUseEmojisEverywhere|canUseAnimatedEmojis)\\(\\i(?=\\))/g,\n replace: '$&,typeof fakeNitroIntention!==\"undefined\"?fakeNitroIntention:void 0'\n },\n {\n // Disallow the emoji if the intention doesn't allow it\n match: /(&&!\\i&&)!(\\i)(?=\\)return \\i\\.\\i\\.DISALLOW_EXTERNAL;)/,\n replace: (_, rest, canUseExternal) => `${rest}(!${canUseExternal}&&(typeof fakeNitroIntention===\"undefined\"||![${EmojiIntentions.CHAT},${EmojiIntentions.GUILD_STICKER_RELATED_EMOJI}].includes(fakeNitroIntention)))`\n },\n {\n // Make the emoji always available if the intention allows it\n match: /if\\(!\\i\\.available/,\n replace: m => `${m}&&(typeof fakeNitroIntention===\"undefined\"||![${EmojiIntentions.CHAT},${EmojiIntentions.GUILD_STICKER_RELATED_EMOJI}].includes(fakeNitroIntention))`\n }\n ]\n },\n // Allow emojis and animated emojis to be sent everywhere\n {\n find: \"canUseAnimatedEmojis:function\",\n predicate: () => settings.store.enableEmojiBypass,\n replacement: {\n match: /((?:canUseEmojisEverywhere|canUseAnimatedEmojis):function\\(\\i)\\){(.+?\\))(?=})/g,\n replace: (_, rest, premiumCheck) => `${rest},fakeNitroIntention){${premiumCheck}||fakeNitroIntention==null||[${EmojiIntentions.CHAT},${EmojiIntentions.GUILD_STICKER_RELATED_EMOJI}].includes(fakeNitroIntention)`\n }\n },\n // Allow stickers to be sent everywhere\n {\n find: \"canUseCustomStickersEverywhere:function\",\n predicate: () => settings.store.enableStickerBypass,\n replacement: {\n match: /canUseCustomStickersEverywhere:function\\(\\i\\){/,\n replace: \"$&return true;\"\n },\n },\n // Make stickers always available\n {\n find: \"\\\"SENDABLE\\\"\",\n predicate: () => settings.store.enableStickerBypass,\n replacement: {\n match: /(\\w+)\\.available\\?/,\n replace: \"true?\"\n }\n },\n // Allow streaming with high quality\n {\n find: \"canUseHighVideoUploadQuality:function\",\n predicate: () => settings.store.enableStreamQualityBypass,\n replacement: [\n \"canUseHighVideoUploadQuality\",\n \"canStreamQuality\",\n ].map(func => {\n return {\n match: new RegExp(`${func}:function\\\\(\\\\i(?:,\\\\i)?\\\\){`, \"g\"),\n replace: \"$&return true;\"\n };\n })\n },\n // Remove boost requirements to stream with high quality\n {\n find: \"STREAM_FPS_OPTION.format\",\n predicate: () => settings.store.enableStreamQualityBypass,\n replacement: {\n match: /guildPremiumTier:\\i\\.\\i\\.TIER_\\d,?/g,\n replace: \"\"\n }\n },\n // Allow client themes to be changeable\n {\n find: \"canUseClientThemes:function\",\n replacement: {\n match: /canUseClientThemes:function\\(\\i\\){/,\n replace: \"$&return true;\"\n }\n },\n {\n find: '.displayName=\"UserSettingsProtoStore\"',\n replacement: [\n {\n // Overwrite incoming connection settings proto with our local settings\n match: /CONNECTION_OPEN:function\\((\\i)\\){/,\n replace: (m, props) => `${m}$self.handleProtoChange(${props}.userSettingsProto,${props}.user);`\n },\n {\n // Overwrite non local proto changes with our local settings\n match: /let{settings:/,\n replace: \"arguments[0].local||$self.handleProtoChange(arguments[0].settings.proto);$&\"\n }\n ]\n },\n // Call our function to handle changing the gradient theme when selecting a new one\n {\n find: \",updateTheme(\",\n replacement: {\n match: /(function \\i\\(\\i\\){let{backgroundGradientPresetId:(\\i).+?)(\\i\\.\\i\\.updateAsync.+?theme=(.+?),.+?},\\i\\))/,\n replace: (_, rest, backgroundGradientPresetId, originalCall, theme) => `${rest}$self.handleGradientThemeSelect(${backgroundGradientPresetId},${theme},()=>${originalCall});`\n }\n },\n {\n find: '[\"strong\",\"em\",\"u\",\"text\",\"inlineCode\",\"s\",\"spoiler\"]',\n replacement: [\n {\n // Call our function to decide whether the emoji link should be kept or not\n predicate: () => settings.store.transformEmojis,\n match: /1!==(\\i)\\.length\\|\\|1!==\\i\\.length/,\n replace: (m, content) => `${m}||$self.shouldKeepEmojiLink(${content}[0])`\n },\n {\n // Patch the rendered message content to add fake nitro emojis or remove sticker links\n predicate: () => settings.store.transformEmojis || settings.store.transformStickers,\n match: /(?=return{hasSpoilerEmbeds:\\i,content:(\\i)})/,\n replace: (_, content) => `${content}=$self.patchFakeNitroEmojisOrRemoveStickersLinks(${content},arguments[2]?.formatInline);`\n }\n ]\n },\n {\n find: \"renderEmbeds(\",\n replacement: [\n {\n // Call our function to decide whether the embed should be ignored or not\n predicate: () => settings.store.transformEmojis || settings.store.transformStickers,\n match: /(renderEmbeds\\((\\i)\\){)(.+?embeds\\.map\\((\\i)=>{)/,\n replace: (_, rest1, message, rest2, embed) => `${rest1}const fakeNitroMessage=${message};${rest2}if($self.shouldIgnoreEmbed(${embed},fakeNitroMessage))return null;`\n },\n {\n // Patch the stickers array to add fake nitro stickers\n predicate: () => settings.store.transformStickers,\n match: /(?<=renderStickersAccessories\\((\\i)\\){let (\\i)=\\(0,\\i\\.\\i\\)\\(\\i\\).+?;)/,\n replace: (_, message, stickers) => `${stickers}=$self.patchFakeNitroStickers(${stickers},${message});`\n },\n {\n // Filter attachments to remove fake nitro stickers or emojis\n predicate: () => settings.store.transformStickers,\n match: /renderAttachments\\(\\i\\){let{attachments:(\\i).+?;/,\n replace: (m, attachments) => `${m}${attachments}=$self.filterAttachments(${attachments});`\n }\n ]\n },\n {\n find: \".Messages.STICKER_POPOUT_UNJOINED_PRIVATE_GUILD_DESCRIPTION.format\",\n predicate: () => settings.store.transformStickers,\n replacement: [\n {\n // Export the renderable sticker to be used in the fake nitro sticker notice\n match: /let{renderableSticker:(\\i).{0,250}isGuildSticker.+?channel:\\i,/,\n replace: (m, renderableSticker) => `${m}fakeNitroRenderableSticker:${renderableSticker},`\n },\n {\n // Add the fake nitro sticker notice\n match: /(let \\i,{sticker:\\i,channel:\\i,closePopout:\\i.+?}=(\\i).+?;)(.+?description:)(\\i)(?=,sticker:\\i)/,\n replace: (_, rest, props, rest2, reactNode) => `${rest}let{fakeNitroRenderableSticker}=${props};${rest2}$self.addFakeNotice(${FakeNoticeType.Sticker},${reactNode},!!fakeNitroRenderableSticker?.fake)`\n }\n ]\n },\n {\n find: \".EMOJI_UPSELL_POPOUT_MORE_EMOJIS_OPENED,\",\n predicate: () => settings.store.transformEmojis,\n replacement: {\n // Export the emoji node to be used in the fake nitro emoji notice\n match: /isDiscoverable:\\i,shouldHideRoleSubscriptionCTA:\\i,(?<={node:(\\i),.+?)/,\n replace: (m, node) => `${m}fakeNitroNode:${node},`\n }\n },\n {\n find: \".Messages.EMOJI_POPOUT_UNJOINED_DISCOVERABLE_GUILD_DESCRIPTION\",\n predicate: () => settings.store.transformEmojis,\n replacement: {\n // Add the fake nitro emoji notice\n match: /(?<=isDiscoverable:\\i,emojiComesFromCurrentGuild:\\i,.+?}=(\\i).+?;)(.+?return )(.{0,1000}\\.Messages\\.EMOJI_POPOUT_UNJOINED_DISCOVERABLE_GUILD_DESCRIPTION.+?)(?=},)/,\n replace: (_, props, rest, reactNode) => `let{fakeNitroNode}=${props};${rest}$self.addFakeNotice(${FakeNoticeType.Emoji},${reactNode},!!fakeNitroNode?.fake)`\n }\n },\n // Allow using custom app icons\n {\n find: \"canUsePremiumAppIcons:function\",\n replacement: {\n match: /canUsePremiumAppIcons:function\\(\\i\\){/,\n replace: \"$&return true;\"\n }\n },\n // Separate patch for allowing using custom app icons\n {\n find: \".FreemiumAppIconIds.DEFAULT&&(\",\n replacement: {\n match: /\\i\\.\\i\\.isPremium\\(\\i\\.\\i\\.getCurrentUser\\(\\)\\)/,\n replace: \"true\"\n }\n }\n ],\n\n get guildId() {\n return getCurrentGuild()?.id;\n },\n\n get canUseEmotes() {\n return (UserStore.getCurrentUser().premiumType ?? 0) > 0;\n },\n\n get canUseStickers() {\n return (UserStore.getCurrentUser().premiumType ?? 0) > 1;\n },\n\n handleProtoChange(proto: any, user: any) {\n if (proto == null || typeof proto === \"string\" || !UserSettingsProtoStore || !PreloadedUserSettingsActionCreators || !AppearanceSettingsActionCreators || !ClientThemeSettingsActionsCreators) return;\n\n const premiumType: number = user?.premium_type ?? UserStore?.getCurrentUser()?.premiumType ?? 0;\n\n if (premiumType !== 2) {\n proto.appearance ??= AppearanceSettingsActionCreators.create();\n\n if (UserSettingsProtoStore.settings.appearance?.theme != null) {\n const appearanceSettingsDummy = AppearanceSettingsActionCreators.create({\n theme: UserSettingsProtoStore.settings.appearance.theme\n });\n\n proto.appearance.theme = appearanceSettingsDummy.theme;\n }\n\n if (UserSettingsProtoStore.settings.appearance?.clientThemeSettings?.backgroundGradientPresetId?.value != null) {\n const clientThemeSettingsDummy = ClientThemeSettingsActionsCreators.create({\n backgroundGradientPresetId: {\n value: UserSettingsProtoStore.settings.appearance.clientThemeSettings.backgroundGradientPresetId.value\n }\n });\n\n proto.appearance.clientThemeSettings ??= clientThemeSettingsDummy;\n proto.appearance.clientThemeSettings.backgroundGradientPresetId = clientThemeSettingsDummy.backgroundGradientPresetId;\n }\n }\n },\n\n handleGradientThemeSelect(backgroundGradientPresetId: number | undefined, theme: number, original: () => void) {\n const premiumType = UserStore?.getCurrentUser()?.premiumType ?? 0;\n if (premiumType === 2 || backgroundGradientPresetId == null) return original();\n\n if (!PreloadedUserSettingsActionCreators || !AppearanceSettingsActionCreators || !ClientThemeSettingsActionsCreators || !ProtoUtils) return;\n\n const currentAppearanceSettings = PreloadedUserSettingsActionCreators.getCurrentValue().appearance;\n\n const newAppearanceProto = currentAppearanceSettings != null\n ? AppearanceSettingsActionCreators.fromBinary(AppearanceSettingsActionCreators.toBinary(currentAppearanceSettings), ProtoUtils.BINARY_READ_OPTIONS)\n : AppearanceSettingsActionCreators.create();\n\n newAppearanceProto.theme = theme;\n\n const clientThemeSettingsDummy = ClientThemeSettingsActionsCreators.create({\n backgroundGradientPresetId: {\n value: backgroundGradientPresetId\n }\n });\n\n newAppearanceProto.clientThemeSettings ??= clientThemeSettingsDummy;\n newAppearanceProto.clientThemeSettings.backgroundGradientPresetId = clientThemeSettingsDummy.backgroundGradientPresetId;\n\n const proto = PreloadedUserSettingsActionCreators.ProtoClass.create();\n proto.appearance = newAppearanceProto;\n\n FluxDispatcher.dispatch({\n type: \"USER_SETTINGS_PROTO_UPDATE\",\n local: true,\n partial: true,\n settings: {\n type: 1,\n proto\n }\n });\n },\n\n trimContent(content: Array<any>) {\n const firstContent = content[0];\n if (typeof firstContent === \"string\") content[0] = firstContent.trimStart();\n if (content[0] === \"\") content.shift();\n\n const lastIndex = content.length - 1;\n const lastContent = content[lastIndex];\n if (typeof lastContent === \"string\") content[lastIndex] = lastContent.trimEnd();\n if (content[lastIndex] === \"\") content.pop();\n },\n\n clearEmptyArrayItems(array: Array<any>) {\n return array.filter(item => item != null);\n },\n\n ensureChildrenIsArray(child: ReactElement) {\n if (!Array.isArray(child.props.children)) child.props.children = [child.props.children];\n },\n\n patchFakeNitroEmojisOrRemoveStickersLinks(content: Array<any>, inline: boolean) {\n // If content has more than one child or it's a single ReactElement like a header or list\n if ((content.length > 1 || typeof content[0]?.type === \"string\") && !settings.store.transformCompoundSentence) return content;\n\n let nextIndex = content.length;\n\n const transformLinkChild = (child: ReactElement) => {\n if (settings.store.transformEmojis) {\n const fakeNitroMatch = child.props.href.match(fakeNitroEmojiRegex);\n if (fakeNitroMatch) {\n let url: URL | null = null;\n try {\n url = new URL(child.props.href);\n } catch { }\n\n const emojiName = EmojiStore.getCustomEmojiById(fakeNitroMatch[1])?.name ?? url?.searchParams.get(\"name\") ?? \"FakeNitroEmoji\";\n\n return Parser.defaultRules.customEmoji.react({\n jumboable: !inline && content.length === 1 && typeof content[0].type !== \"string\",\n animated: fakeNitroMatch[2] === \"gif\",\n emojiId: fakeNitroMatch[1],\n name: emojiName,\n fake: true\n }, void 0, { key: String(nextIndex++) });\n }\n }\n\n if (settings.store.transformStickers) {\n if (fakeNitroStickerRegex.test(child.props.href)) return null;\n\n const gifMatch = child.props.href.match(fakeNitroGifStickerRegex);\n if (gifMatch) {\n // There is no way to differentiate a regular gif attachment from a fake nitro animated sticker, so we check if the StickerStore contains the id of the fake sticker\n if (StickerStore.getStickerById(gifMatch[1])) return null;\n }\n }\n\n return child;\n };\n\n const transformChild = (child: ReactElement) => {\n if (child?.props?.trusted != null) return transformLinkChild(child);\n if (child?.props?.children != null) {\n if (!Array.isArray(child.props.children)) {\n child.props.children = modifyChild(child.props.children);\n return child;\n }\n\n child.props.children = modifyChildren(child.props.children);\n if (child.props.children.length === 0) return null;\n return child;\n }\n\n return child;\n };\n\n const modifyChild = (child: ReactElement) => {\n const newChild = transformChild(child);\n\n if (newChild?.type === \"ul\" || newChild?.type === \"ol\") {\n this.ensureChildrenIsArray(newChild);\n if (newChild.props.children.length === 0) return null;\n\n let listHasAnItem = false;\n for (const [index, child] of newChild.props.children.entries()) {\n if (child == null) {\n delete newChild.props.children[index];\n continue;\n }\n\n this.ensureChildrenIsArray(child);\n if (child.props.children.length > 0) listHasAnItem = true;\n else delete newChild.props.children[index];\n }\n\n if (!listHasAnItem) return null;\n\n newChild.props.children = this.clearEmptyArrayItems(newChild.props.children);\n }\n\n return newChild;\n };\n\n const modifyChildren = (children: Array<ReactElement>) => {\n for (const [index, child] of children.entries()) children[index] = modifyChild(child);\n\n children = this.clearEmptyArrayItems(children);\n this.trimContent(children);\n\n return children;\n };\n\n try {\n return modifyChildren(lodash.cloneDeep(content));\n } catch (err) {\n new Logger(\"FakeNitro\").error(err);\n return content;\n }\n },\n\n patchFakeNitroStickers(stickers: Array<any>, message: Message) {\n const itemsToMaybePush: Array<string> = [];\n\n const contentItems = message.content.split(/\\s/);\n if (settings.store.transformCompoundSentence) itemsToMaybePush.push(...contentItems);\n else if (contentItems.length === 1) itemsToMaybePush.push(contentItems[0]);\n\n itemsToMaybePush.push(...message.attachments.filter(attachment => attachment.content_type === \"image/gif\").map(attachment => attachment.url));\n\n for (const item of itemsToMaybePush) {\n if (!settings.store.transformCompoundSentence && !item.startsWith(\"http\")) continue;\n\n const imgMatch = item.match(fakeNitroStickerRegex);\n if (imgMatch) {\n let url: URL | null = null;\n try {\n url = new URL(item);\n } catch { }\n\n const stickerName = StickerStore.getStickerById(imgMatch[1])?.name ?? url?.searchParams.get(\"name\") ?? \"FakeNitroSticker\";\n stickers.push({\n format_type: 1,\n id: imgMatch[1],\n name: stickerName,\n fake: true\n });\n\n continue;\n }\n\n const gifMatch = item.match(fakeNitroGifStickerRegex);\n if (gifMatch) {\n if (!StickerStore.getStickerById(gifMatch[1])) continue;\n\n const stickerName = StickerStore.getStickerById(gifMatch[1])?.name ?? \"FakeNitroSticker\";\n stickers.push({\n format_type: 2,\n id: gifMatch[1],\n name: stickerName,\n fake: true\n });\n }\n }\n\n return stickers;\n },\n\n shouldIgnoreEmbed(embed: Message[\"embeds\"][number], message: Message) {\n const contentItems = message.content.split(/\\s/);\n if (contentItems.length > 1 && !settings.store.transformCompoundSentence) return false;\n\n switch (embed.type) {\n case \"image\": {\n if (\n !settings.store.transformCompoundSentence\n && !contentItems.includes(embed.url!)\n && !contentItems.includes(embed.image?.proxyURL!)\n ) return false;\n\n if (settings.store.transformEmojis) {\n if (fakeNitroEmojiRegex.test(embed.url!)) return true;\n }\n\n if (settings.store.transformStickers) {\n if (fakeNitroStickerRegex.test(embed.url!)) return true;\n\n const gifMatch = embed.url!.match(fakeNitroGifStickerRegex);\n if (gifMatch) {\n // There is no way to differentiate a regular gif attachment from a fake nitro animated sticker, so we check if the StickerStore contains the id of the fake sticker\n if (StickerStore.getStickerById(gifMatch[1])) return true;\n }\n }\n\n break;\n }\n }\n\n return false;\n },\n\n filterAttachments(attachments: Message[\"attachments\"]) {\n return attachments.filter(attachment => {\n if (attachment.content_type !== \"image/gif\") return true;\n\n const match = attachment.url.match(fakeNitroGifStickerRegex);\n if (match) {\n // There is no way to differentiate a regular gif attachment from a fake nitro animated sticker, so we check if the StickerStore contains the id of the fake sticker\n if (StickerStore.getStickerById(match[1])) return false;\n }\n\n return true;\n });\n },\n\n shouldKeepEmojiLink(link: any) {\n return link.target && fakeNitroEmojiRegex.test(link.target);\n },\n\n addFakeNotice(type: FakeNoticeType, node: Array<ReactNode>, fake: boolean) {\n if (!fake) return node;\n\n node = Array.isArray(node) ? node : [node];\n\n switch (type) {\n case FakeNoticeType.Sticker: {\n node.push(\" This is a FakeNitro sticker and renders like a real sticker only for you. Appears as a link to non-plugin users.\");\n\n return node;\n }\n case FakeNoticeType.Emoji: {\n node.push(\" This is a FakeNitro emoji and renders like a real emoji only for you. Appears as a link to non-plugin users.\");\n\n return node;\n }\n }\n },\n\n hasPermissionToUseExternalEmojis(channelId: string): boolean {\n const channel = ChannelStore.getChannel(channelId);\n\n if (!channel || channel.isDM() || channel.isGroupDM() || channel.isMultiUserDM()) return true;\n\n return PermissionStore.can(USE_EXTERNAL_EMOJIS, channel);\n },\n\n hasPermissionToUseExternalStickers(channelId: string) {\n const channel = ChannelStore.getChannel(channelId);\n\n if (!channel || channel.isDM() || channel.isGroupDM() || channel.isMultiUserDM()) return true;\n\n return PermissionStore.can(USE_EXTERNAL_STICKERS, channel);\n },\n\n getStickerLink(stickerId: string) {\n return `https://media.discordapp.net/stickers/${stickerId}.png?size=${Settings.plugins.FakeNitro.stickerSize}`;\n },\n\n async sendAnimatedSticker(stickerLink: string, stickerId: string, channelId: string) {\n const { parseURL } = importApngJs();\n\n const { frames, width, height } = await parseURL(stickerLink);\n\n const gif = GIFEncoder();\n const resolution = Settings.plugins.FakeNitro.stickerSize;\n\n const canvas = document.createElement(\"canvas\");\n canvas.width = resolution;\n canvas.height = resolution;\n\n const ctx = canvas.getContext(\"2d\", {\n willReadFrequently: true\n })!;\n\n const scale = resolution / Math.max(width, height);\n ctx.scale(scale, scale);\n\n let previousFrameData: ImageData;\n\n for (const frame of frames) {\n const { left, top, width, height, img, delay, blendOp, disposeOp } = frame;\n\n previousFrameData = ctx.getImageData(left, top, width, height);\n\n if (blendOp === ApngBlendOp.SOURCE) {\n ctx.clearRect(left, top, width, height);\n }\n\n ctx.drawImage(img, left, top, width, height);\n\n const { data } = ctx.getImageData(0, 0, resolution, resolution);\n\n const palette = quantize(data, 256);\n const index = applyPalette(data, palette);\n\n gif.writeFrame(index, resolution, resolution, {\n transparent: true,\n palette,\n delay\n });\n\n if (disposeOp === ApngDisposeOp.BACKGROUND) {\n ctx.clearRect(left, top, width, height);\n } else if (disposeOp === ApngDisposeOp.PREVIOUS) {\n ctx.putImageData(previousFrameData, left, top);\n }\n }\n\n gif.finish();\n\n const file = new File([gif.bytesView()], `${stickerId}.gif`, { type: \"image/gif\" });\n UploadHandler.promptToUpload([file], ChannelStore.getChannel(channelId), DRAFT_TYPE);\n },\n\n start() {\n const s = settings.store;\n\n if (!s.enableEmojiBypass && !s.enableStickerBypass) {\n return;\n }\n\n function getWordBoundary(origStr: string, offset: number) {\n return (!origStr[offset] || /\\s/.test(origStr[offset])) ? \"\" : \" \";\n }\n\n this.preSend = addPreSendListener((channelId, messageObj, extra) => {\n const { guildId } = this;\n\n stickerBypass: {\n if (!s.enableStickerBypass)\n break stickerBypass;\n\n const sticker = StickerStore.getStickerById(extra.stickers?.[0]!);\n if (!sticker)\n break stickerBypass;\n\n // Discord Stickers are now free yayyy!! :D\n if (\"pack_id\" in sticker)\n break stickerBypass;\n\n const canUseStickers = this.canUseStickers && this.hasPermissionToUseExternalStickers(channelId);\n if (sticker.available !== false && (canUseStickers || sticker.guild_id === guildId))\n break stickerBypass;\n\n // [12/12/2023]\n // Work around an annoying bug where getStickerLink will return StickerType.GIF,\n // but will give us a normal non animated png for no reason\n // TODO: Remove this workaround when it's not needed anymore\n let link = this.getStickerLink(sticker.id);\n if (sticker.format_type === StickerType.GIF && link.includes(\".png\")) {\n link = link.replace(\".png\", \".gif\");\n }\n if (sticker.format_type === StickerType.APNG) {\n this.sendAnimatedSticker(link, sticker.id, channelId);\n return { cancel: true };\n } else {\n extra.stickers!.length = 0;\n messageObj.content += ` ${link}&name=${encodeURIComponent(sticker.name)}`;\n }\n }\n\n if (s.enableEmojiBypass) {\n const canUseEmotes = this.canUseEmotes && this.hasPermissionToUseExternalEmojis(channelId);\n\n for (const emoji of messageObj.validNonShortcutEmojis) {\n if (!emoji.require_colons) continue;\n if (emoji.available !== false && canUseEmotes) continue;\n if (emoji.guildId === guildId && !emoji.animated) continue;\n\n const emojiString = `<${emoji.animated ? \"a\" : \"\"}:${emoji.originalName || emoji.name}:${emoji.id}>`;\n const url = emoji.url.replace(/\\?size=\\d+/, \"?\" + new URLSearchParams({\n size: Settings.plugins.FakeNitro.emojiSize,\n name: encodeURIComponent(emoji.name)\n }));\n messageObj.content = messageObj.content.replace(emojiString, (match, offset, origStr) => {\n return `${getWordBoundary(origStr, offset - 1)}${url}${getWordBoundary(origStr, offset + match.length)}`;\n });\n }\n }\n\n return { cancel: false };\n });\n\n this.preEdit = addPreEditListener((channelId, __, messageObj) => {\n if (!s.enableEmojiBypass) return;\n\n const canUseEmotes = this.canUseEmotes && this.hasPermissionToUseExternalEmojis(channelId);\n\n const { guildId } = this;\n\n messageObj.content = messageObj.content.replace(/(?<!\\\\)<a?:(?:\\w+):(\\d+)>/ig, (emojiStr, emojiId, offset, origStr) => {\n const emoji = EmojiStore.getCustomEmojiById(emojiId);\n if (emoji == null) return emojiStr;\n if (!emoji.require_colons) return emojiStr;\n if (emoji.available !== false && canUseEmotes) return emojiStr;\n if (emoji.guildId === guildId && !emoji.animated) return emojiStr;\n\n const url = emoji.url.replace(/\\?size=\\d+/, \"?\" + new URLSearchParams({\n size: Settings.plugins.FakeNitro.emojiSize,\n name: encodeURIComponent(emoji.name)\n }));\n return `${getWordBoundary(origStr, offset - 1)}${url}${getWordBoundary(origStr, offset + emojiStr.length)}`;\n });\n });\n },\n\n stop() {\n removePreSendListener(this.preSend);\n removePreEditListener(this.preEdit);\n }\n});\n", "\"use strict\";\n/*!\n * virtual-merge\n * Copyright (c) 2023 Vendicated\n * SPDX-License-Identifier: MIT\n */\nfunction virtualMerge(...objects) {\n const fallback = {};\n function findObjectByProp(prop) {\n for (let i = objects.length - 1; i >= 0; i--) {\n if (prop in objects[i])\n return objects[i];\n }\n return fallback;\n }\n const handler = {\n ownKeys() {\n return objects.reduce((acc, obj) => {\n acc.push(...Reflect.ownKeys(obj));\n return acc;\n }, Reflect.ownKeys(fallback));\n }\n };\n for (const method of [\"defineProperty\", \"deleteProperty\", \"get\", \"getOwnPropertyDescriptor\", \"has\", \"set\"]) {\n handler[method] = function(_, ...args) {\n return Reflect[method](findObjectByProp(args[0]), ...args);\n };\n }\n return new Proxy(fallback, handler);\n}\nexport default virtualMerge;\nif (typeof module !== \"undefined\")\n module.exports = virtualMerge;\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\n// This plugin is a port from Alyxia's Vendetta plugin\nimport { definePluginSettings } from \"@api/Settings\";\nimport ErrorBoundary from \"@components/ErrorBoundary\";\nimport { Devs } from \"@utils/constants\";\nimport { Margins } from \"@utils/margins\";\nimport { copyWithToast } from \"@utils/misc\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { Button, Forms } from \"@webpack/common\";\nimport { User } from \"discord-types/general\";\nimport virtualMerge from \"virtual-merge\";\n\ninterface UserProfile extends User {\n themeColors?: Array<number>;\n}\n\ninterface Colors {\n primary: number;\n accent: number;\n}\n\nfunction encode(primary: number, accent: number): string {\n const message = `[#${primary.toString(16).padStart(6, \"0\")},#${accent.toString(16).padStart(6, \"0\")}]`;\n const padding = \"\";\n const encoded = Array.from(message)\n .map(x => x.codePointAt(0))\n .filter(x => x! >= 0x20 && x! <= 0x7f)\n .map(x => String.fromCodePoint(x! + 0xe0000))\n .join(\"\");\n\n return (padding || \"\") + \" \" + encoded;\n}\n\n// Courtesy of Cynthia.\nfunction decode(bio: string): Array<number> | null {\n if (bio == null) return null;\n\n const colorString = bio.match(\n /\\u{e005b}\\u{e0023}([\\u{e0061}-\\u{e0066}\\u{e0041}-\\u{e0046}\\u{e0030}-\\u{e0039}]+?)\\u{e002c}\\u{e0023}([\\u{e0061}-\\u{e0066}\\u{e0041}-\\u{e0046}\\u{e0030}-\\u{e0039}]+?)\\u{e005d}/u,\n );\n if (colorString != null) {\n const parsed = [...colorString[0]]\n .map(x => String.fromCodePoint(x.codePointAt(0)! - 0xe0000))\n .join(\"\");\n const colors = parsed\n .substring(1, parsed.length - 1)\n .split(\",\")\n .map(x => parseInt(x.replace(\"#\", \"0x\"), 16));\n\n return colors;\n } else {\n return null;\n }\n}\n\nconst settings = definePluginSettings({\n nitroFirst: {\n description: \"Default color source if both are present\",\n type: OptionType.SELECT,\n options: [\n { label: \"Nitro colors\", value: true, default: true },\n { label: \"Fake colors\", value: false },\n ]\n }\n});\n\nexport default definePlugin({\n name: \"FakeProfileThemes\",\n description: \"Allows profile theming by hiding the colors in your bio thanks to invisible 3y3 encoding\",\n authors: [Devs.Alyxia, Devs.Remty],\n patches: [\n {\n find: \"UserProfileStore\",\n replacement: {\n match: /(?<=getUserProfile\\(\\i\\){return )(\\i\\[\\i\\])/,\n replace: \"$self.colorDecodeHook($1)\"\n }\n }, {\n find: \".USER_SETTINGS_PROFILE_THEME_ACCENT\",\n replacement: {\n match: /RESET_PROFILE_THEME}\\)(?<=color:(\\i),.{0,500}?color:(\\i),.{0,500}?)/,\n replace: \"$&,$self.addCopy3y3Button({primary:$1,accent:$2})\"\n }\n }\n ],\n settingsAboutComponent: () => (\n <Forms.FormSection>\n <Forms.FormTitle tag=\"h3\">Usage</Forms.FormTitle>\n <Forms.FormText>\n After enabling this plugin, you will see custom colors in the profiles of other people using compatible plugins. <br />\n To set your own colors:\n <ul>\n <li>\u2022 go to your profile settings</li>\n <li>\u2022 choose your own colors in the Nitro preview</li>\n <li>\u2022 click the \"Copy 3y3\" button</li>\n <li>\u2022 paste the invisible text anywhere in your bio</li>\n </ul><br />\n <b>Please note:</b> if you are using a theme which hides nitro ads, you should disable it temporarily to set colors.\n </Forms.FormText>\n </Forms.FormSection>),\n settings,\n colorDecodeHook(user: UserProfile) {\n if (user) {\n // don't replace colors if already set with nitro\n if (settings.store.nitroFirst && user.themeColors) return user;\n const colors = decode(user.bio);\n if (colors) {\n return virtualMerge(user, {\n premiumType: 2,\n themeColors: colors\n });\n }\n }\n return user;\n },\n addCopy3y3Button: ErrorBoundary.wrap(function ({ primary, accent }: Colors) {\n return <Button\n onClick={() => {\n const colorString = encode(primary, accent);\n copyWithToast(colorString);\n }}\n color={Button.Colors.PRIMARY}\n size={Button.Sizes.XLARGE}\n className={Margins.left16}\n >Copy 3y3\n </Button >;\n }, { noop: true }),\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\nimport { EmojiStore } from \"@webpack/common\";\nimport { Emoji } from \"@webpack/types\";\n\ninterface EmojiAutocompleteState {\n query?: {\n type: string;\n typeInfo: {\n sentinel: string;\n };\n results: {\n emojis: Emoji[] & { sliceTo?: number; };\n };\n };\n}\n\nexport default definePlugin({\n name: \"FavoriteEmojiFirst\",\n authors: [Devs.Aria, Devs.Ven],\n description: \"Puts your favorite emoji first in the emoji autocomplete.\",\n patches: [\n {\n find: \"renderResults({results:\",\n replacement: [\n {\n // https://regex101.com/r/N7kpLM/1\n match: /let \\i=.{1,100}renderResults\\({results:(\\i)\\.query\\.results,/,\n replace: \"$self.sortEmojis($1);$&\"\n },\n ],\n },\n\n {\n find: \"MAX_AUTOCOMPLETE_RESULTS+\",\n replacement: [\n // set maxCount to Infinity so our sortEmojis callback gets the entire list, not just the first 10\n // and remove Discord's emojiResult slice, storing the endIndex on the array for us to use later\n {\n // https://regex101.com/r/x2mobQ/1\n // searchEmojis(...,maxCount: stuff) ... endEmojis = emojis.slice(0, maxCount - gifResults.length)\n match: /,maxCount:(\\i)(.{1,500}\\i)=(\\i)\\.slice\\(0,(\\i-\\i\\.length)\\)/,\n // ,maxCount:Infinity ... endEmojis = (emojis.sliceTo = n, emojis)\n replace: \",maxCount:Infinity$2=($3.sliceTo = $4, $3)\"\n }\n ]\n }\n ],\n\n sortEmojis({ query }: EmojiAutocompleteState) {\n if (\n query?.type !== \"EMOJIS_AND_STICKERS\"\n || query.typeInfo?.sentinel !== \":\"\n || !query.results?.emojis?.length\n ) return;\n\n const emojiContext = EmojiStore.getDisambiguatedEmojiContext();\n\n query.results.emojis = query.results.emojis.sort((a, b) => {\n const aIsFavorite = emojiContext.isFavoriteEmojiWithoutFetchingLatest(a);\n const bIsFavorite = emojiContext.isFavoriteEmojiWithoutFetchingLatest(b);\n\n if (aIsFavorite && !bIsFavorite) return -1;\n\n if (!aIsFavorite && bIsFavorite) return 1;\n\n return 0;\n }).slice(0, query.results.emojis.sliceTo ?? 10);\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { definePluginSettings } from \"@api/Settings\";\nimport ErrorBoundary from \"@components/ErrorBoundary\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { findByPropsLazy } from \"@webpack\";\nimport { useCallback, useEffect, useRef, useState } from \"@webpack/common\";\n\ninterface SearchBarComponentProps {\n ref?: React.MutableRefObject<any>;\n autoFocus: boolean;\n className: string;\n size: string;\n onChange: (query: string) => void;\n onClear: () => void;\n query: string;\n placeholder: string;\n}\n\ntype TSearchBarComponent =\n React.FC<SearchBarComponentProps> & { Sizes: Record<\"SMALL\" | \"MEDIUM\" | \"LARGE\", string>; };\n\ninterface Gif {\n format: number;\n src: string;\n width: number;\n height: number;\n order: number;\n url: string;\n}\n\ninterface Instance {\n dead?: boolean;\n state: {\n resultType?: string;\n };\n props: {\n favCopy: Gif[],\n\n favorites: Gif[],\n },\n forceUpdate: () => void;\n}\n\n\nconst containerClasses: { searchBar: string; } = findByPropsLazy(\"searchBar\", \"searchBarFullRow\");\n\nexport const settings = definePluginSettings({\n searchOption: {\n type: OptionType.SELECT,\n description: \"The part of the url you want to search\",\n options: [\n {\n label: \"Entire Url\",\n value: \"url\"\n },\n {\n label: \"Path Only (/somegif.gif)\",\n value: \"path\"\n },\n {\n label: \"Host & Path (tenor.com somgif.gif)\",\n value: \"hostandpath\",\n default: true\n }\n ] as const\n }\n});\n\nexport default definePlugin({\n name: \"FavoriteGifSearch\",\n authors: [Devs.Aria],\n description: \"Adds a search bar to favorite gifs.\",\n\n patches: [\n {\n find: \"renderHeaderContent()\",\n replacement: [\n {\n // https://regex101.com/r/07gpzP/1\n // ($1 renderHeaderContent=function { ... switch (x) ... case FAVORITES:return) ($2) ($3 case default:return r.jsx(($<searchComp>), {...props}))\n match: /(renderHeaderContent\\(\\).{1,150}FAVORITES:return)(.{1,150});(case.{1,200}default:return\\(0,\\i\\.jsx\\)\\((?<searchComp>\\i\\..{1,10}),)/,\n replace: \"$1 this.state.resultType === 'Favorites' ? $self.renderSearchBar(this, $<searchComp>) : $2;$3\"\n },\n {\n // to persist filtered favorites when component re-renders.\n // when resizing the window the component rerenders and we loose the filtered favorites and have to type in the search bar to get them again\n match: /(,suggestions:\\i,favorites:)(\\i),/,\n replace: \"$1$self.getFav($2),favCopy:$2,\"\n }\n\n ]\n }\n ],\n\n settings,\n\n getTargetString,\n\n instance: null as Instance | null,\n renderSearchBar(instance: Instance, SearchBarComponent: TSearchBarComponent) {\n this.instance = instance;\n return (\n <ErrorBoundary noop={true}>\n <SearchBar instance={instance} SearchBarComponent={SearchBarComponent} />\n </ErrorBoundary>\n );\n },\n\n getFav(favorites: Gif[]) {\n if (!this.instance || this.instance.dead) return favorites;\n const { favorites: filteredFavorites } = this.instance.props;\n\n return filteredFavorites != null && filteredFavorites?.length !== favorites.length ? filteredFavorites : favorites;\n\n }\n});\n\n\nfunction SearchBar({ instance, SearchBarComponent }: { instance: Instance; SearchBarComponent: TSearchBarComponent; }) {\n const [query, setQuery] = useState(\"\");\n const ref = useRef<{ containerRef?: React.MutableRefObject<HTMLDivElement>; } | null>(null);\n\n const onChange = useCallback((searchQuery: string) => {\n setQuery(searchQuery);\n const { props } = instance;\n\n // return early\n if (searchQuery === \"\") {\n props.favorites = props.favCopy;\n instance.forceUpdate();\n return;\n }\n\n\n // scroll back to top\n ref.current?.containerRef?.current\n .closest(\"#gif-picker-tab-panel\")\n ?.querySelector(\"[class|=\\\"content\\\"]\")\n ?.firstElementChild?.scrollTo(0, 0);\n\n\n const result =\n props.favCopy\n .map(gif => ({\n score: fuzzySearch(searchQuery.toLowerCase(), getTargetString(gif.url ?? gif.src).replace(/(%20|[_-])/g, \" \").toLowerCase()),\n gif,\n }))\n .filter(m => m.score != null) as { score: number; gif: Gif; }[];\n\n result.sort((a, b) => b.score - a.score);\n props.favorites = result.map(e => e.gif);\n\n instance.forceUpdate();\n }, [instance.state]);\n\n useEffect(() => {\n return () => {\n instance.dead = true;\n };\n }, []);\n\n return (\n <SearchBarComponent\n ref={ref}\n autoFocus={true}\n className={containerClasses.searchBar}\n size={SearchBarComponent.Sizes.MEDIUM}\n onChange={onChange}\n onClear={() => {\n setQuery(\"\");\n if (instance.props.favCopy != null) {\n instance.props.favorites = instance.props.favCopy;\n instance.forceUpdate();\n }\n }}\n query={query}\n placeholder=\"Search Favorite Gifs\"\n />\n );\n}\n\n\n\nexport function getTargetString(urlStr: string) {\n const url = new URL(urlStr);\n switch (settings.store.searchOption) {\n case \"url\":\n return url.href;\n case \"path\":\n if (url.host === \"media.discordapp.net\" || url.host === \"tenor.com\")\n // /attachments/899763415290097664/1095711736461537381/attachment-1.gif -> attachment-1.gif\n // /view/some-gif-hi-24248063 -> some-gif-hi-24248063\n return url.pathname.split(\"/\").at(-1) ?? url.pathname;\n return url.pathname;\n case \"hostandpath\":\n if (url.host === \"media.discordapp.net\" || url.host === \"tenor.com\")\n return `${url.host} ${url.pathname.split(\"/\").at(-1) ?? url.pathname}`;\n return `${url.host} ${url.pathname}`;\n\n default:\n return \"\";\n }\n}\n\nfunction fuzzySearch(searchQuery: string, searchString: string) {\n let searchIndex = 0;\n let score = 0;\n\n for (let i = 0; i < searchString.length; i++) {\n if (searchString[i] === searchQuery[searchIndex]) {\n score++;\n searchIndex++;\n } else {\n score--;\n }\n\n if (searchIndex === searchQuery.length) {\n return score;\n }\n }\n\n return null;\n}\n", "/*\n * Vencord, a Discord client mod\n * Copyright (c) 2023 Vendicated and contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport { definePluginSettings } from \"@api/Settings\";\nimport { makeRange } from \"@components/PluginSettings/components\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin, { OptionType } from \"@utils/types\";\n\n// The entire code of this plugin can be found in ipcPlugins\nexport default definePlugin({\n name: \"FixSpotifyEmbeds\",\n description: \"Fixes spotify embeds being incredibly loud by letting you customise the volume\",\n authors: [Devs.Ven],\n settings: definePluginSettings({\n volume: {\n type: OptionType.SLIDER,\n description: \"The volume % to set for spotify embeds. Anything above 10% is veeeery loud\",\n markers: makeRange(0, 100, 10),\n stickToMarkers: false,\n default: 10\n }\n })\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\nimport { GuildStore } from \"@webpack/common\";\nimport { Channel, User } from \"discord-types/general\";\n\nexport default definePlugin({\n name: \"ForceOwnerCrown\",\n description: \"Force the owner crown next to usernames even if the server is large.\",\n authors: [Devs.D3SOX, Devs.Nickyux],\n patches: [\n {\n find: \"AVATAR_DECORATION_PADDING:\",\n replacement: {\n match: /,isOwner:(\\i),/,\n replace: \",_isOwner:$1=$self.isGuildOwner(e),\"\n }\n }\n ],\n isGuildOwner(props: { user: User, channel: Channel, isOwner: boolean, guildId?: string; }) {\n if (!props?.user?.id) return props.isOwner;\n if (props.channel?.type === 3 /* GROUP_DM */)\n return props.isOwner;\n\n // guild id is in props twice, fallback if the first is undefined\n const guildId = props.guildId ?? props.channel?.guild_id;\n const userId = props.user.id;\n\n return GuildStore.getGuild(guildId)?.ownerId === userId;\n },\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { ApplicationCommandInputType, ApplicationCommandOptionType, findOption, sendBotMessage } from \"@api/Commands\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\nimport { findByPropsLazy } from \"@webpack\";\nimport { RestAPI, UserStore } from \"@webpack/common\";\n\nconst FriendInvites = findByPropsLazy(\"createFriendInvite\");\nconst { uuid4 } = findByPropsLazy(\"uuid4\");\n\nexport default definePlugin({\n name: \"FriendInvites\",\n description: \"Create and manage friend invite links via slash commands (/create friend invite, /view friend invites, /revoke friend invites).\",\n authors: [Devs.afn, Devs.Dziurwa],\n dependencies: [\"CommandsAPI\"],\n commands: [\n {\n name: \"create friend invite\",\n description: \"Generates a friend invite link.\",\n inputType: ApplicationCommandInputType.BOT,\n options: [{\n name: \"Uses\",\n description: \"How many uses?\",\n choices: [\n { label: \"1\", name: \"1\", value: \"1\" },\n { label: \"5\", name: \"5\", value: \"5\" }\n ],\n required: false,\n type: ApplicationCommandOptionType.INTEGER\n }],\n\n execute: async (args, ctx) => {\n const uses = findOption<number>(args, \"Uses\", 5);\n\n if (uses === 1 && !UserStore.getCurrentUser().phone)\n return sendBotMessage(ctx.channel.id, {\n content: \"You need to have a phone number connected to your account to create a friend invite with 1 use!\"\n });\n\n let invite: any;\n if (uses === 1) {\n const random = uuid4();\n const { body: { invite_suggestions } } = await RestAPI.post({\n url: \"/friend-finder/find-friends\",\n body: {\n modified_contacts: {\n [random]: [1, \"\", \"\"]\n },\n phone_contact_methods_count: 1\n }\n });\n invite = await FriendInvites.createFriendInvite({\n code: invite_suggestions[0][3],\n recipient_phone_number_or_email: random,\n contact_visibility: 1,\n filter_visibilities: [],\n filtered_invite_suggestions_index: 1\n });\n } else {\n invite = await FriendInvites.createFriendInvite();\n }\n\n sendBotMessage(ctx.channel.id, {\n content: `\n discord.gg/${invite.code} \u00B7\n Expires: <t:${new Date(invite.expires_at).getTime() / 1000}:R> \u00B7\n Max uses: \\`${invite.max_uses}\\`\n `.trim().replace(/\\s+/g, \" \")\n });\n }\n },\n {\n name: \"view friend invites\",\n description: \"View a list of all generated friend invites.\",\n inputType: ApplicationCommandInputType.BOT,\n execute: async (_, ctx) => {\n const invites = await FriendInvites.getAllFriendInvites();\n const friendInviteList = invites.map(i =>\n `\n _discord.gg/${i.code}_ \u00B7\n Expires: <t:${new Date(i.expires_at).getTime() / 1000}:R> \u00B7\n Times used: \\`${i.uses}/${i.max_uses}\\`\n `.trim().replace(/\\s+/g, \" \")\n );\n\n sendBotMessage(ctx.channel.id, {\n content: friendInviteList.join(\"\\n\") || \"You have no active friend invites!\"\n });\n },\n },\n {\n name: \"revoke friend invites\",\n description: \"Revokes all generated friend invites.\",\n inputType: ApplicationCommandInputType.BOT,\n execute: async (_, ctx) => {\n await FriendInvites.revokeFriendInvites();\n\n sendBotMessage(ctx.channel.id, {\n content: \"All friend invites have been revoked.\"\n });\n },\n },\n ]\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\n(window.VencordStyles ??= new Map()).set(\"src/plugins/gameActivityToggle/style.css\", {\n name: \"src/plugins/gameActivityToggle/style.css\",\n source: \"[class*=\\\"withTagAsButton\\\"] {\\n min-width: 88px !important;\\n}\\n\",\n classNames: {},\n dom: null,\n});\n\nexport default \"src/plugins/gameActivityToggle/style.css\";\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { definePluginSettings } from \"@api/Settings\";\nimport { disableStyle, enableStyle } from \"@api/Styles\";\nimport ErrorBoundary from \"@components/ErrorBoundary\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { findComponentByCodeLazy } from \"@webpack\";\nimport { StatusSettingsStores } from \"@webpack/common\";\n\nimport style from \"./style.css?managed\";\n\nconst Button = findComponentByCodeLazy(\"Button.Sizes.NONE,disabled:\");\n\nfunction makeIcon(showCurrentGame?: boolean) {\n const { oldIcon } = settings.use([\"oldIcon\"]);\n\n const redLinePath = !oldIcon\n ? \"M22.7 2.7a1 1 0 0 0-1.4-1.4l-20 20a1 1 0 1 0 1.4 1.4Z\"\n : \"M23 2.27 21.73 1 1 21.73 2.27 23 23 2.27Z\";\n\n const maskBlackPath = !oldIcon\n ? \"M23.27 4.73 19.27 .73 -.27 20.27 3.73 24.27Z\"\n : \"M23.27 4.54 19.46.73 .73 19.46 4.54 23.27 23.27 4.54Z\";\n\n return function () {\n return (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\">\n <path\n fill={!showCurrentGame && !oldIcon ? \"var(--status-danger)\" : \"currentColor\"}\n mask={!showCurrentGame ? \"url(#gameActivityMask)\" : void 0}\n d=\"M3.06 20.4q-1.53 0-2.37-1.065T.06 16.74l1.26-9q.27-1.8 1.605-2.97T6.06 3.6h11.88q1.8 0 3.135 1.17t1.605 2.97l1.26 9q.21 1.53-.63 2.595T20.94 20.4q-.63 0-1.17-.225T18.78 19.5l-2.7-2.7H7.92l-2.7 2.7q-.45.45-.99.675t-1.17.225Zm14.94-7.2q.51 0 .855-.345T19.2 12q0-.51-.345-.855T18 10.8q-.51 0-.855.345T16.8 12q0 .51.345 .855T18 13.2Zm-2.4-3.6q.51 0 .855-.345T16.8 8.4q0-.51-.345-.855T15.6 7.2q-.51 0-.855.345T14.4 8.4q0 .51.345 .855T15.6 9.6ZM6.9 13.2h1.8v-2.1h2.1v-1.8h-2.1v-2.1h-1.8v2.1h-2.1v1.8h2.1v2.1Z\"\n />\n {!showCurrentGame && <>\n <path fill=\"var(--status-danger)\" d={redLinePath} />\n <mask id=\"gameActivityMask\">\n <rect fill=\"white\" x=\"0\" y=\"0\" width=\"24\" height=\"24\" />\n <path fill=\"black\" d={maskBlackPath} />\n </mask>\n </>}\n </svg>\n );\n };\n}\n\nfunction GameActivityToggleButton() {\n const showCurrentGame = StatusSettingsStores.ShowCurrentGame.useSetting();\n\n return (\n <Button\n tooltipText={showCurrentGame ? \"Disable Game Activity\" : \"Enable Game Activity\"}\n icon={makeIcon(showCurrentGame)}\n role=\"switch\"\n aria-checked={!showCurrentGame}\n onClick={() => StatusSettingsStores.ShowCurrentGame.updateSetting(old => !old)}\n />\n );\n}\n\nconst settings = definePluginSettings({\n oldIcon: {\n type: OptionType.BOOLEAN,\n description: \"Use the old icon style before Discord icon redesign\",\n default: false\n }\n});\n\nexport default definePlugin({\n name: \"GameActivityToggle\",\n description: \"Adds a button next to the mic and deafen button to toggle game activity.\",\n authors: [Devs.Nuckyz, Devs.RuukuLada],\n settings,\n\n patches: [\n {\n find: \".Messages.ACCOUNT_SPEAKING_WHILE_MUTED\",\n replacement: {\n match: /this\\.renderNameZone\\(\\).+?children:\\[/,\n replace: \"$&$self.GameActivityToggleButton(),\"\n }\n }\n ],\n\n GameActivityToggleButton: ErrorBoundary.wrap(GameActivityToggleButton, { noop: true }),\n\n start() {\n enableStyle(style);\n },\n\n stop() {\n disableStyle(style);\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Devs } from \"@utils/constants\";\nimport { insertTextIntoChatInputBox } from \"@utils/discord\";\nimport definePlugin from \"@utils/types\";\nimport { findByPropsLazy } from \"@webpack\";\n\nconst { closeExpressionPicker } = findByPropsLazy(\"closeExpressionPicker\");\n\nexport default definePlugin({\n name: \"GifPaste\",\n description: \"Makes picking a gif in the gif picker insert a link into the chatbox instead of instantly sending it\",\n authors: [Devs.Ven],\n\n patches: [{\n find: \".handleSelectGIF=\",\n replacement: {\n match: /\\.handleSelectGIF=(\\i)=>\\{/,\n replace: \".handleSelectGIF=$1=>{if (!this.props.className) return $self.handleSelect($1);\"\n }\n }],\n\n handleSelect(gif?: { url: string; }) {\n if (gif) {\n insertTextIntoChatInputBox(gif.url + \" \");\n closeExpressionPicker();\n }\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { definePluginSettings } from \"@api/Settings\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { findByPropsLazy } from \"@webpack\";\nimport { ContextMenuApi, FluxDispatcher, Menu, MessageActions } from \"@webpack/common\";\nimport { Channel, Message } from \"discord-types/general\";\n\ninterface Sticker {\n id: string;\n format_type: number;\n description: string;\n name: string;\n}\n\nenum GreetMode {\n Greet = \"Greet\",\n NormalMessage = \"Message\"\n}\n\nconst settings = definePluginSettings({\n greetMode: {\n type: OptionType.SELECT,\n options: [\n { label: \"Greet (you can only greet 3 times)\", value: GreetMode.Greet, default: true },\n { label: \"Normal Message (you can greet spam)\", value: GreetMode.NormalMessage }\n ],\n description: \"Choose the greet mode\"\n }\n}).withPrivateSettings<{\n multiGreetChoices?: string[];\n unholyMultiGreetEnabled?: boolean;\n}>();\n\nconst { WELCOME_STICKERS } = findByPropsLazy(\"WELCOME_STICKERS\");\n\nfunction greet(channel: Channel, message: Message, stickers: string[]) {\n const options = MessageActions.getSendMessageOptionsForReply({\n channel,\n message,\n shouldMention: true,\n showMentionToggle: true\n });\n\n if (settings.store.greetMode === GreetMode.NormalMessage || stickers.length > 1) {\n options.stickerIds = stickers;\n const msg = {\n content: \"\",\n tts: false,\n invalidEmojis: [],\n validNonShortcutEmojis: []\n };\n\n MessageActions._sendMessage(channel.id, msg, options);\n } else {\n MessageActions.sendGreetMessage(channel.id, stickers[0], options);\n }\n}\n\n\nfunction GreetMenu({ channel, message }: { message: Message, channel: Channel; }) {\n const s = settings.use([\"greetMode\", \"multiGreetChoices\"]);\n const { greetMode, multiGreetChoices = [] } = s;\n\n return (\n <Menu.Menu\n navId=\"greet-sticker-picker\"\n onClose={() => FluxDispatcher.dispatch({ type: \"CONTEXT_MENU_CLOSE\" })}\n aria-label=\"Greet Sticker Picker\"\n >\n <Menu.MenuGroup\n label=\"Greet Mode\"\n >\n {Object.values(GreetMode).map(mode => (\n <Menu.MenuRadioItem\n key={mode}\n group=\"greet-mode\"\n id={\"greet-mode-\" + mode}\n label={mode}\n checked={mode === greetMode}\n action={() => s.greetMode = mode}\n />\n ))}\n </Menu.MenuGroup>\n\n <Menu.MenuSeparator />\n\n <Menu.MenuGroup\n label=\"Greet Stickers\"\n >\n {WELCOME_STICKERS.map(sticker => (\n <Menu.MenuItem\n key={sticker.id}\n id={\"greet-\" + sticker.id}\n label={sticker.description.split(\" \")[0]}\n action={() => greet(channel, message, [sticker.id])}\n />\n ))}\n </Menu.MenuGroup>\n\n {!settings.store.unholyMultiGreetEnabled ? null : (\n <>\n <Menu.MenuSeparator />\n\n <Menu.MenuItem\n label=\"Unholy Multi-Greet\"\n id=\"unholy-multi-greet\"\n >\n {WELCOME_STICKERS.map(sticker => {\n const checked = multiGreetChoices.some(s => s === sticker.id);\n\n return (\n <Menu.MenuCheckboxItem\n key={sticker.id}\n id={\"multi-greet-\" + sticker.id}\n label={sticker.description.split(\" \")[0]}\n checked={checked}\n disabled={!checked && multiGreetChoices.length >= 3}\n action={() => {\n s.multiGreetChoices = checked\n ? multiGreetChoices.filter(s => s !== sticker.id)\n : [...multiGreetChoices, sticker.id];\n }}\n />\n );\n })}\n\n <Menu.MenuSeparator />\n <Menu.MenuItem\n id=\"multi-greet-submit\"\n label=\"Send Greets\"\n action={() => greet(channel, message, multiGreetChoices!)}\n disabled={multiGreetChoices.length === 0}\n />\n\n </Menu.MenuItem>\n </>\n )}\n </Menu.Menu>\n );\n}\n\nexport default definePlugin({\n name: \"GreetStickerPicker\",\n description: \"Allows you to use any greet sticker instead of only the random one by right-clicking the 'Wave to say hi!' button\",\n authors: [Devs.Ven],\n\n settings,\n\n patches: [\n {\n find: \"Messages.WELCOME_CTA_LABEL\",\n replacement: {\n match: /innerClassName:\\i\\.welcomeCTAButton,(?<={channel:\\i,message:\\i}=(\\i).{0,400}?)/,\n replace: \"$&onContextMenu:(vcEvent)=>$self.pickSticker(vcEvent, $1),\"\n }\n }\n ],\n\n pickSticker(\n event: React.UIEvent,\n props: {\n channel: Channel,\n message: Message;\n }\n ) {\n if (!(props.message as any).deleted)\n ContextMenuApi.openContextMenu(event, () => <GreetMenu {...props} />);\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Logger } from \"@utils/Logger\";\nimport { Channel, Message } from \"discord-types/general\";\nimport type { MouseEventHandler } from \"react\";\n\nconst logger = new Logger(\"MessagePopover\");\n\nexport interface ButtonItem {\n key?: string,\n label: string,\n icon: React.ComponentType<any>,\n message: Message,\n channel: Channel,\n onClick?: MouseEventHandler<HTMLButtonElement>,\n onContextMenu?: MouseEventHandler<HTMLButtonElement>;\n}\n\nexport type getButtonItem = (message: Message) => ButtonItem | null;\n\nexport const buttons = new Map<string, getButtonItem>();\n\nexport function addButton(\n identifier: string,\n item: getButtonItem,\n) {\n buttons.set(identifier, item);\n}\n\nexport function removeButton(identifier: string) {\n buttons.delete(identifier);\n}\n\nexport function _buildPopoverElements(\n msg: Message,\n makeButton: (item: ButtonItem) => React.ComponentType\n) {\n const items = [] as React.ComponentType[];\n\n for (const [identifier, getItem] of buttons.entries()) {\n try {\n const item = getItem(msg);\n if (item) {\n item.key ??= identifier;\n items.push(makeButton(item));\n }\n } catch (err) {\n logger.error(`[${identifier}]`, err);\n }\n }\n\n return items;\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { get, set } from \"@api/DataStore\";\nimport { addButton, removeButton } from \"@api/MessagePopover\";\nimport { ImageInvisible, ImageVisible } from \"@components/Icons\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\nimport { ChannelStore } from \"@webpack/common\";\n\nlet style: HTMLStyleElement;\n\nconst KEY = \"HideAttachments_HiddenIds\";\n\nlet hiddenMessages: Set<string> = new Set();\nconst getHiddenMessages = () => get(KEY).then(set => {\n hiddenMessages = set ?? new Set<string>();\n return hiddenMessages;\n});\nconst saveHiddenMessages = (ids: Set<string>) => set(KEY, ids);\n\nexport default definePlugin({\n name: \"HideAttachments\",\n description: \"Hide attachments and Embeds for individual messages via hover button\",\n authors: [Devs.Ven],\n dependencies: [\"MessagePopoverAPI\"],\n\n async start() {\n style = document.createElement(\"style\");\n style.id = \"VencordHideAttachments\";\n document.head.appendChild(style);\n\n await getHiddenMessages();\n await this.buildCss();\n\n addButton(\"HideAttachments\", msg => {\n if (!msg.attachments.length && !msg.embeds.length && !msg.stickerItems.length) return null;\n\n const isHidden = hiddenMessages.has(msg.id);\n\n return {\n label: isHidden ? \"Show Attachments\" : \"Hide Attachments\",\n icon: isHidden ? ImageVisible : ImageInvisible,\n message: msg,\n channel: ChannelStore.getChannel(msg.channel_id),\n onClick: () => this.toggleHide(msg.id)\n };\n });\n },\n\n stop() {\n style.remove();\n hiddenMessages.clear();\n removeButton(\"HideAttachments\");\n },\n\n async buildCss() {\n const elements = [...hiddenMessages].map(id => `#message-accessories-${id}`).join(\",\");\n style.textContent = `\n :is(${elements}) :is([class*=\"embedWrapper\"], [class*=\"clickableSticker\"]) {\n /* important is not necessary, but add it to make sure bad themes won't break it */\n display: none !important;\n }\n :is(${elements})::after {\n content: \"Attachments hidden\";\n color: var(--text-muted);\n font-size: 80%;\n }\n `;\n },\n\n async toggleHide(id: string) {\n const ids = await getHiddenMessages();\n if (!ids.delete(id))\n ids.add(id);\n\n await saveHiddenMessages(ids);\n await this.buildCss();\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\n\nexport default definePlugin({\n name: \"iLoveSpam\",\n description: \"Do not hide messages from 'likely spammers'\",\n authors: [Devs.botato, Devs.Nyako],\n patches: [\n {\n find: \"hasFlag:{writable\",\n replacement: {\n match: /if\\((\\i)<=(?:1<<30|1073741824)\\)return/,\n replace: \"if($1===(1<<20))return false;$&\",\n },\n },\n ],\n});\n", "/*\n * Vencord, a Discord client mod\n * Copyright (c) 2023 Vendicated and contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport * as DataStore from \"@api/DataStore\";\nimport { definePluginSettings } from \"@api/Settings\";\nimport ErrorBoundary from \"@components/ErrorBoundary\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\nimport { findStoreLazy } from \"@webpack\";\nimport { StatusSettingsStores, Tooltip } from \"webpack/common\";\n\nconst enum ActivitiesTypes {\n Game,\n Embedded\n}\n\ninterface IgnoredActivity {\n id: string;\n name: string;\n type: ActivitiesTypes;\n}\n\nconst RunningGameStore = findStoreLazy(\"RunningGameStore\");\n\nfunction ToggleIcon(activity: IgnoredActivity, tooltipText: string, path: string, fill: string) {\n return (\n <Tooltip text={tooltipText}>\n {tooltipProps => (\n <button\n {...tooltipProps}\n onClick={e => handleActivityToggle(e, activity)}\n style={{ all: \"unset\", cursor: \"pointer\", display: \"flex\", justifyContent: \"center\", alignItems: \"center\" }}\n >\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 -960 960 960\"\n >\n <path fill={fill} d={path} />\n </svg>\n </button>\n )}\n </Tooltip>\n );\n}\n\nconst ToggleIconOn = (activity: IgnoredActivity, fill: string) => ToggleIcon(activity, \"Disable Activity\", \"M480-320q75 0 127.5-52.5T660-500q0-75-52.5-127.5T480-680q-75 0-127.5 52.5T300-500q0 75 52.5 127.5T480-320Zm0-72q-45 0-76.5-31.5T372-500q0-45 31.5-76.5T480-608q45 0 76.5 31.5T588-500q0 45-31.5 76.5T480-392Zm0 192q-146 0-266-81.5T40-500q54-137 174-218.5T480-800q146 0 266 81.5T920-500q-54 137-174 218.5T480-200Zm0-300Zm0 220q113 0 207.5-59.5T832-500q-50-101-144.5-160.5T480-720q-113 0-207.5 59.5T128-500q50 101 144.5 160.5T480-280Z\", fill);\nconst ToggleIconOff = (activity: IgnoredActivity, fill: string) => ToggleIcon(activity, \"Enable Activity\", \"m644-428-58-58q9-47-27-88t-93-32l-58-58q17-8 34.5-12t37.5-4q75 0 127.5 52.5T660-500q0 20-4 37.5T644-428Zm128 126-58-56q38-29 67.5-63.5T832-500q-50-101-143.5-160.5T480-720q-29 0-57 4t-55 12l-62-62q41-17 84-25.5t90-8.5q151 0 269 83.5T920-500q-23 59-60.5 109.5T772-302Zm20 246L624-222q-35 11-70.5 16.5T480-200q-151 0-269-83.5T40-500q21-53 53-98.5t73-81.5L56-792l56-56 736 736-56 56ZM222-624q-29 26-53 57t-41 67q50 101 143.5 160.5T480-280q20 0 39-2.5t39-5.5l-36-38q-11 3-21 4.5t-21 1.5q-75 0-127.5-52.5T300-500q0-11 1.5-21t4.5-21l-84-82Zm319 93Zm-151 75Z\", fill);\n\nfunction ToggleActivityComponent(activity: IgnoredActivity, isPlaying = false) {\n const s = settings.use([\"ignoredActivities\"]);\n const { ignoredActivities = [] } = s;\n\n if (ignoredActivities.some(act => act.id === activity.id)) return ToggleIconOff(activity, \"var(--status-danger)\");\n return ToggleIconOn(activity, isPlaying ? \"var(--green-300)\" : \"var(--primary-400)\");\n}\n\nfunction handleActivityToggle(e: React.MouseEvent<HTMLButtonElement, MouseEvent>, activity: IgnoredActivity) {\n e.stopPropagation();\n\n const ignoredActivityIndex = getIgnoredActivities().findIndex(act => act.id === activity.id);\n if (ignoredActivityIndex === -1) settings.store.ignoredActivities = getIgnoredActivities().concat(activity);\n else settings.store.ignoredActivities = getIgnoredActivities().filter((_, index) => index !== ignoredActivityIndex);\n\n // Trigger activities recalculation\n StatusSettingsStores.ShowCurrentGame.updateSetting(old => old);\n}\n\nconst settings = definePluginSettings({}).withPrivateSettings<{\n ignoredActivities: IgnoredActivity[];\n}>();\n\nfunction getIgnoredActivities() {\n return settings.store.ignoredActivities ??= [];\n}\n\nexport default definePlugin({\n name: \"IgnoreActivities\",\n authors: [Devs.Nuckyz],\n description: \"Ignore activities from showing up on your status ONLY. You can configure which ones are ignored from the Registered Games and Activities tabs.\",\n\n settings,\n\n patches: [\n {\n find: '.displayName=\"LocalActivityStore\"',\n replacement: [\n {\n match: /HANG_STATUS.+?(?=!\\i\\(\\i,\\i\\)&&)(?<=(\\i)\\.push.+?)/,\n replace: (m, activities) => `${m}${activities}=${activities}.filter($self.isActivityNotIgnored);`\n }\n ]\n },\n {\n find: \".Messages.SETTINGS_GAMES_TOGGLE_OVERLAY\",\n replacement: {\n match: /\\.Messages\\.SETTINGS_GAMES_TOGGLE_OVERLAY.+?}\\(\\),(?<={overlay:\\i,.+?=(\\i),.+?)(?=!(\\i))/,\n replace: (m, props, nowPlaying) => `${m}$self.renderToggleGameActivityButton(${props},${nowPlaying}),`\n }\n },\n {\n find: \".activityTitleText,variant\",\n replacement: {\n match: /(?<=\\i\\.activityTitleText.+?children:(\\i)\\.name.*?}\\),)/,\n replace: (_, props) => `$self.renderToggleActivityButton(${props}),`\n },\n },\n {\n find: \".activityCardDetails,children\",\n replacement: {\n match: /(?<=\\i\\.activityCardDetails.+?children:(\\i\\.application)\\.name.*?}\\),)/,\n replace: (_, props) => `$self.renderToggleActivityButton(${props}),`\n }\n }\n ],\n\n async start() {\n const oldIgnoredActivitiesData = await DataStore.get<Map<IgnoredActivity[\"id\"], IgnoredActivity>>(\"IgnoreActivities_ignoredActivities\");\n\n if (oldIgnoredActivitiesData != null) {\n settings.store.ignoredActivities = Array.from(oldIgnoredActivitiesData.values())\n .map(activity => ({ ...activity, name: \"Unknown Name\" }));\n\n DataStore.del(\"IgnoreActivities_ignoredActivities\");\n }\n\n if (getIgnoredActivities().length !== 0) {\n const gamesSeen = RunningGameStore.getGamesSeen() as { id?: string; exePath: string; }[];\n\n for (const [index, ignoredActivity] of getIgnoredActivities().entries()) {\n if (ignoredActivity.type !== ActivitiesTypes.Game) continue;\n\n if (!gamesSeen.some(game => game.id === ignoredActivity.id || game.exePath === ignoredActivity.id)) {\n getIgnoredActivities().splice(index, 1);\n }\n }\n }\n },\n\n isActivityNotIgnored(props: { type: number; application_id?: string; name?: string; }) {\n if (props.type === 0 || props.type === 3) {\n if (props.application_id != null) return !getIgnoredActivities().some(activity => activity.id === props.application_id);\n else {\n const exePath = RunningGameStore.getRunningGames().find(game => game.name === props.name)?.exePath;\n if (exePath) return !getIgnoredActivities().some(activity => activity.id === exePath);\n }\n }\n return true;\n },\n\n renderToggleGameActivityButton(props: { id?: string; name: string, exePath: string; }, nowPlaying: boolean) {\n return (\n <ErrorBoundary noop>\n <div style={{ marginLeft: 12, zIndex: 0 }}>\n {ToggleActivityComponent({ id: props.id ?? props.exePath, name: props.name, type: ActivitiesTypes.Game }, nowPlaying)}\n </div>\n </ErrorBoundary>\n );\n },\n\n renderToggleActivityButton(props: { id: string; name: string; }) {\n return (\n <ErrorBoundary noop>\n {ToggleActivityComponent({ id: props.id, name: props.name, type: ActivitiesTypes.Embedded })}\n </ErrorBoundary>\n );\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nexport const ELEMENT_ID = \"vc-imgzoom-magnify-modal\";\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nexport function waitFor(condition: () => boolean, cb: () => void) {\n if (condition()) cb();\n else requestAnimationFrame(() => waitFor(condition, cb));\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { classNameFactory } from \"@api/Styles\";\nimport { FluxDispatcher, React, useRef, useState } from \"@webpack/common\";\n\nimport { ELEMENT_ID } from \"../constants\";\nimport { settings } from \"../index\";\nimport { waitFor } from \"../utils/waitFor\";\n\ninterface Vec2 {\n x: number,\n y: number;\n}\n\nexport interface MagnifierProps {\n zoom: number;\n size: number,\n instance: any;\n}\n\nconst cl = classNameFactory(\"vc-imgzoom-\");\n\nexport const Magnifier: React.FC<MagnifierProps> = ({ instance, size: initialSize, zoom: initalZoom }) => {\n const [ready, setReady] = useState(false);\n\n const [lensPosition, setLensPosition] = useState<Vec2>({ x: 0, y: 0 });\n const [imagePosition, setImagePosition] = useState<Vec2>({ x: 0, y: 0 });\n const [opacity, setOpacity] = useState(0);\n\n const isShiftDown = useRef(false);\n\n const zoom = useRef(initalZoom);\n const size = useRef(initialSize);\n\n const element = useRef<HTMLDivElement | null>(null);\n const currentVideoElementRef = useRef<HTMLVideoElement | null>(null);\n const originalVideoElementRef = useRef<HTMLVideoElement | null>(null);\n const imageRef = useRef<HTMLImageElement | null>(null);\n\n // since we accessing document im gonna use useLayoutEffect\n React.useLayoutEffect(() => {\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key === \"Shift\") {\n isShiftDown.current = true;\n }\n };\n const onKeyUp = (e: KeyboardEvent) => {\n if (e.key === \"Shift\") {\n isShiftDown.current = false;\n }\n };\n const syncVideos = () => {\n currentVideoElementRef.current!.currentTime = originalVideoElementRef.current!.currentTime;\n };\n\n const updateMousePosition = (e: MouseEvent) => {\n if (instance.state.mouseOver && instance.state.mouseDown) {\n const offset = size.current / 2;\n const pos = { x: e.pageX, y: e.pageY };\n const x = -((pos.x - element.current!.getBoundingClientRect().left) * zoom.current - offset);\n const y = -((pos.y - element.current!.getBoundingClientRect().top) * zoom.current - offset);\n setLensPosition({ x: e.x - offset, y: e.y - offset });\n setImagePosition({ x, y });\n setOpacity(1);\n } else {\n setOpacity(0);\n }\n\n };\n\n const onMouseDown = (e: MouseEvent) => {\n if (instance.state.mouseOver && e.button === 0 /* left click */) {\n zoom.current = settings.store.zoom;\n size.current = settings.store.size;\n\n // close context menu if open\n if (document.getElementById(\"image-context\")) {\n FluxDispatcher.dispatch({ type: \"CONTEXT_MENU_CLOSE\" });\n }\n\n updateMousePosition(e);\n setOpacity(1);\n }\n };\n\n const onMouseUp = () => {\n setOpacity(0);\n if (settings.store.saveZoomValues) {\n settings.store.zoom = zoom.current;\n settings.store.size = size.current;\n }\n };\n\n const onWheel = async (e: WheelEvent) => {\n if (instance.state.mouseOver && instance.state.mouseDown && !isShiftDown.current) {\n const val = zoom.current + ((e.deltaY / 100) * (settings.store.invertScroll ? -1 : 1)) * settings.store.zoomSpeed;\n zoom.current = val <= 1 ? 1 : val;\n updateMousePosition(e);\n }\n if (instance.state.mouseOver && instance.state.mouseDown && isShiftDown.current) {\n const val = size.current + (e.deltaY * (settings.store.invertScroll ? -1 : 1)) * settings.store.zoomSpeed;\n size.current = val <= 50 ? 50 : val;\n updateMousePosition(e);\n }\n };\n\n waitFor(() => instance.state.readyState === \"READY\", () => {\n const elem = document.getElementById(ELEMENT_ID) as HTMLDivElement;\n element.current = elem;\n elem.firstElementChild!.setAttribute(\"draggable\", \"false\");\n if (instance.props.animated) {\n originalVideoElementRef.current = elem!.querySelector(\"video\")!;\n originalVideoElementRef.current.addEventListener(\"timeupdate\", syncVideos);\n setReady(true);\n } else {\n setReady(true);\n }\n });\n document.addEventListener(\"keydown\", onKeyDown);\n document.addEventListener(\"keyup\", onKeyUp);\n document.addEventListener(\"mousemove\", updateMousePosition);\n document.addEventListener(\"mousedown\", onMouseDown);\n document.addEventListener(\"mouseup\", onMouseUp);\n document.addEventListener(\"wheel\", onWheel);\n return () => {\n document.removeEventListener(\"keydown\", onKeyDown);\n document.removeEventListener(\"keyup\", onKeyUp);\n document.removeEventListener(\"mousemove\", updateMousePosition);\n document.removeEventListener(\"mousedown\", onMouseDown);\n document.removeEventListener(\"mouseup\", onMouseUp);\n document.removeEventListener(\"wheel\", onWheel);\n\n if (settings.store.saveZoomValues) {\n settings.store.zoom = zoom.current;\n settings.store.size = size.current;\n }\n };\n }, []);\n\n if (!ready) return null;\n\n const box = element.current!.getBoundingClientRect();\n\n return (\n <div\n className={cl(\"lens\", { \"nearest-neighbor\": settings.store.nearestNeighbour, square: settings.store.square })}\n style={{\n opacity,\n width: size.current + \"px\",\n height: size.current + \"px\",\n transform: `translate(${lensPosition.x}px, ${lensPosition.y}px)`,\n }}\n >\n {instance.props.animated ?\n (\n <video\n ref={currentVideoElementRef}\n style={{\n position: \"absolute\",\n left: `${imagePosition.x}px`,\n top: `${imagePosition.y}px`\n }}\n width={`${box.width * zoom.current}px`}\n height={`${box.height * zoom.current}px`}\n poster={instance.props.src}\n src={originalVideoElementRef.current?.src ?? instance.props.src}\n autoPlay\n loop\n />\n ) : (\n <img\n ref={imageRef}\n style={{\n position: \"absolute\",\n transform: `translate(${imagePosition.x}px, ${imagePosition.y}px)`\n }}\n width={`${box.width * zoom.current}px`}\n height={`${box.height * zoom.current}px`}\n src={instance.props.src}\n alt=\"\"\n />\n )}\n </div>\n );\n};\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\n(window.VencordStyles ??= new Map()).set(\"src/plugins/imageZoom/styles.css\", {\n name: \"src/plugins/imageZoom/styles.css\",\n source: \".vc-imgzoom-lens {\\n position: absolute;\\n inset: 0;\\n z-index: 9999;\\n border: 2px solid grey;\\n border-radius: 50%;\\n overflow: hidden;\\n cursor: none;\\n box-shadow: inset 0 0 10px 2px grey;\\n filter: drop-shadow(0 0 2px grey);\\n pointer-events: none;\\n}\\n\\n.vc-imgzoom-square {\\n border-radius: 0;\\n}\\n\\n.vc-imgzoom-nearest-neighbor>img {\\n image-rendering: pixelated;\\n\\n /* https://googlechrome.github.io/samples/image-rendering-pixelated/index.html */\\n}\\n\\n/* make the carousel take up less space so we can click the backdrop and exit out of it */\\n[class*=\\\"modalCarouselWrapper_\\\"] {\\n top: 0 !important;\\n}\\n\\n[class*=\\\"carouselModal_\\\"] {\\n height: 0 !important;\\n}\\n\",\n classNames: {},\n dom: null,\n});\n\nexport default \"src/plugins/imageZoom/styles.css\";\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { addContextMenuPatch, NavContextMenuPatchCallback, removeContextMenuPatch } from \"@api/ContextMenu\";\nimport { definePluginSettings } from \"@api/Settings\";\nimport { disableStyle, enableStyle } from \"@api/Styles\";\nimport { makeRange } from \"@components/PluginSettings/components\";\nimport { Devs } from \"@utils/constants\";\nimport { debounce } from \"@utils/debounce\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { ContextMenuApi, Menu, React, ReactDOM } from \"@webpack/common\";\nimport type { Root } from \"react-dom/client\";\n\nimport { Magnifier, MagnifierProps } from \"./components/Magnifier\";\nimport { ELEMENT_ID } from \"./constants\";\nimport styles from \"./styles.css?managed\";\n\nexport const settings = definePluginSettings({\n saveZoomValues: {\n type: OptionType.BOOLEAN,\n description: \"Whether to save zoom and lens size values\",\n default: true,\n },\n\n invertScroll: {\n type: OptionType.BOOLEAN,\n description: \"Invert scroll\",\n default: true,\n },\n\n nearestNeighbour: {\n type: OptionType.BOOLEAN,\n description: \"Use Nearest Neighbour Interpolation when scaling images\",\n default: false,\n },\n\n square: {\n type: OptionType.BOOLEAN,\n description: \"Make the lens square\",\n default: false,\n },\n\n zoom: {\n description: \"Zoom of the lens\",\n type: OptionType.SLIDER,\n markers: makeRange(1, 50, 4),\n default: 2,\n stickToMarkers: false,\n },\n size: {\n description: \"Radius / Size of the lens\",\n type: OptionType.SLIDER,\n markers: makeRange(50, 1000, 50),\n default: 100,\n stickToMarkers: false,\n },\n\n zoomSpeed: {\n description: \"How fast the zoom / lens size changes\",\n type: OptionType.SLIDER,\n markers: makeRange(0.1, 5, 0.2),\n default: 0.5,\n stickToMarkers: false,\n },\n});\n\n\nconst imageContextMenuPatch: NavContextMenuPatchCallback = children => () => {\n children.push(\n <Menu.MenuGroup id=\"image-zoom\">\n <Menu.MenuCheckboxItem\n id=\"vc-square\"\n label=\"Square Lens\"\n checked={settings.store.square}\n action={() => {\n settings.store.square = !settings.store.square;\n ContextMenuApi.closeContextMenu();\n }}\n />\n <Menu.MenuCheckboxItem\n id=\"vc-nearest-neighbour\"\n label=\"Nearest Neighbour\"\n checked={settings.store.nearestNeighbour}\n action={() => {\n settings.store.nearestNeighbour = !settings.store.nearestNeighbour;\n ContextMenuApi.closeContextMenu();\n }}\n />\n <Menu.MenuControlItem\n id=\"vc-zoom\"\n label=\"Zoom\"\n control={(props, ref) => (\n <Menu.MenuSliderControl\n ref={ref}\n {...props}\n minValue={1}\n maxValue={50}\n value={settings.store.zoom}\n onChange={debounce((value: number) => settings.store.zoom = value, 100)}\n />\n )}\n />\n <Menu.MenuControlItem\n id=\"vc-size\"\n label=\"Lens Size\"\n control={(props, ref) => (\n <Menu.MenuSliderControl\n ref={ref}\n {...props}\n minValue={50}\n maxValue={1000}\n value={settings.store.size}\n onChange={debounce((value: number) => settings.store.size = value, 100)}\n />\n )}\n />\n <Menu.MenuControlItem\n id=\"vc-zoom-speed\"\n label=\"Zoom Speed\"\n control={(props, ref) => (\n <Menu.MenuSliderControl\n ref={ref}\n {...props}\n minValue={0.1}\n maxValue={5}\n value={settings.store.zoomSpeed}\n onChange={debounce((value: number) => settings.store.zoomSpeed = value, 100)}\n renderValue={(value: number) => `${value.toFixed(3)}x`}\n />\n )}\n />\n </Menu.MenuGroup>\n );\n};\n\nexport default definePlugin({\n name: \"ImageZoom\",\n description: \"Lets you zoom in to images and gifs. Use scroll wheel to zoom in and shift + scroll wheel to increase lens radius / size\",\n authors: [Devs.Aria],\n tags: [\"ImageUtilities\"],\n\n patches: [\n {\n find: \"Messages.OPEN_IN_BROWSER\",\n replacement: {\n // there are 2 image thingies. one for carosuel and one for the single image.\n // so thats why i added global flag.\n // also idk if this patch is good, should it be more specific?\n // https://regex101.com/r/xfvNvV/1\n match: /return.{1,200}\\.wrapper.{1,200}src:\\i,/g,\n replace: `$&id: '${ELEMENT_ID}',`\n }\n },\n\n {\n find: \"handleImageLoad=\",\n replacement: [\n {\n match: /showThumbhashPlaceholder:\\i,/,\n replace: \"...$self.makeProps(this),$&\"\n },\n\n {\n match: /componentDidMount\\(\\){/,\n replace: \"$&$self.renderMagnifier(this);\",\n },\n\n {\n match: /componentWillUnmount\\(\\){/,\n replace: \"$&$self.unMountMagnifier();\"\n }\n ]\n },\n {\n find: \".carouselModal\",\n replacement: {\n match: /(?<=\\.carouselModal.{0,100}onClick:)\\i,/,\n replace: \"()=>{},\"\n }\n }\n ],\n\n settings,\n\n // to stop from rendering twice /shrug\n currentMagnifierElement: null as React.FunctionComponentElement<MagnifierProps & JSX.IntrinsicAttributes> | null,\n element: null as HTMLDivElement | null,\n\n Magnifier,\n root: null as Root | null,\n makeProps(instance) {\n return {\n onMouseOver: () => this.onMouseOver(instance),\n onMouseOut: () => this.onMouseOut(instance),\n onMouseDown: (e: React.MouseEvent) => this.onMouseDown(e, instance),\n onMouseUp: () => this.onMouseUp(instance),\n id: instance.props.id,\n };\n },\n\n renderMagnifier(instance) {\n if (instance.props.id === ELEMENT_ID) {\n if (!this.currentMagnifierElement) {\n this.currentMagnifierElement = <Magnifier size={settings.store.size} zoom={settings.store.zoom} instance={instance} />;\n this.root = ReactDOM.createRoot(this.element!);\n this.root.render(this.currentMagnifierElement);\n }\n }\n },\n\n unMountMagnifier() {\n this.root?.unmount();\n this.currentMagnifierElement = null;\n this.root = null;\n },\n\n onMouseOver(instance) {\n instance.setState((state: any) => ({ ...state, mouseOver: true }));\n },\n onMouseOut(instance) {\n instance.setState((state: any) => ({ ...state, mouseOver: false }));\n },\n onMouseDown(e: React.MouseEvent, instance) {\n if (e.button === 0 /* left */)\n instance.setState((state: any) => ({ ...state, mouseDown: true }));\n },\n onMouseUp(instance) {\n instance.setState((state: any) => ({ ...state, mouseDown: false }));\n },\n\n start() {\n enableStyle(styles);\n addContextMenuPatch(\"image-context\", imageContextMenuPatch);\n this.element = document.createElement(\"div\");\n this.element.classList.add(\"MagnifierContainer\");\n document.body.appendChild(this.element);\n },\n\n stop() {\n disableStyle(styles);\n // so componenetWillUnMount gets called if Magnifier component is still alive\n this.root && this.root.unmount();\n this.element?.remove();\n removeContextMenuPatch(\"image-context\", imageContextMenuPatch);\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport {\n ModalContent,\n ModalFooter,\n ModalHeader,\n ModalRoot,\n openModal,\n} from \"@utils/modal\";\nimport { Button, Forms, React, TextInput } from \"@webpack/common\";\n\nimport { decrypt } from \"../index\";\n\nexport function DecModal(props: any) {\n const encryptedMessage: string = props?.message?.content;\n const [password, setPassword] = React.useState(\"password\");\n\n return (\n <ModalRoot {...props}>\n <ModalHeader>\n <Forms.FormTitle tag=\"h4\">Decrypt Message</Forms.FormTitle>\n </ModalHeader>\n\n <ModalContent>\n <Forms.FormTitle tag=\"h5\" style={{ marginTop: \"10px\" }}>Message with Encryption</Forms.FormTitle>\n <TextInput defaultValue={encryptedMessage} disabled={true}></TextInput>\n <Forms.FormTitle tag=\"h5\" style={{ marginTop: \"10px\" }}>Password</Forms.FormTitle>\n <TextInput\n style={{ marginBottom: \"20px\" }}\n onChange={setPassword}\n />\n </ModalContent>\n\n <ModalFooter>\n <Button\n color={Button.Colors.GREEN}\n onClick={() => {\n const toSend = decrypt(encryptedMessage, password, true);\n if (!toSend || !props?.message) return;\n // @ts-expect-error\n Vencord.Plugins.plugins.InvisibleChat.buildEmbed(props?.message, toSend);\n props.onClose();\n }}>\n Decrypt\n </Button>\n <Button\n color={Button.Colors.TRANSPARENT}\n look={Button.Looks.LINK}\n style={{ left: 15, position: \"absolute\" }}\n onClick={props.onClose}\n >\n Cancel\n </Button>\n </ModalFooter>\n </ModalRoot>\n );\n}\n\nexport function buildDecModal(msg: any): any {\n openModal((props: any) => <DecModal {...props} {...msg} />);\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { insertTextIntoChatInputBox } from \"@utils/discord\";\nimport {\n ModalContent,\n ModalFooter,\n ModalHeader,\n ModalProps,\n ModalRoot,\n openModal,\n} from \"@utils/modal\";\nimport { Button, Forms, React, Switch, TextInput } from \"@webpack/common\";\n\nimport { encrypt } from \"../index\";\n\nfunction EncModal(props: ModalProps) {\n const [secret, setSecret] = React.useState(\"\");\n const [cover, setCover] = React.useState(\"\");\n const [password, setPassword] = React.useState(\"password\");\n const [noCover, setNoCover] = React.useState(false);\n\n const isValid = secret && (noCover || (cover && cover.trim().split(\" \").length > 1));\n\n return (\n <ModalRoot {...props}>\n <ModalHeader>\n <Forms.FormTitle tag=\"h4\">Encrypt Message</Forms.FormTitle>\n </ModalHeader>\n\n <ModalContent>\n <Forms.FormTitle tag=\"h5\" style={{ marginTop: \"10px\" }}>Secret</Forms.FormTitle>\n <TextInput\n onChange={(e: string) => {\n setSecret(e);\n }}\n />\n <Forms.FormTitle tag=\"h5\" style={{ marginTop: \"10px\" }}>Cover (2 or more Words!!)</Forms.FormTitle>\n <TextInput\n disabled={noCover}\n onChange={(e: string) => {\n setCover(e);\n }}\n />\n <Forms.FormTitle tag=\"h5\" style={{ marginTop: \"10px\" }}>Password</Forms.FormTitle>\n <TextInput\n style={{ marginBottom: \"20px\" }}\n defaultValue={\"password\"}\n onChange={(e: string) => {\n setPassword(e);\n }}\n />\n <Switch\n value={noCover}\n onChange={(e: boolean) => {\n setNoCover(e);\n }}\n >\n Don't use a Cover\n </Switch>\n </ModalContent>\n\n <ModalFooter>\n <Button\n color={Button.Colors.GREEN}\n disabled={!isValid}\n onClick={() => {\n if (!isValid) return;\n const encrypted = encrypt(secret, password, noCover ? \"d d\" : cover);\n const toSend = noCover ? encrypted.replaceAll(\"d\", \"\") : encrypted;\n if (!toSend) return;\n\n insertTextIntoChatInputBox(toSend);\n\n props.onClose();\n }}\n >\n Send\n </Button>\n <Button\n color={Button.Colors.TRANSPARENT}\n look={Button.Looks.LINK}\n style={{ left: 15, position: \"absolute\" }}\n onClick={() => {\n props.onClose();\n }}\n >\n Cancel\n </Button>\n </ModalFooter>\n </ModalRoot>\n );\n}\n\nexport function buildEncModal(): any {\n openModal(props => <EncModal {...props} />);\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { addButton, removeButton } from \"@api/MessagePopover\";\nimport { definePluginSettings } from \"@api/Settings\";\nimport ErrorBoundary from \"@components/ErrorBoundary\";\nimport { Devs } from \"@utils/constants\";\nimport { getStegCloak } from \"@utils/dependencies\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { Button, ButtonLooks, ButtonWrapperClasses, ChannelStore, FluxDispatcher, RestAPI, Tooltip } from \"@webpack/common\";\nimport { Message } from \"discord-types/general\";\n\nimport { buildDecModal } from \"./components/DecryptionModal\";\nimport { buildEncModal } from \"./components/EncryptionModal\";\n\nlet steggo: any;\n\nfunction PopOverIcon() {\n return (\n\n <svg\n fill=\"var(--header-secondary)\"\n width={24} height={24}\n viewBox={\"0 0 64 64\"}\n >\n <path d=\"M 32 9 C 24.832 9 19 14.832 19 22 L 19 27.347656 C 16.670659 28.171862 15 30.388126 15 33 L 15 49 C 15 52.314 17.686 55 21 55 L 43 55 C 46.314 55 49 52.314 49 49 L 49 33 C 49 30.388126 47.329341 28.171862 45 27.347656 L 45 22 C 45 14.832 39.168 9 32 9 z M 32 13 C 36.963 13 41 17.038 41 22 L 41 27 L 23 27 L 23 22 C 23 17.038 27.037 13 32 13 z\" />\n </svg>\n );\n}\n\n\nfunction Indicator() {\n return (\n <Tooltip text=\"This message has a hidden message! (InvisibleChat)\">\n {({ onMouseEnter, onMouseLeave }) => (\n <img\n aria-label=\"Hidden Message Indicator (InvisibleChat)\"\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n src=\"https://github.com/SammCheese/invisible-chat/raw/NewReplugged/src/assets/lock.png\"\n width={20}\n height={20}\n style={{ transform: \"translateY(4p)\", paddingInline: 4 }}\n />\n )}\n </Tooltip>\n\n );\n\n}\n\nfunction ChatBarIcon(chatBoxProps: {\n type: {\n analyticsName: string;\n };\n}) {\n if (chatBoxProps.type.analyticsName !== \"normal\") return null;\n\n return (\n <Tooltip text=\"Encrypt Message\">\n {({ onMouseEnter, onMouseLeave }) => (\n // size=\"\" = Button.Sizes.NONE\n /*\n many themes set \"> button\" to display: none, as the gift button is\n the only directly descending button (all the other elements are divs.)\n Thus, wrap in a div here to avoid getting hidden by that.\n flex is for some reason necessary as otherwise the button goes flying off\n */\n <div style={{ display: \"flex\" }}>\n <Button\n aria-haspopup=\"dialog\"\n aria-label=\"Encrypt Message\"\n size=\"\"\n look={ButtonLooks.BLANK}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n innerClassName={ButtonWrapperClasses.button}\n onClick={() => buildEncModal()}\n style={{ padding: \"0 2px\", scale: \"0.9\" }}\n >\n <div className={ButtonWrapperClasses.buttonWrapper}>\n <svg\n aria-hidden\n role=\"img\"\n width=\"32\"\n height=\"32\"\n viewBox={\"0 0 64 64\"}\n style={{ scale: \"1.1\" }}\n >\n <path fill=\"currentColor\" d=\"M 32 9 C 24.832 9 19 14.832 19 22 L 19 27.347656 C 16.670659 28.171862 15 30.388126 15 33 L 15 49 C 15 52.314 17.686 55 21 55 L 43 55 C 46.314 55 49 52.314 49 49 L 49 33 C 49 30.388126 47.329341 28.171862 45 27.347656 L 45 22 C 45 14.832 39.168 9 32 9 z M 32 13 C 36.963 13 41 17.038 41 22 L 41 27 L 23 27 L 23 22 C 23 17.038 27.037 13 32 13 z\" />\n </svg>\n </div>\n </Button>\n </div>\n )\n }\n </Tooltip >\n );\n}\n\nconst settings = definePluginSettings({\n savedPasswords: {\n type: OptionType.STRING,\n default: \"password, Password\",\n description: \"Saved Passwords (Seperated with a , )\"\n }\n});\n\nexport default definePlugin({\n name: \"InvisibleChat\",\n description: \"Encrypt your Messages in a non-suspicious way!\",\n authors: [Devs.SammCheese],\n dependencies: [\"MessagePopoverAPI\"],\n patches: [\n {\n // Indicator\n find: \".Messages.MESSAGE_EDITED,\",\n replacement: {\n match: /let\\{className:\\i,message:\\i[^}]*\\}=(\\i)/,\n replace: \"try {$1 && $self.INV_REGEX.test($1.message.content) ? $1.content.push($self.indicator()) : null } catch {};$&\"\n }\n },\n {\n find: \"ChannelTextAreaButtons\",\n replacement: {\n match: /(\\i)\\.push.{1,30}disabled:(\\i),.{1,20}\\},\"gift\"\\)\\)/,\n replace: \"$&,(()=>{try{$2||$1.push($self.chatBarIcon(arguments[0]))}catch{}})()\",\n }\n },\n ],\n\n EMBED_API_URL: \"https://embed.sammcheese.net\",\n INV_REGEX: new RegExp(/( \\u200c|\\u200d |[\\u2060-\\u2064])[^\\u200b]/),\n URL_REGEX: new RegExp(\n /(http(s)?:\\/\\/.)?(www\\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\\.[a-z]{2,6}\\b([-a-zA-Z0-9@:%_+.~#?&//=]*)/,\n ),\n settings,\n async start() {\n const { default: StegCloak } = await getStegCloak();\n steggo = new StegCloak(true, false);\n\n addButton(\"invDecrypt\", message => {\n return this.INV_REGEX.test(message?.content)\n ? {\n label: \"Decrypt Message\",\n icon: this.popOverIcon,\n message: message,\n channel: ChannelStore.getChannel(message.channel_id),\n onClick: async () => {\n await iteratePasswords(message).then((res: string | false) => {\n if (res) return void this.buildEmbed(message, res);\n return void buildDecModal({ message });\n });\n }\n }\n : null;\n });\n },\n\n stop() {\n removeButton(\"invDecrypt\");\n },\n\n // Gets the Embed of a Link\n async getEmbed(url: URL): Promise<Object | {}> {\n const { body } = await RestAPI.post({\n url: \"/unfurler/embed-urls\",\n body: {\n urls: [url]\n }\n });\n return await body.embeds[0];\n },\n\n async buildEmbed(message: any, revealed: string): Promise<void> {\n const urlCheck = revealed.match(this.URL_REGEX);\n\n message.embeds.push({\n type: \"rich\",\n title: \"Decrypted Message\",\n color: \"0x45f5f5\",\n description: revealed,\n footer: {\n text: \"Made with \u2764\uFE0F by c0dine and Sammy!\",\n },\n });\n\n if (urlCheck?.length) {\n const embed = await this.getEmbed(new URL(urlCheck[0]));\n if (embed)\n message.embeds.push(embed);\n }\n\n this.updateMessage(message);\n },\n\n updateMessage: (message: any) => {\n FluxDispatcher.dispatch({\n type: \"MESSAGE_UPDATE\",\n message,\n });\n },\n\n chatBarIcon: ErrorBoundary.wrap(ChatBarIcon, { noop: true }),\n popOverIcon: () => <PopOverIcon />,\n indicator: ErrorBoundary.wrap(Indicator, { noop: true })\n});\n\nexport function encrypt(secret: string, password: string, cover: string): string {\n return steggo.hide(secret + \"\\u200b\", password, cover);\n}\n\nexport function decrypt(encrypted: string, password: string, removeIndicator: boolean): string {\n const decrypted = steggo.reveal(encrypted, password);\n return removeIndicator ? decrypted.replace(\"\\u200b\", \"\") : decrypted;\n}\n\nexport function isCorrectPassword(result: string): boolean {\n return result.endsWith(\"\\u200b\");\n}\n\nexport async function iteratePasswords(message: Message): Promise<string | false> {\n const passwords = settings.store.savedPasswords.split(\",\").map(s => s.trim());\n\n if (!message?.content || !passwords?.length) return false;\n\n let { content } = message;\n\n // we use an extra variable so we dont have to edit the message content directly\n if (/^\\W/.test(message.content)) content = `d ${message.content}d`;\n\n for (let i = 0; i < passwords.length; i++) {\n const result = decrypt(content, passwords[i], false);\n if (isCorrectPassword(result)) {\n return result;\n }\n }\n\n return false;\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport * as DataStore from \"@api/DataStore\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\nimport { ChannelStore, NavigationRouter, SelectedChannelStore, SelectedGuildStore } from \"@webpack/common\";\n\nexport interface LogoutEvent {\n type: \"LOGOUT\";\n isSwitchingAccount: boolean;\n}\n\ninterface ChannelSelectEvent {\n type: \"CHANNEL_SELECT\";\n channelId: string | null;\n guildId: string | null;\n}\n\ninterface PreviousChannel {\n guildId: string | null;\n channelId: string | null;\n}\n\nlet isSwitchingAccount = false;\nlet previousCache: PreviousChannel | undefined;\n\nfunction attemptToNavigateToChannel(guildId: string | null, channelId: string) {\n if (!ChannelStore.hasChannel(channelId)) return;\n NavigationRouter.transitionTo(`/channels/${guildId ?? \"@me\"}/${channelId}`);\n}\n\nexport default definePlugin({\n name: \"KeepCurrentChannel\",\n description: \"Attempt to navigate to the channel you were in before switching accounts or loading Discord.\",\n authors: [Devs.Nuckyz],\n\n flux: {\n LOGOUT(e: LogoutEvent) {\n ({ isSwitchingAccount } = e);\n },\n\n CONNECTION_OPEN() {\n if (!isSwitchingAccount) return;\n isSwitchingAccount = false;\n\n if (previousCache?.channelId)\n attemptToNavigateToChannel(previousCache.guildId, previousCache.channelId);\n },\n\n async CHANNEL_SELECT({ guildId, channelId }: ChannelSelectEvent) {\n if (isSwitchingAccount) return;\n\n previousCache = {\n guildId,\n channelId\n };\n await DataStore.set(\"KeepCurrentChannel_previousData\", previousCache);\n }\n },\n\n async start() {\n previousCache = await DataStore.get<PreviousChannel>(\"KeepCurrentChannel_previousData\");\n if (!previousCache) {\n previousCache = {\n guildId: SelectedGuildStore.getGuildId(),\n channelId: SelectedChannelStore.getChannelId() ?? null\n };\n\n await DataStore.set(\"KeepCurrentChannel_previousData\", previousCache);\n } else if (previousCache.channelId) {\n attemptToNavigateToChannel(previousCache.guildId, previousCache.channelId);\n }\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Sofia Lima\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { definePluginSettings } from \"@api/Settings\";\nimport { Link } from \"@components/Link\";\nimport { Devs } from \"@utils/constants\";\nimport { Logger } from \"@utils/Logger\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { findByPropsLazy } from \"@webpack\";\nimport { ApplicationAssetUtils, FluxDispatcher, Forms } from \"@webpack/common\";\n\ninterface ActivityAssets {\n large_image?: string;\n large_text?: string;\n small_image?: string;\n small_text?: string;\n}\n\n\ninterface ActivityButton {\n label: string;\n url: string;\n}\n\ninterface Activity {\n state: string;\n details?: string;\n timestamps?: {\n start?: number;\n };\n assets?: ActivityAssets;\n buttons?: Array<string>;\n name: string;\n application_id: string;\n metadata?: {\n button_urls?: Array<string>;\n };\n type: number;\n flags: number;\n}\n\ninterface TrackData {\n name: string;\n album: string;\n artist: string;\n url: string;\n imageUrl?: string;\n}\n\n// only relevant enum values\nconst enum ActivityType {\n PLAYING = 0,\n LISTENING = 2,\n}\n\nconst enum ActivityFlag {\n INSTANCE = 1 << 0,\n}\n\nconst enum NameFormat {\n StatusName = \"status-name\",\n ArtistFirst = \"artist-first\",\n SongFirst = \"song-first\",\n ArtistOnly = \"artist\",\n SongOnly = \"song\"\n}\n\nconst applicationId = \"1108588077900898414\";\nconst placeholderId = \"2a96cbd8b46e442fc41c2b86b821562f\";\n\nconst logger = new Logger(\"LastFMRichPresence\");\n\nconst presenceStore = findByPropsLazy(\"getLocalPresence\");\n\nasync function getApplicationAsset(key: string): Promise<string> {\n return (await ApplicationAssetUtils.fetchAssetIds(applicationId, [key]))[0];\n}\n\nfunction setActivity(activity: Activity | null) {\n FluxDispatcher.dispatch({\n type: \"LOCAL_ACTIVITY_UPDATE\",\n activity,\n socketId: \"LastFM\",\n });\n}\n\nconst settings = definePluginSettings({\n username: {\n description: \"last.fm username\",\n type: OptionType.STRING,\n },\n apiKey: {\n description: \"last.fm api key\",\n type: OptionType.STRING,\n },\n shareUsername: {\n description: \"show link to last.fm profile\",\n type: OptionType.BOOLEAN,\n default: false,\n },\n hideWithSpotify: {\n description: \"hide last.fm presence if spotify is running\",\n type: OptionType.BOOLEAN,\n default: true,\n },\n statusName: {\n description: \"custom status text\",\n type: OptionType.STRING,\n default: \"some music\",\n },\n nameFormat: {\n description: \"Show name of song and artist in status name\",\n type: OptionType.SELECT,\n options: [\n {\n label: \"Use custom status name\",\n value: NameFormat.StatusName,\n default: true\n },\n {\n label: \"Use format 'artist - song'\",\n value: NameFormat.ArtistFirst\n },\n {\n label: \"Use format 'song - artist'\",\n value: NameFormat.SongFirst\n },\n {\n label: \"Use artist name only\",\n value: NameFormat.ArtistOnly\n },\n {\n label: \"Use song name only\",\n value: NameFormat.SongOnly\n }\n ],\n },\n useListeningStatus: {\n description: 'show \"Listening to\" status instead of \"Playing\"',\n type: OptionType.BOOLEAN,\n default: false,\n },\n missingArt: {\n description: \"When album or album art is missing\",\n type: OptionType.SELECT,\n options: [\n {\n label: \"Use large Last.fm logo\",\n value: \"lastfmLogo\",\n default: true\n },\n {\n label: \"Use generic placeholder\",\n value: \"placeholder\"\n }\n ],\n },\n});\n\nexport default definePlugin({\n name: \"LastFMRichPresence\",\n description: \"Little plugin for Last.fm rich presence\",\n authors: [Devs.dzshn, Devs.RuiNtD, Devs.blahajZip, Devs.archeruwu],\n\n settingsAboutComponent: () => (\n <>\n <Forms.FormTitle tag=\"h3\">How to get an API key</Forms.FormTitle>\n <Forms.FormText>\n An API key is required to fetch your current track. To get one, you can\n visit <Link href=\"https://www.last.fm/api/account/create\">this page</Link> and\n fill in the following information: <br /> <br />\n\n Application name: Discord Rich Presence <br />\n Application description: (personal use) <br /> <br />\n\n And copy the API key (not the shared secret!)\n </Forms.FormText>\n </>\n ),\n\n settings,\n\n start() {\n this.updatePresence();\n this.updateInterval = setInterval(() => { this.updatePresence(); }, 16000);\n },\n\n stop() {\n clearInterval(this.updateInterval);\n },\n\n async fetchTrackData(): Promise<TrackData | null> {\n if (!settings.store.username || !settings.store.apiKey)\n return null;\n\n try {\n const params = new URLSearchParams({\n method: \"user.getrecenttracks\",\n api_key: settings.store.apiKey,\n user: settings.store.username,\n limit: \"1\",\n format: \"json\"\n });\n\n const res = await fetch(`https://ws.audioscrobbler.com/2.0/?${params}`);\n if (!res.ok) throw `${res.status} ${res.statusText}`;\n\n const json = await res.json();\n if (json.error) {\n logger.error(\"Error from Last.fm API\", `${json.error}: ${json.message}`);\n return null;\n }\n\n const trackData = json.recenttracks?.track[0];\n\n if (!trackData?.[\"@attr\"]?.nowplaying)\n return null;\n\n // why does the json api have xml structure\n return {\n name: trackData.name || \"Unknown\",\n album: trackData.album[\"#text\"],\n artist: trackData.artist[\"#text\"] || \"Unknown\",\n url: trackData.url,\n imageUrl: trackData.image?.find((x: any) => x.size === \"large\")?.[\"#text\"]\n };\n } catch (e) {\n logger.error(\"Failed to query Last.fm API\", e);\n // will clear the rich presence if API fails\n return null;\n }\n },\n\n async updatePresence() {\n setActivity(await this.getActivity());\n },\n\n getLargeImage(track: TrackData): string | undefined {\n if (track.imageUrl && !track.imageUrl.includes(placeholderId))\n return track.imageUrl;\n\n if (settings.store.missingArt === \"placeholder\")\n return \"placeholder\";\n },\n\n async getActivity(): Promise<Activity | null> {\n if (settings.store.hideWithSpotify) {\n for (const activity of presenceStore.getActivities()) {\n if (activity.type === ActivityType.LISTENING && activity.application_id !== applicationId) {\n // there is already music status because of Spotify or richerCider (probably more)\n return null;\n }\n }\n }\n\n const trackData = await this.fetchTrackData();\n if (!trackData) return null;\n\n const largeImage = this.getLargeImage(trackData);\n const assets: ActivityAssets = largeImage ?\n {\n large_image: await getApplicationAsset(largeImage),\n large_text: trackData.album || undefined,\n small_image: await getApplicationAsset(\"lastfm-small\"),\n small_text: \"Last.fm\",\n } : {\n large_image: await getApplicationAsset(\"lastfm-large\"),\n large_text: trackData.album || undefined,\n };\n\n const buttons: ActivityButton[] = [\n {\n label: \"View Song\",\n url: trackData.url,\n },\n ];\n\n if (settings.store.shareUsername)\n buttons.push({\n label: \"Last.fm Profile\",\n url: `https://www.last.fm/user/${settings.store.username}`,\n });\n\n const statusName = (() => {\n switch (settings.store.nameFormat) {\n case NameFormat.ArtistFirst:\n return trackData.artist + \" - \" + trackData.name;\n case NameFormat.SongFirst:\n return trackData.name + \" - \" + trackData.artist;\n case NameFormat.ArtistOnly:\n return trackData.artist;\n case NameFormat.SongOnly:\n return trackData.name;\n default:\n return settings.store.statusName;\n }\n })();\n\n return {\n application_id: applicationId,\n name: statusName,\n\n details: trackData.name,\n state: trackData.artist,\n assets,\n\n buttons: buttons.map(v => v.label),\n metadata: {\n button_urls: buttons.map(v => v.url),\n },\n\n type: settings.store.useListeningStatus ? ActivityType.LISTENING : ActivityType.PLAYING,\n flags: ActivityFlag.INSTANCE,\n };\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { definePluginSettings } from \"@api/Settings\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin, { OptionType } from \"@utils/types\";\n\n// These are Xor encrypted to prevent you from spoiling yourself when you read the source code.\n// don't worry about it :P\nconst quotes = [\n \"Eyrokac\",\n \"Rdcg$l`'k|~n\",\n 'H`tf$d&iajo+d`{\"',\n \"Sucqplh`(Eclhualva()&\",\n \"Lncgmka'8KNMDC,shpanf'`x./,\",\n \"Ioqweijnfn*IeuvfvAotkfxo./,\",\n 'Hd{#cp\\x7Ft$)nbd!{lq%mig~*\\x7Fh`v#mk&sm{gx nd#idjb(a\\x7Ffao\"bja&amdkge!Rlo\u00ECkhf)hyedfjjb*\\'^hzdrdmm$lu\\'|ao+mnqw$fijxh~bbmg#Tjm\u00EEefd+fnp#lpkffz5',\n \"h\",\n \"sijklm&cam*rot\\\"hjjq'|ak\\x7F xmv#wc'ep*mawmvvlrb(|ynr>\\\"Aqq&cgg-\\x7F ugoh%rom)e\\x7Fhdpp%$\",\n 'Tnfb}\"u\\'~`nno!kp$vvhfzeyee\"a}%Tfam*Xh`fls%Jboldos-\"lj`&hn)~ce!`jcbct|)gdbhnf$wikm$zgaxkmc%afely+og\"144?\\'ign+iu%p$qisiefr gpfa$',\n \"Ndtfv%ahfgk+ghtf$|ir(|z' Oguaw&`ggdj mgw$|ir(me|n\",\n \"(!\u0363\u00B3$\u0359\u0290'\u0369\u00B9#\",\n \"(\uFF88\u25D7\u30ED\u25D1,\uFF8F-2\uFF6C\uFF95\u272C\",\n \"Ynw#hjil(ze+psgwp|&sgmkr!\",\n \"Tikmolh`(fl+a!dvjk\\x7F'y|e\\x7Fe/,-\",\n \"3/3750?5><9>885:7\",\n \"mdmt\",\n \"Wdn`khc+(oxbeof\",\n 'Ig\"zkp*\\'g{*xolglj`&~g|*gowg/$mgt(Eclm`.#ticf{l*xed\"wl`&Kangj igbhqn\\'d`dn `v#lqrw{3%$bhv-h|)kangj_imwhlhb',\n \"Tscmw%Tnoa~x\",\n \"I\u2018f#npus(ec`e!vl$lhsm{`ncu\\\"ekw&f(defeov-$Rnf|)sdu\u2018pf$wcam{ceg!vl$du'D`d~x-\\\"jw%oi(okht-\\\"DJP)Kag\u007Fs,!mq$du'A\u2010|n sg`akrkq)~jkdl#pj&diefbnf\\\"jp)&@F\\\\*{ltq#Hlhrp'\",\n \"Ynw$v`&cg`dl fml`%rhlhs*\",\n \"Dnl$p%qhz{s' hv$w%hh|aceg!;#gpvt(fl+cndea`&dg|fon&v#wjjqm(\",\n \"\\ud83d)pft`gs(ec`e!13$qojmz#\",\n \"a!njcmr'ide~nu\\\"lb%rheoedldpz$lu'gbkr\",\n \"dn\\\"zkp&kg\u007Fo4\",\n \"hnpqkw\",\n \"sn\\\"fau\u007F\",\n \"Sn\\\"tmqnh}}*musvkaw&flf&+ldv$w%lr{}*aulr#vlao|)cetn\\\"jp$\",\n \"Dxkmc%ot(hhxomwwai\u007F'{hln\",\n \"hd{#}js&(pe~'sg#gprb(3#\\\"\",\n \"hd{b${\",\n \"<;vqkijbq33271:56<3799?24944:\",\n \"Thof$lu'ofdn,!qsefc'az*bnrcma+&Om{o+iu\\\"`khct$)bnrd\\\"bcdoi&\",\n \"snofplkb{)c\u007F'r\\\"lod\u007F'|f*aurv#cpno`abchijklmno\",\n \"Wdn`khc'|f*eghl{%\"\n];\n\nconst settings = definePluginSettings({\n replaceEvents: {\n description: \"Replace Event Quotes too\",\n type: OptionType.BOOLEAN,\n default: true\n }\n});\n\nexport default definePlugin({\n name: \"LoadingQuotes\",\n description: \"Replace Discords loading quotes\",\n authors: [Devs.Ven, Devs.KraXen72],\n\n settings,\n\n patches: [\n {\n find: \".LOADING_DID_YOU_KNOW}\",\n replacement: [\n {\n match: /\\._loadingText=function\\(\\)\\{/,\n replace: \"$&return $self.quote;\",\n },\n {\n match: /\\._eventLoadingText=function\\(\\)\\{/,\n replace: \"$&return $self.quote;\",\n predicate: () => settings.store.replaceEvents\n }\n ],\n },\n ],\n\n xor(quote: string) {\n const key = \"read if cute\";\n const codes = Array.from(quote, (s, i) => s.charCodeAt(0) ^ (i % key.length));\n return String.fromCharCode(...codes);\n },\n\n get quote() {\n return this.xor(quotes[Math.floor(Math.random() * quotes.length)]);\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport ErrorBoundary from \"@components/ErrorBoundary\";\nimport { Flex } from \"@components/Flex\";\nimport { Devs } from \"@utils/constants\";\nimport { getCurrentChannel } from \"@utils/discord\";\nimport definePlugin from \"@utils/types\";\nimport { findStoreLazy } from \"@webpack\";\nimport { SelectedChannelStore, Tooltip, useStateFromStores } from \"@webpack/common\";\nimport { FluxStore } from \"@webpack/types\";\n\nconst GuildMemberCountStore = findStoreLazy(\"GuildMemberCountStore\") as FluxStore & { getMemberCount(guildId: string): number | null; };\nconst ChannelMemberStore = findStoreLazy(\"ChannelMemberStore\") as FluxStore & {\n getProps(guildId: string, channelId: string): { groups: { count: number; id: string; }[]; };\n};\n\nconst sharedIntlNumberFormat = new Intl.NumberFormat();\nconst numberFormat = (value: number) => sharedIntlNumberFormat.format(value);\n\nfunction MemberCount() {\n const { id: channelId, guild_id: guildId } = useStateFromStores([SelectedChannelStore], () => getCurrentChannel());\n const { groups } = useStateFromStores(\n [ChannelMemberStore],\n () => ChannelMemberStore.getProps(guildId, channelId)\n );\n const total = useStateFromStores(\n [GuildMemberCountStore],\n () => GuildMemberCountStore.getMemberCount(guildId)\n );\n\n if (total == null)\n return null;\n\n const online =\n (groups.length === 1 && groups[0].id === \"unknown\")\n ? 0\n : groups.reduce((count, curr) => count + (curr.id === \"offline\" ? 0 : curr.count), 0);\n\n return (\n <Flex id=\"vc-membercount\" style={{\n marginTop: \"1em\",\n paddingInline: \"1em\",\n justifyContent: \"center\",\n alignContent: \"center\",\n gap: 0\n }}>\n <Tooltip text={`${numberFormat(online)} online in this channel`} position=\"bottom\">\n {props => (\n <div {...props}>\n <span\n style={{\n backgroundColor: \"var(--green-360)\",\n width: \"12px\",\n height: \"12px\",\n borderRadius: \"50%\",\n display: \"inline-block\",\n marginRight: \"0.5em\"\n }}\n />\n <span style={{ color: \"var(--green-360)\" }}>{numberFormat(online)}</span>\n </div>\n )}\n </Tooltip>\n <Tooltip text={`${numberFormat(total)} total server members`} position=\"bottom\">\n {props => (\n <div {...props}>\n <span\n style={{\n width: \"6px\",\n height: \"6px\",\n borderRadius: \"50%\",\n border: \"3px solid var(--primary-400)\",\n display: \"inline-block\",\n marginRight: \"0.5em\",\n marginLeft: \"1em\"\n }}\n />\n <span style={{ color: \"var(--primary-400)\" }}>{numberFormat(total)}</span>\n </div>\n )}\n </Tooltip>\n </Flex>\n );\n}\n\nexport default definePlugin({\n name: \"MemberCount\",\n description: \"Shows the amount of online & total members in the server member list\",\n authors: [Devs.Ven, Devs.Commandtechno],\n\n patches: [{\n find: \"{isSidebarVisible:\",\n replacement: {\n match: /(?<=let\\{className:(\\i),.+?children):\\[(\\i\\.useMemo[^}]+\"aria-multiselectable\")/,\n replace: \":[$1?.startsWith('members')?$self.render():null,$2\"\n }\n }],\n\n render: ErrorBoundary.wrap(MemberCount, { noop: true })\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { addClickListener, removeClickListener } from \"@api/MessageEvents\";\nimport { definePluginSettings, Settings } from \"@api/Settings\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { findByPropsLazy } from \"@webpack\";\nimport { FluxDispatcher, PermissionsBits, PermissionStore, UserStore } from \"@webpack/common\";\n\nlet isDeletePressed = false;\nconst keydown = (e: KeyboardEvent) => e.key === \"Backspace\" && (isDeletePressed = true);\nconst keyup = (e: KeyboardEvent) => e.key === \"Backspace\" && (isDeletePressed = false);\n\n\nconst settings = definePluginSettings({\n enableDeleteOnClick: {\n type: OptionType.BOOLEAN,\n description: \"Enable delete on click while holding backspace\",\n default: true\n },\n enableDoubleClickToEdit: {\n type: OptionType.BOOLEAN,\n description: \"Enable double click to edit\",\n default: true\n },\n enableDoubleClickToReply: {\n type: OptionType.BOOLEAN,\n description: \"Enable double click to reply\",\n default: true\n },\n requireModifier: {\n type: OptionType.BOOLEAN,\n description: \"Only do double click actions when shift/ctrl is held\",\n default: false\n }\n});\n\nexport default definePlugin({\n name: \"MessageClickActions\",\n description: \"Hold Backspace and click to delete, double click to edit/reply\",\n authors: [Devs.Ven],\n dependencies: [\"MessageEventsAPI\"],\n\n settings,\n\n start() {\n const MessageActions = findByPropsLazy(\"deleteMessage\", \"startEditMessage\");\n const EditStore = findByPropsLazy(\"isEditing\", \"isEditingAny\");\n\n document.addEventListener(\"keydown\", keydown);\n document.addEventListener(\"keyup\", keyup);\n\n this.onClick = addClickListener((msg: any, channel, event) => {\n const isMe = msg.author.id === UserStore.getCurrentUser().id;\n if (!isDeletePressed) {\n if (event.detail < 2) return;\n if (settings.store.requireModifier && !event.ctrlKey && !event.shiftKey) return;\n if (channel.guild_id && !PermissionStore.can(PermissionsBits.SEND_MESSAGES, channel)) return;\n if (msg.deleted === true) return;\n\n if (isMe) {\n if (!settings.store.enableDoubleClickToEdit || EditStore.isEditing(channel.id, msg.id)) return;\n\n MessageActions.startEditMessage(channel.id, msg.id, msg.content);\n event.preventDefault();\n } else {\n if (!settings.store.enableDoubleClickToReply) return;\n\n const EPHEMERAL = 64;\n if (msg.hasFlag(EPHEMERAL)) return;\n\n FluxDispatcher.dispatch({\n type: \"CREATE_PENDING_REPLY\",\n channel,\n message: msg,\n shouldMention: !Settings.plugins.NoReplyMention.enabled,\n showMentionToggle: channel.guild_id !== null\n });\n }\n } else if (settings.store.enableDeleteOnClick && (isMe || PermissionStore.can(PermissionsBits.MANAGE_MESSAGES, channel))) {\n if (msg.deleted) {\n FluxDispatcher.dispatch({\n type: \"MESSAGE_DELETE\",\n channelId: channel.id,\n id: msg.id,\n mlDeleted: true\n });\n } else {\n MessageActions.deleteMessage(channel.id, msg.id);\n }\n event.preventDefault();\n }\n });\n },\n\n stop() {\n removeClickListener(this.onClick);\n document.removeEventListener(\"keydown\", keydown);\n document.removeEventListener(\"keyup\", keyup);\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nexport type AccessoryCallback = (props: Record<string, any>) => JSX.Element | null | Array<JSX.Element | null>;\nexport type Accessory = {\n callback: AccessoryCallback;\n position?: number;\n};\n\nexport const accessories = new Map<String, Accessory>();\n\nexport function addAccessory(\n identifier: string,\n callback: AccessoryCallback,\n position?: number\n) {\n accessories.set(identifier, {\n callback,\n position,\n });\n}\n\nexport function removeAccessory(identifier: string) {\n accessories.delete(identifier);\n}\n\nexport function _modifyAccessories(\n elements: JSX.Element[],\n props: Record<string, any>\n) {\n for (const accessory of accessories.values()) {\n let accessories = accessory.callback(props);\n if (accessories == null)\n continue;\n\n if (!Array.isArray(accessories))\n accessories = [accessories];\n else if (accessories.length === 0)\n continue;\n\n elements.splice(\n accessory.position != null\n ? accessory.position < 0\n ? elements.length + accessory.position\n : accessory.position\n : elements.length,\n 0,\n ...accessories.filter(e => e != null) as JSX.Element[]\n );\n }\n\n return elements;\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { addAccessory } from \"@api/MessageAccessories\";\nimport { definePluginSettings } from \"@api/Settings\";\nimport ErrorBoundary from \"@components/ErrorBoundary\";\nimport { Devs } from \"@utils/constants.js\";\nimport { classes } from \"@utils/misc\";\nimport { Queue } from \"@utils/Queue\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { findByPropsLazy, findComponentByCodeLazy } from \"@webpack\";\nimport {\n Button,\n ChannelStore,\n FluxDispatcher,\n GuildStore,\n MessageStore,\n Parser,\n PermissionStore,\n RestAPI,\n Text,\n TextAndImagesSettingsStores,\n UserStore\n} from \"@webpack/common\";\nimport { Channel, Guild, Message } from \"discord-types/general\";\n\nconst messageCache = new Map<string, {\n message?: Message;\n fetched: boolean;\n}>();\n\nconst Embed = findComponentByCodeLazy(\".inlineMediaEmbed\");\nconst AutoModEmbed = findComponentByCodeLazy(\".withFooter]:\", \"childrenMessageContent:\");\nconst ChannelMessage = findComponentByCodeLazy(\"renderSimpleAccessories)\");\n\nconst SearchResultClasses = findByPropsLazy(\"message\", \"searchResult\");\n\nconst messageLinkRegex = /(?<!<)https?:\\/\\/(?:\\w+\\.)?discord(?:app)?\\.com\\/channels\\/(\\d{17,20}|@me)\\/(\\d{17,20})\\/(\\d{17,20})/g;\nconst tenorRegex = /^https:\\/\\/(?:www\\.)?tenor\\.com\\//;\n\ninterface Attachment {\n height: number;\n width: number;\n url: string;\n proxyURL?: string;\n}\n\ninterface MessageEmbedProps {\n message: Message;\n channel: Channel;\n guildID: string;\n}\n\nconst messageFetchQueue = new Queue();\n\nconst settings = definePluginSettings({\n messageBackgroundColor: {\n description: \"Background color for messages in rich embeds\",\n type: OptionType.BOOLEAN\n },\n automodEmbeds: {\n description: \"Use automod embeds instead of rich embeds (smaller but less info)\",\n type: OptionType.SELECT,\n options: [\n {\n label: \"Always use automod embeds\",\n value: \"always\"\n },\n {\n label: \"Prefer automod embeds, but use rich embeds if some content can't be shown\",\n value: \"prefer\"\n },\n {\n label: \"Never use automod embeds\",\n value: \"never\",\n default: true\n }\n ]\n },\n listMode: {\n description: \"Whether to use ID list as blacklist or whitelist\",\n type: OptionType.SELECT,\n options: [\n {\n label: \"Blacklist\",\n value: \"blacklist\",\n default: true\n },\n {\n label: \"Whitelist\",\n value: \"whitelist\"\n }\n ]\n },\n idList: {\n description: \"Guild/channel/user IDs to blacklist or whitelist (separate with comma)\",\n type: OptionType.STRING,\n default: \"\"\n },\n clearMessageCache: {\n type: OptionType.COMPONENT,\n description: \"Clear the linked message cache\",\n component: () =>\n <Button onClick={() => messageCache.clear()}>\n Clear the linked message cache\n </Button>\n }\n});\n\n\nasync function fetchMessage(channelID: string, messageID: string) {\n const cached = messageCache.get(messageID);\n if (cached) return cached.message;\n\n messageCache.set(messageID, { fetched: false });\n\n const res = await RestAPI.get({\n url: `/channels/${channelID}/messages`,\n query: {\n limit: 1,\n around: messageID\n },\n retries: 2\n }).catch(() => null);\n\n const msg = res?.body?.[0];\n if (!msg) return;\n\n const message: Message = MessageStore.getMessages(msg.channel_id).receiveMessage(msg).get(msg.id);\n\n messageCache.set(message.id, {\n message,\n fetched: true\n });\n\n return message;\n}\n\n\nfunction getImages(message: Message): Attachment[] {\n const attachments: Attachment[] = [];\n\n for (const { content_type, height, width, url, proxy_url } of message.attachments ?? []) {\n if (content_type?.startsWith(\"image/\"))\n attachments.push({\n height: height!,\n width: width!,\n url: url,\n proxyURL: proxy_url!\n });\n }\n\n for (const { type, image, thumbnail, url } of message.embeds ?? []) {\n if (type === \"image\")\n attachments.push({ ...(image ?? thumbnail!) });\n else if (url && type === \"gifv\" && !tenorRegex.test(url))\n attachments.push({\n height: thumbnail!.height,\n width: thumbnail!.width,\n url\n });\n }\n\n return attachments;\n}\n\nfunction noContent(attachments: number, embeds: number) {\n if (!attachments && !embeds) return \"\";\n if (!attachments) return `[no content, ${embeds} embed${embeds !== 1 ? \"s\" : \"\"}]`;\n if (!embeds) return `[no content, ${attachments} attachment${attachments !== 1 ? \"s\" : \"\"}]`;\n return `[no content, ${attachments} attachment${attachments !== 1 ? \"s\" : \"\"} and ${embeds} embed${embeds !== 1 ? \"s\" : \"\"}]`;\n}\n\nfunction requiresRichEmbed(message: Message) {\n if (message.components.length) return true;\n if (message.attachments.some(a => !a.content_type?.startsWith(\"image/\"))) return true;\n if (message.embeds.some(e => e.type !== \"image\" && (e.type !== \"gifv\" || tenorRegex.test(e.url!)))) return true;\n\n return false;\n}\n\nfunction computeWidthAndHeight(width: number, height: number) {\n const maxWidth = 400;\n const maxHeight = 300;\n\n if (width > height) {\n const adjustedWidth = Math.min(width, maxWidth);\n return { width: adjustedWidth, height: Math.round(height / (width / adjustedWidth)) };\n }\n\n const adjustedHeight = Math.min(height, maxHeight);\n return { width: Math.round(width / (height / adjustedHeight)), height: adjustedHeight };\n}\n\nfunction withEmbeddedBy(message: Message, embeddedBy: string[]) {\n return new Proxy(message, {\n get(_, prop) {\n if (prop === \"vencordEmbeddedBy\") return embeddedBy;\n // @ts-ignore ts so bad\n return Reflect.get(...arguments);\n }\n });\n}\n\n\nfunction MessageEmbedAccessory({ message }: { message: Message; }) {\n // @ts-ignore\n const embeddedBy: string[] = message.vencordEmbeddedBy ?? [];\n\n const accessories = [] as (JSX.Element | null)[];\n\n let match = null as RegExpMatchArray | null;\n while ((match = messageLinkRegex.exec(message.content!)) !== null) {\n const [_, guildID, channelID, messageID] = match;\n if (embeddedBy.includes(messageID)) {\n continue;\n }\n\n const linkedChannel = ChannelStore.getChannel(channelID);\n if (!linkedChannel || (guildID !== \"@me\" && !PermissionStore.can(1024n /* view channel */, linkedChannel))) {\n continue;\n }\n\n const { listMode, idList } = settings.store;\n\n const isListed = [guildID, channelID, message.author.id].some(id => id && idList.includes(id));\n\n if (listMode === \"blacklist\" && isListed) continue;\n if (listMode === \"whitelist\" && !isListed) continue;\n\n let linkedMessage = messageCache.get(messageID)?.message;\n if (!linkedMessage) {\n linkedMessage ??= MessageStore.getMessage(channelID, messageID);\n if (linkedMessage) {\n messageCache.set(messageID, { message: linkedMessage, fetched: true });\n } else {\n const msg = { ...message } as any;\n delete msg.embeds;\n delete msg.interaction;\n\n messageFetchQueue.push(() => fetchMessage(channelID, messageID)\n .then(m => m && FluxDispatcher.dispatch({\n type: \"MESSAGE_UPDATE\",\n message: msg\n }))\n );\n continue;\n }\n }\n\n const messageProps: MessageEmbedProps = {\n message: withEmbeddedBy(linkedMessage, [...embeddedBy, message.id]),\n channel: linkedChannel,\n guildID\n };\n\n const type = settings.store.automodEmbeds;\n accessories.push(\n type === \"always\" || (type === \"prefer\" && !requiresRichEmbed(linkedMessage))\n ? <AutomodEmbedAccessory {...messageProps} />\n : <ChannelMessageEmbedAccessory {...messageProps} />\n );\n }\n\n return accessories.length ? <>{accessories}</> : null;\n}\n\nfunction ChannelMessageEmbedAccessory({ message, channel, guildID }: MessageEmbedProps): JSX.Element | null {\n const isDM = guildID === \"@me\";\n\n const guild = !isDM && GuildStore.getGuild(channel.guild_id);\n const dmReceiver = UserStore.getUser(ChannelStore.getChannel(channel.id).recipients?.[0]);\n\n\n return <Embed\n embed={{\n rawDescription: \"\",\n color: \"var(--background-secondary)\",\n author: {\n name: <Text variant=\"text-xs/medium\" tag=\"span\">\n <span>{isDM ? \"Direct Message - \" : (guild as Guild).name + \" - \"}</span>\n {isDM\n ? Parser.parse(`<@${dmReceiver.id}>`)\n : Parser.parse(`<#${channel.id}>`)\n }\n </Text>,\n iconProxyURL: guild\n ? `https://${window.GLOBAL_ENV.CDN_HOST}/icons/${guild.id}/${guild.icon}.png`\n : `https://${window.GLOBAL_ENV.CDN_HOST}/avatars/${dmReceiver.id}/${dmReceiver.avatar}`\n }\n }}\n renderDescription={() => (\n <div key={message.id} className={classes(SearchResultClasses.message, settings.store.messageBackgroundColor && SearchResultClasses.searchResult)}>\n <ChannelMessage\n id={`message-link-embeds-${message.id}`}\n message={message}\n channel={channel}\n subscribeToComponentDispatch={false}\n />\n </div>\n )}\n />;\n}\n\nfunction AutomodEmbedAccessory(props: MessageEmbedProps): JSX.Element | null {\n const { message, channel, guildID } = props;\n const compact = TextAndImagesSettingsStores.MessageDisplayCompact.useSetting();\n const isDM = guildID === \"@me\";\n const images = getImages(message);\n const { parse } = Parser;\n\n return <AutoModEmbed\n channel={channel}\n childrenAccessories={\n <Text color=\"text-muted\" variant=\"text-xs/medium\" tag=\"span\">\n {isDM\n ? parse(`<@${ChannelStore.getChannel(channel.id).recipients[0]}>`)\n : parse(`<#${channel.id}>`)\n }\n <span>{isDM ? \" - Direct Message\" : \" - \" + GuildStore.getGuild(channel.guild_id)?.name}</span>\n </Text>\n }\n compact={compact}\n content={\n <>\n {message.content || message.attachments.length <= images.length\n ? parse(message.content)\n : [noContent(message.attachments.length, message.embeds.length)]\n }\n {images.map(a => {\n const { width, height } = computeWidthAndHeight(a.width, a.height);\n return (\n <div>\n <img src={a.url} width={width} height={height} />\n </div>\n );\n })}\n </>\n }\n hideTimestamp={false}\n message={message}\n _messageEmbed=\"automod\"\n />;\n}\n\nexport default definePlugin({\n name: \"MessageLinkEmbeds\",\n description: \"Adds a preview to messages that link another message\",\n authors: [Devs.TheSun, Devs.Ven, Devs.RyanCaoDev],\n dependencies: [\"MessageAccessoriesAPI\"],\n\n settings,\n\n start() {\n addAccessory(\"messageLinkEmbed\", props => {\n if (!messageLinkRegex.test(props.message.content))\n return null;\n\n // need to reset the regex because it's global\n messageLinkRegex.lastIndex = 0;\n\n return (\n <ErrorBoundary>\n <MessageEmbedAccessory\n message={props.message}\n />\n </ErrorBoundary>\n );\n }, 4 /* just above rich embeds */);\n },\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\n(window.VencordStyles ??= new Map()).set(\"src/plugins/messageLogger/deleteStyleOverlay.css\", {\n name: \"src/plugins/messageLogger/deleteStyleOverlay.css\",\n source: \".messagelogger-deleted {\\n background-color: rgba(240 71 71 / 15%) !important;\\n}\\n\",\n classNames: {},\n dom: null,\n});\n\nexport default \"src/plugins/messageLogger/deleteStyleOverlay.css\";\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\n(window.VencordStyles ??= new Map()).set(\"src/plugins/messageLogger/deleteStyleText.css\", {\n name: \"src/plugins/messageLogger/deleteStyleText.css\",\n source: \"/* Message content highlighting */\\n.messagelogger-deleted [class*=\\\"contents\\\"] > :is(div, h1, h2, h3, p) {\\n color: #f04747 !important;\\n}\\n\\n/* Bot \\\"thinking\\\" text highlighting */\\n.messagelogger-deleted [class*=\\\"colorStandard\\\"] {\\n color: #f04747 !important;\\n}\\n\\n/* Embed highlighting */\\n.messagelogger-deleted article :is(div, span, h1, h2, h3, p) {\\n color: #f04747 !important;\\n}\\n\\n.messagelogger-deleted a {\\n color: #be3535 !important;\\n text-decoration: underline;\\n}\\n\",\n classNames: {},\n dom: null,\n});\n\nexport default \"src/plugins/messageLogger/deleteStyleText.css\";\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport \"./messageLogger.css\";\n\nimport { addContextMenuPatch, NavContextMenuPatchCallback, removeContextMenuPatch } from \"@api/ContextMenu\";\nimport { Settings } from \"@api/Settings\";\nimport { disableStyle, enableStyle } from \"@api/Styles\";\nimport ErrorBoundary from \"@components/ErrorBoundary\";\nimport { Devs } from \"@utils/constants\";\nimport { Logger } from \"@utils/Logger\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { findByPropsLazy } from \"@webpack\";\nimport { ChannelStore, FluxDispatcher, i18n, Menu, moment, Parser, Timestamp, UserStore } from \"@webpack/common\";\n\nimport overlayStyle from \"./deleteStyleOverlay.css?managed\";\nimport textStyle from \"./deleteStyleText.css?managed\";\n\nconst styles = findByPropsLazy(\"edited\", \"communicationDisabled\", \"isSystemMessage\");\n\nfunction addDeleteStyle() {\n if (Settings.plugins.MessageLogger.deleteStyle === \"text\") {\n enableStyle(textStyle);\n disableStyle(overlayStyle);\n } else {\n disableStyle(textStyle);\n enableStyle(overlayStyle);\n }\n}\n\nconst REMOVE_HISTORY_ID = \"ml-remove-history\";\nconst TOGGLE_DELETE_STYLE_ID = \"ml-toggle-style\";\nconst patchMessageContextMenu: NavContextMenuPatchCallback = (children, props) => () => {\n const { message } = props;\n const { deleted, editHistory, id, channel_id } = message;\n\n if (!deleted && !editHistory?.length) return;\n\n toggle: {\n if (!deleted) break toggle;\n\n const domElement = document.getElementById(`chat-messages-${channel_id}-${id}`);\n if (!domElement) break toggle;\n\n children.push((\n <Menu.MenuItem\n id={TOGGLE_DELETE_STYLE_ID}\n key={TOGGLE_DELETE_STYLE_ID}\n label=\"Toggle Deleted Highlight\"\n action={() => domElement.classList.toggle(\"messagelogger-deleted\")}\n />\n ));\n }\n\n children.push((\n <Menu.MenuItem\n id={REMOVE_HISTORY_ID}\n key={REMOVE_HISTORY_ID}\n label=\"Remove Message History\"\n color=\"danger\"\n action={() => {\n if (deleted) {\n FluxDispatcher.dispatch({\n type: \"MESSAGE_DELETE\",\n channelId: channel_id,\n id,\n mlDeleted: true\n });\n } else {\n message.editHistory = [];\n }\n }}\n />\n ));\n};\n\nexport default definePlugin({\n name: \"MessageLogger\",\n description: \"Temporarily logs deleted and edited messages.\",\n authors: [Devs.rushii, Devs.Ven, Devs.AutumnVN],\n\n start() {\n addDeleteStyle();\n addContextMenuPatch(\"message\", patchMessageContextMenu);\n },\n\n stop() {\n removeContextMenuPatch(\"message\", patchMessageContextMenu);\n },\n\n renderEdit(edit: { timestamp: any, content: string; }) {\n return (\n <ErrorBoundary noop>\n <div className=\"messagelogger-edited\">\n {Parser.parse(edit.content)}\n <Timestamp\n timestamp={edit.timestamp}\n isEdited={true}\n isInline={false}\n >\n <span className={styles.edited}>{\" \"}({i18n.Messages.MESSAGE_EDITED})</span>\n </Timestamp>\n </div>\n </ErrorBoundary>\n );\n },\n\n makeEdit(newMessage: any, oldMessage: any): any {\n return {\n timestamp: moment?.call(newMessage.edited_timestamp),\n content: oldMessage.content\n };\n },\n\n options: {\n deleteStyle: {\n type: OptionType.SELECT,\n description: \"The style of deleted messages\",\n default: \"text\",\n options: [\n { label: \"Red text\", value: \"text\", default: true },\n { label: \"Red overlay\", value: \"overlay\" }\n ],\n onChange: () => addDeleteStyle()\n },\n ignoreBots: {\n type: OptionType.BOOLEAN,\n description: \"Whether to ignore messages by bots\",\n default: false\n },\n ignoreSelf: {\n type: OptionType.BOOLEAN,\n description: \"Whether to ignore messages by yourself\",\n default: false\n },\n ignoreUsers: {\n type: OptionType.STRING,\n description: \"Comma-separated list of user IDs to ignore\",\n default: \"\"\n },\n ignoreChannels: {\n type: OptionType.STRING,\n description: \"Comma-separated list of channel IDs to ignore\",\n default: \"\"\n },\n ignoreGuilds: {\n type: OptionType.STRING,\n description: \"Comma-separated list of guild IDs to ignore\",\n default: \"\"\n },\n },\n\n handleDelete(cache: any, data: { ids: string[], id: string; mlDeleted?: boolean; }, isBulk: boolean) {\n try {\n if (cache == null || (!isBulk && !cache.has(data.id))) return cache;\n\n const mutate = (id: string) => {\n const msg = cache.get(id);\n if (!msg) return;\n\n const EPHEMERAL = 64;\n const shouldIgnore = data.mlDeleted ||\n (msg.flags & EPHEMERAL) === EPHEMERAL ||\n this.shouldIgnore(msg);\n\n if (shouldIgnore) {\n cache = cache.remove(id);\n } else {\n cache = cache.update(id, m => m\n .set(\"deleted\", true)\n .set(\"attachments\", m.attachments.map(a => (a.deleted = true, a))));\n }\n };\n\n if (isBulk) {\n data.ids.forEach(mutate);\n } else {\n mutate(data.id);\n }\n } catch (e) {\n new Logger(\"MessageLogger\").error(\"Error during handleDelete\", e);\n }\n return cache;\n },\n\n shouldIgnore(message: any) {\n const { ignoreBots, ignoreSelf, ignoreUsers, ignoreChannels, ignoreGuilds } = Settings.plugins.MessageLogger;\n const myId = UserStore.getCurrentUser().id;\n\n return ignoreBots && message.author?.bot ||\n ignoreSelf && message.author?.id === myId ||\n ignoreUsers.includes(message.author?.id) ||\n ignoreChannels.includes(message.channel_id) ||\n ignoreChannels.includes(ChannelStore.getChannel(message.channel_id)?.parent_id) ||\n ignoreGuilds.includes(ChannelStore.getChannel(message.channel_id)?.guild_id);\n },\n\n // Based on canary 63b8f1b4f2025213c5cf62f0966625bee3d53136\n patches: [\n {\n // MessageStore\n // Module 171447\n find: \"displayName=\\\"MessageStore\\\"\",\n replacement: [\n {\n // Add deleted=true to all target messages in the MESSAGE_DELETE event\n match: /MESSAGE_DELETE:function\\((\\i)\\){let.+?((?:\\i\\.){2})getOrCreate.+?},/,\n replace:\n \"MESSAGE_DELETE:function($1){\" +\n \" var cache = $2getOrCreate($1.channelId);\" +\n \" cache = $self.handleDelete(cache, $1, false);\" +\n \" $2commit(cache);\" +\n \"},\"\n },\n {\n // Add deleted=true to all target messages in the MESSAGE_DELETE_BULK event\n match: /MESSAGE_DELETE_BULK:function\\((\\i)\\){let.+?((?:\\i\\.){2})getOrCreate.+?},/,\n replace:\n \"MESSAGE_DELETE_BULK:function($1){\" +\n \" var cache = $2getOrCreate($1.channelId);\" +\n \" cache = $self.handleDelete(cache, $1, true);\" +\n \" $2commit(cache);\" +\n \"},\"\n },\n {\n // Add current cached content + new edit time to cached message's editHistory\n match: /(MESSAGE_UPDATE:function\\((\\i)\\).+?)\\.update\\((\\i)/,\n replace: \"$1\" +\n \".update($3,m =>\" +\n \" (($2.message.flags & 64) === 64 || $self.shouldIgnore($2.message)) ? m :\" +\n \" $2.message.content !== m.editHistory?.[0]?.content && $2.message.content !== m.content ?\" +\n \" m.set('editHistory',[...(m.editHistory || []), $self.makeEdit($2.message, m)]) :\" +\n \" m\" +\n \")\" +\n \".update($3\"\n },\n {\n // fix up key (edit last message) attempting to edit a deleted message\n match: /(?<=getLastEditableMessage\\(\\i\\)\\{.{0,200}\\.find\\((\\i)=>)/,\n replace: \"!$1.deleted &&\"\n }\n ]\n },\n\n {\n // Message domain model\n // Module 451\n find: \"}addReaction(\",\n replacement: [\n {\n match: /this\\.customRenderedContent=(\\i)\\.customRenderedContent,/,\n replace: \"this.customRenderedContent = $1.customRenderedContent,\" +\n \"this.deleted = $1.deleted || false,\" +\n \"this.editHistory = $1.editHistory || [],\"\n }\n ]\n },\n\n {\n // Updated message transformer(?)\n // Module 819525\n find: \"THREAD_STARTER_MESSAGE?null===\",\n replacement: [\n // {\n // // DEBUG: Log the params of the target function to the patch below\n // match: /function N\\(e,t\\){/,\n // replace: \"function L(e,t){console.log('pre-transform', e, t);\"\n // },\n {\n // Pass through editHistory & deleted & original attachments to the \"edited message\" transformer\n match: /interactionData:(\\i)\\.interactionData/,\n replace:\n \"interactionData:$1.interactionData,\" +\n \"deleted:$1.deleted,\" +\n \"editHistory:$1.editHistory,\" +\n \"attachments:$1.attachments\"\n },\n\n // {\n // // DEBUG: Log the params of the target function to the patch below\n // match: /function R\\(e\\){/,\n // replace: \"function R(e){console.log('after-edit-transform', arguments);\"\n // },\n {\n // Construct new edited message and add editHistory & deleted (ref above)\n // Pass in custom data to attachment parser to mark attachments deleted as well\n match: /attachments:(\\i)\\((\\i)\\)/,\n replace:\n \"attachments: $1((() => {\" +\n \" if ($self.shouldIgnore($2)) return $2;\" +\n \" let old = arguments[1]?.attachments;\" +\n \" if (!old) return $2;\" +\n \" let new_ = $2.attachments?.map(a => a.id) ?? [];\" +\n \" let diff = old.filter(a => !new_.includes(a.id));\" +\n \" old.forEach(a => a.deleted = true);\" +\n \" $2.attachments = [...diff, ...$2.attachments];\" +\n \" return $2;\" +\n \"})()),\" +\n \"deleted: arguments[1]?.deleted,\" +\n \"editHistory: arguments[1]?.editHistory\"\n },\n {\n // Preserve deleted attribute on attachments\n match: /(\\((\\i)\\){return null==\\2\\.attachments.+?)spoiler:/,\n replace:\n \"$1deleted: arguments[0]?.deleted,\" +\n \"spoiler:\"\n }\n ]\n },\n\n {\n // Attachment renderer\n // Module 96063\n find: \".removeAttachmentHoverButton\",\n group: true,\n replacement: [\n {\n match: /(className:\\i,attachment:\\i),/,\n replace: \"$1,attachment: {deleted},\"\n },\n {\n match: /\\[\\i\\.obscured\\]:.+?,/,\n replace: \"$& 'messagelogger-deleted-attachment': deleted,\"\n }\n ]\n },\n\n {\n // Base message component renderer\n // Module 748241\n find: \"Message must not be a thread starter message\",\n replacement: [\n {\n // Append messagelogger-deleted to classNames if deleted\n match: /\\)\\(\"li\",\\{(.+?),className:/,\n replace: \")(\\\"li\\\",{$1,className:(arguments[0].message.deleted ? \\\"messagelogger-deleted \\\" : \\\"\\\")+\"\n }\n ]\n },\n\n {\n // Message content renderer\n // Module 43016\n find: \"Messages.MESSAGE_EDITED,\\\")\\\"\",\n replacement: [\n {\n // Render editHistory in the deepest div for message content\n match: /(\\)\\(\"div\",\\{id:.+?children:\\[)/,\n replace: \"$1 (arguments[0].message.editHistory?.length > 0 ? arguments[0].message.editHistory.map(edit => $self.renderEdit(edit)) : null), \"\n }\n ]\n },\n\n {\n // ReferencedMessageStore\n // Module 778667\n find: \"displayName=\\\"ReferencedMessageStore\\\"\",\n replacement: [\n {\n match: /MESSAGE_DELETE:function\\((\\i)\\).+?},/,\n replace: \"MESSAGE_DELETE:function($1){},\"\n },\n {\n match: /MESSAGE_DELETE_BULK:function\\((\\i)\\).+?},/,\n replace: \"MESSAGE_DELETE_BULK:function($1){},\"\n }\n ]\n },\n\n {\n // Message context base menu\n // Module 600300\n find: \"useMessageMenu:\",\n replacement: [\n {\n // Remove the first section if message is deleted\n match: /children:(\\[\"\"===.+?\\])/,\n replace: \"children:arguments[0].message.deleted?[]:$1\"\n }\n ]\n }\n\n // {\n // // MessageStore caching internals\n // // Module 819525\n // find: \"e.getOrCreate=function(t)\",\n // replacement: [\n // // {\n // // // DEBUG: log getOrCreate return values from MessageStore caching internals\n // // match: /getOrCreate=function(.+?)return/,\n // // replace: \"getOrCreate=function$1console.log('getOrCreate',n);return\"\n // // }\n // ]\n // }\n ]\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { ApplicationCommandInputType, ApplicationCommandOptionType, findOption, registerCommand, sendBotMessage, unregisterCommand } from \"@api/Commands\";\nimport * as DataStore from \"@api/DataStore\";\nimport { Settings } from \"@api/Settings\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin, { OptionType } from \"@utils/types\";\n\nconst EMOTE = \"<:luna:1035316192220553236>\";\nconst DATA_KEY = \"MessageTags_TAGS\";\nconst MessageTagsMarker = Symbol(\"MessageTags\");\n\ninterface Tag {\n name: string;\n message: string;\n enabled: boolean;\n}\n\nconst getTags = () => DataStore.get(DATA_KEY).then<Tag[]>(t => t ?? []);\nconst getTag = (name: string) => DataStore.get(DATA_KEY).then<Tag | null>((t: Tag[]) => (t ?? []).find((tt: Tag) => tt.name === name) ?? null);\nconst addTag = async (tag: Tag) => {\n const tags = await getTags();\n tags.push(tag);\n DataStore.set(DATA_KEY, tags);\n return tags;\n};\nconst removeTag = async (name: string) => {\n let tags = await getTags();\n tags = await tags.filter((t: Tag) => t.name !== name);\n DataStore.set(DATA_KEY, tags);\n return tags;\n};\n\nfunction createTagCommand(tag: Tag) {\n registerCommand({\n name: tag.name,\n description: tag.name,\n inputType: ApplicationCommandInputType.BUILT_IN_TEXT,\n execute: async (_, ctx) => {\n if (!await getTag(tag.name)) {\n sendBotMessage(ctx.channel.id, {\n content: `${EMOTE} The tag **${tag.name}** does not exist anymore! Please reload ur Discord to fix :)`\n });\n return { content: `/${tag.name}` };\n }\n\n if (Settings.plugins.MessageTags.clyde) sendBotMessage(ctx.channel.id, {\n content: `${EMOTE} The tag **${tag.name}** has been sent!`\n });\n return { content: tag.message.replaceAll(\"\\\\n\", \"\\n\") };\n },\n [MessageTagsMarker]: true,\n }, \"CustomTags\");\n}\n\n\nexport default definePlugin({\n name: \"MessageTags\",\n description: \"Allows you to save messages and to use them with a simple command.\",\n authors: [Devs.Luna],\n options: {\n clyde: {\n name: \"Clyde message on send\",\n description: \"If enabled, clyde will send you an ephemeral message when a tag was used.\",\n type: OptionType.BOOLEAN,\n default: true\n }\n },\n dependencies: [\"CommandsAPI\"],\n\n async start() {\n for (const tag of await getTags()) createTagCommand(tag);\n },\n\n commands: [\n {\n name: \"tags\",\n description: \"Manage all the tags for yourself\",\n inputType: ApplicationCommandInputType.BUILT_IN,\n options: [\n {\n name: \"create\",\n description: \"Create a new tag\",\n type: ApplicationCommandOptionType.SUB_COMMAND,\n options: [\n {\n name: \"tag-name\",\n description: \"The name of the tag to trigger the response\",\n type: ApplicationCommandOptionType.STRING,\n required: true\n },\n {\n name: \"message\",\n description: \"The message that you will send when using this tag\",\n type: ApplicationCommandOptionType.STRING,\n required: true\n }\n ]\n },\n {\n name: \"list\",\n description: \"List all tags from yourself\",\n type: ApplicationCommandOptionType.SUB_COMMAND,\n options: []\n },\n {\n name: \"delete\",\n description: \"Remove a tag from your yourself\",\n type: ApplicationCommandOptionType.SUB_COMMAND,\n options: [\n {\n name: \"tag-name\",\n description: \"The name of the tag to trigger the response\",\n type: ApplicationCommandOptionType.STRING,\n required: true\n }\n ]\n },\n {\n name: \"preview\",\n description: \"Preview a tag without sending it publicly\",\n type: ApplicationCommandOptionType.SUB_COMMAND,\n options: [\n {\n name: \"tag-name\",\n description: \"The name of the tag to trigger the response\",\n type: ApplicationCommandOptionType.STRING,\n required: true\n }\n ]\n }\n ],\n\n async execute(args, ctx) {\n\n switch (args[0].name) {\n case \"create\": {\n const name: string = findOption(args[0].options, \"tag-name\", \"\");\n const message: string = findOption(args[0].options, \"message\", \"\");\n\n if (await getTag(name))\n return sendBotMessage(ctx.channel.id, {\n content: `${EMOTE} A Tag with the name **${name}** already exists!`\n });\n\n const tag = {\n name: name,\n enabled: true,\n message: message\n };\n\n createTagCommand(tag);\n await addTag(tag);\n\n sendBotMessage(ctx.channel.id, {\n content: `${EMOTE} Successfully created the tag **${name}**!`\n });\n break; // end 'create'\n }\n case \"delete\": {\n const name: string = findOption(args[0].options, \"tag-name\", \"\");\n\n if (!await getTag(name))\n return sendBotMessage(ctx.channel.id, {\n content: `${EMOTE} A Tag with the name **${name}** does not exist!`\n });\n\n unregisterCommand(name);\n await removeTag(name);\n\n sendBotMessage(ctx.channel.id, {\n content: `${EMOTE} Successfully deleted the tag **${name}**!`\n });\n break; // end 'delete'\n }\n case \"list\": {\n sendBotMessage(ctx.channel.id, {\n embeds: [\n {\n // @ts-ignore\n title: \"All Tags:\",\n // @ts-ignore\n description: (await getTags())\n .map(tag => `\\`${tag.name}\\`: ${tag.message.slice(0, 72).replaceAll(\"\\\\n\", \" \")}${tag.message.length > 72 ? \"...\" : \"\"}`)\n .join(\"\\n\") || `${EMOTE} Woops! There are no tags yet, use \\`/tags create\\` to create one!`,\n // @ts-ignore\n color: 0xd77f7f,\n type: \"rich\",\n }\n ]\n });\n break; // end 'list'\n }\n case \"preview\": {\n const name: string = findOption(args[0].options, \"tag-name\", \"\");\n const tag = await getTag(name);\n\n if (!tag)\n return sendBotMessage(ctx.channel.id, {\n content: `${EMOTE} A Tag with the name **${name}** does not exist!`\n });\n\n sendBotMessage(ctx.channel.id, {\n content: tag.message.replaceAll(\"\\\\n\", \"\\n\")\n });\n break; // end 'preview'\n }\n\n default: {\n sendBotMessage(ctx.channel.id, {\n content: \"Invalid sub-command\"\n });\n break;\n }\n }\n }\n }\n ]\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated, Samu and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { ApplicationCommandInputType, findOption, OptionalMessageOption, RequiredMessageOption, sendBotMessage } from \"@api/Commands\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\n\n\nfunction mock(input: string): string {\n let output = \"\";\n for (let i = 0; i < input.length; i++) {\n output += i % 2 ? input[i].toUpperCase() : input[i].toLowerCase();\n }\n return output;\n}\n\nexport default definePlugin({\n name: \"MoreCommands\",\n description: \"echo, lenny, mock\",\n authors: [Devs.Arjix, Devs.echo, Devs.Samu],\n dependencies: [\"CommandsAPI\"],\n commands: [\n {\n name: \"echo\",\n description: \"Sends a message as Clyde (locally)\",\n options: [OptionalMessageOption],\n inputType: ApplicationCommandInputType.BOT,\n execute: (opts, ctx) => {\n const content = findOption(opts, \"message\", \"\");\n\n sendBotMessage(ctx.channel.id, { content });\n },\n },\n {\n name: \"lenny\",\n description: \"Sends a lenny face\",\n options: [OptionalMessageOption],\n execute: opts => ({\n content: findOption(opts, \"message\", \"\") + \" ( \u0361\u00B0 \u035C\u0296 \u0361\u00B0)\"\n }),\n },\n {\n name: \"mock\",\n description: \"mOcK PeOpLe\",\n options: [RequiredMessageOption],\n execute: opts => ({\n content: mock(findOption(opts, \"message\", \"\"))\n }),\n },\n ]\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { findOption, OptionalMessageOption } from \"@api/Commands\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\n\nexport default definePlugin({\n name: \"MoreKaomoji\",\n description: \"Adds more Kaomoji to discord. \u30FD(\u00B4\u25BD`)/\",\n authors: [Devs.JacobTm],\n dependencies: [\"CommandsAPI\"],\n commands: [\n { name: \"dissatisfaction\", description: \" \uFF1E\uFE4F\uFF1C\" },\n { name: \"smug\", description: \" \u0CA0_\u0CA0\" },\n { name: \"happy\", description: \" \u30FD(\u00B4\u25BD`)/\" },\n { name: \"crying\", description: \" \u0CA5_\u0CA5\" },\n { name: \"angry\", description: \" \u30FD(\uFF40\u0414\u00B4)\uFF89\" },\n { name: \"anger\", description: \" \u30FD(\uFF4F`\u76BF\u2032\uFF4F)\uFF89\" },\n { name: \"joy\", description: \" <(\uFFE3\uFE36\uFFE3)>\" },\n { name: \"blush\", description: \"\u0AEE \u02F6\u1D54 \u1D55 \u1D54\u02F6 \u10D0\" },\n { name: \"confused\", description: \"(\u2022\u0E34_\u2022\u0E34)?\" },\n { name: \"sleeping\", description: \"(\u1D17_\u1D17)\" },\n { name: \"laughing\", description: \"o(\u2267\u25BD\u2266)o\" },\n\n ].map(data => ({\n ...data,\n options: [OptionalMessageOption],\n execute: opts => ({\n content: findOption(opts, \"message\", \"\") + data.description\n })\n }))\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { definePluginSettings } from \"@api/Settings\";\nimport { Flex } from \"@components/Flex\";\nimport { Devs } from \"@utils/constants\";\nimport { Margins } from \"@utils/margins\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { findByPropsLazy, findLazy } from \"@webpack\";\nimport { Card, ChannelStore, Forms, GuildStore, PermissionsBits, Switch, TextInput, Tooltip, useState } from \"@webpack/common\";\nimport { RC } from \"@webpack/types\";\nimport { Channel, Message, User } from \"discord-types/general\";\n\ntype PermissionName = \"CREATE_INSTANT_INVITE\" | \"KICK_MEMBERS\" | \"BAN_MEMBERS\" | \"ADMINISTRATOR\" | \"MANAGE_CHANNELS\" | \"MANAGE_GUILD\" | \"CHANGE_NICKNAME\" | \"MANAGE_NICKNAMES\" | \"MANAGE_ROLES\" | \"MANAGE_WEBHOOKS\" | \"MANAGE_GUILD_EXPRESSIONS\" | \"CREATE_GUILD_EXPRESSIONS\" | \"VIEW_AUDIT_LOG\" | \"VIEW_CHANNEL\" | \"VIEW_GUILD_ANALYTICS\" | \"VIEW_CREATOR_MONETIZATION_ANALYTICS\" | \"MODERATE_MEMBERS\" | \"SEND_MESSAGES\" | \"SEND_TTS_MESSAGES\" | \"MANAGE_MESSAGES\" | \"EMBED_LINKS\" | \"ATTACH_FILES\" | \"READ_MESSAGE_HISTORY\" | \"MENTION_EVERYONE\" | \"USE_EXTERNAL_EMOJIS\" | \"ADD_REACTIONS\" | \"USE_APPLICATION_COMMANDS\" | \"MANAGE_THREADS\" | \"CREATE_PUBLIC_THREADS\" | \"CREATE_PRIVATE_THREADS\" | \"USE_EXTERNAL_STICKERS\" | \"SEND_MESSAGES_IN_THREADS\" | \"CONNECT\" | \"SPEAK\" | \"MUTE_MEMBERS\" | \"DEAFEN_MEMBERS\" | \"MOVE_MEMBERS\" | \"USE_VAD\" | \"PRIORITY_SPEAKER\" | \"STREAM\" | \"USE_EMBEDDED_ACTIVITIES\" | \"USE_SOUNDBOARD\" | \"USE_EXTERNAL_SOUNDS\" | \"REQUEST_TO_SPEAK\" | \"MANAGE_EVENTS\" | \"CREATE_EVENTS\";\n\ninterface Tag {\n // name used for identifying, must be alphanumeric + underscores\n name: string;\n // name shown on the tag itself, can be anything probably; automatically uppercase'd\n displayName: string;\n description: string;\n permissions?: PermissionName[];\n condition?(message: Message | null, user: User, channel: Channel): boolean;\n}\n\ninterface TagSetting {\n text: string;\n showInChat: boolean;\n showInNotChat: boolean;\n}\ninterface TagSettings {\n WEBHOOK: TagSetting,\n OWNER: TagSetting,\n ADMINISTRATOR: TagSetting,\n MODERATOR_STAFF: TagSetting,\n MODERATOR: TagSetting,\n VOICE_MODERATOR: TagSetting,\n [k: string]: TagSetting;\n}\n\n// PermissionStore.computePermissions is not the same function and doesn't work here\nconst PermissionUtil = findByPropsLazy(\"computePermissions\", \"canEveryoneRole\") as {\n computePermissions({ ...args }): bigint;\n};\n\nconst Tag = findLazy(m => m.Types?.[0] === \"BOT\") as RC<{ type?: number, className?: string, useRemSizes?: boolean; }> & { Types: Record<string, number>; };\n\nconst isWebhook = (message: Message, user: User) => !!message?.webhookId && user.isNonUserBot();\n\nconst tags: Tag[] = [\n {\n name: \"WEBHOOK\",\n displayName: \"Webhook\",\n description: \"Messages sent by webhooks\",\n condition: isWebhook\n }, {\n name: \"OWNER\",\n displayName: \"Owner\",\n description: \"Owns the server\",\n condition: (_, user, channel) => GuildStore.getGuild(channel?.guild_id)?.ownerId === user.id\n }, {\n name: \"ADMINISTRATOR\",\n displayName: \"Admin\",\n description: \"Has the administrator permission\",\n permissions: [\"ADMINISTRATOR\"]\n }, {\n name: \"MODERATOR_STAFF\",\n displayName: \"Staff\",\n description: \"Can manage the server, channels or roles\",\n permissions: [\"MANAGE_GUILD\", \"MANAGE_CHANNELS\", \"MANAGE_ROLES\"]\n }, {\n name: \"MODERATOR\",\n displayName: \"Mod\",\n description: \"Can manage messages or kick/ban people\",\n permissions: [\"MANAGE_MESSAGES\", \"KICK_MEMBERS\", \"BAN_MEMBERS\"]\n }, {\n name: \"VOICE_MODERATOR\",\n displayName: \"VC Mod\",\n description: \"Can manage voice chats\",\n permissions: [\"MOVE_MEMBERS\", \"MUTE_MEMBERS\", \"DEAFEN_MEMBERS\"]\n }\n];\nconst defaultSettings = Object.fromEntries(\n tags.map(({ name, displayName }) => [name, { text: displayName, showInChat: true, showInNotChat: true }])\n) as TagSettings;\n\nfunction SettingsComponent(props: { setValue(v: any): void; }) {\n settings.store.tagSettings ??= defaultSettings;\n\n const [tagSettings, setTagSettings] = useState(settings.store.tagSettings as TagSettings);\n const setValue = (v: TagSettings) => {\n setTagSettings(v);\n props.setValue(v);\n };\n\n return (\n <Flex flexDirection=\"column\">\n {tags.map(t => (\n <Card style={{ padding: \"1em 1em 0\" }}>\n <Forms.FormTitle style={{ width: \"fit-content\" }}>\n <Tooltip text={t.description}>\n {({ onMouseEnter, onMouseLeave }) => (\n <div\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n >\n {t.displayName} Tag <Tag type={Tag.Types[t.name]} />\n </div>\n )}\n </Tooltip>\n </Forms.FormTitle>\n\n <TextInput\n type=\"text\"\n value={tagSettings[t.name]?.text ?? t.displayName}\n placeholder={`Text on tag (default: ${t.displayName})`}\n onChange={v => {\n tagSettings[t.name].text = v;\n setValue(tagSettings);\n }}\n className={Margins.bottom16}\n />\n\n <Switch\n value={tagSettings[t.name]?.showInChat ?? true}\n onChange={v => {\n tagSettings[t.name].showInChat = v;\n setValue(tagSettings);\n }}\n hideBorder\n >\n Show in messages\n </Switch>\n\n <Switch\n value={tagSettings[t.name]?.showInNotChat ?? true}\n onChange={v => {\n tagSettings[t.name].showInNotChat = v;\n setValue(tagSettings);\n }}\n hideBorder\n >\n Show in member list and profiles\n </Switch>\n </Card>\n ))}\n </Flex>\n );\n}\n\nconst settings = definePluginSettings({\n dontShowForBots: {\n description: \"Don't show extra tags for bots (excluding webhooks)\",\n type: OptionType.BOOLEAN\n },\n dontShowBotTag: {\n description: \"Only show extra tags for bots / Hide [BOT] text\",\n type: OptionType.BOOLEAN\n },\n tagSettings: {\n type: OptionType.COMPONENT,\n component: SettingsComponent,\n description: \"fill me\",\n }\n});\n\nexport default definePlugin({\n name: \"MoreUserTags\",\n description: \"Adds tags for webhooks and moderative roles (owner, admin, etc.)\",\n authors: [Devs.Cyn, Devs.TheSun, Devs.RyanCaoDev, Devs.LordElias, Devs.AutumnVN],\n settings,\n patches: [\n // add tags to the tag list\n {\n find: \"BotTagTypes:\",\n replacement: {\n match: /\\((\\i)=\\{\\}\\)\\)\\[(\\i)\\.BOT/,\n replace: \"($1=$self.getTagTypes()))[$2.BOT\"\n }\n },\n {\n find: \".DISCORD_SYSTEM_MESSAGE_BOT_TAG_TOOLTIP,\",\n replacement: [\n // make the tag show the right text\n {\n match: /(switch\\((\\i)\\){.+?)case (\\i(?:\\.\\i)?)\\.BOT:default:(\\i)=(\\i\\.\\i\\.Messages)\\.BOT_TAG_BOT/,\n replace: (_, origSwitch, variant, tags, displayedText, strings) =>\n `${origSwitch}default:{${displayedText} = $self.getTagText(${tags}[${variant}], ${strings})}`\n },\n // show OP tags correctly\n {\n match: /(\\i)=(\\i)===\\i(?:\\.\\i)?\\.ORIGINAL_POSTER/,\n replace: \"$1=$self.isOPTag($2)\"\n },\n // add HTML data attributes (for easier theming)\n {\n match: /.botText,children:(\\i)}\\)]/,\n replace: \"$&,'data-tag':$1.toLowerCase()\"\n }\n ],\n },\n // in messages\n {\n find: \"renderSystemTag:\",\n replacement: {\n match: /;return\\((\\(null==\\i\\?void 0:\\i\\.isSystemDM\\(\\).+?.Types.ORIGINAL_POSTER\\)),null==(\\i)\\)/,\n replace: \";$1;$2=$self.getTag({...arguments[0],origType:$2,location:'chat'});return $2 == null\"\n }\n },\n // in the member list\n {\n find: \".Messages.GUILD_OWNER,\",\n replacement: {\n match: /(?<type>\\i)=\\(null==.{0,100}\\.BOT;return null!=(?<user>\\i)&&\\i\\.bot/,\n replace: \"$<type> = $self.getTag({user: $<user>, channel: arguments[0].channel, origType: $<user>.bot ? 0 : null, location: 'not-chat' }); return typeof $<type> === 'number'\"\n }\n },\n // pass channel id down props to be used in profiles\n {\n find: \".hasAvatarForGuild(null==\",\n replacement: {\n match: /(?=usernameIcon:)/,\n replace: \"moreTags_channelId:arguments[0].channelId,\"\n }\n },\n {\n find: 'copyMetaData:\"User Tag\"',\n replacement: {\n match: /(?=,botClass:)/,\n replace: \",moreTags_channelId:arguments[0].moreTags_channelId\"\n }\n },\n // in profiles\n {\n find: \",overrideDiscriminator:\",\n replacement: [\n {\n // prevent channel id from getting ghosted\n // it's either this or extremely long lookbehind\n match: /user:\\i,nick:\\i,/,\n replace: \"$&moreTags_channelId,\"\n }, {\n match: /,botType:(\\i\\((\\i)\\)),/g,\n replace: \",botType:$self.getTag({user:$2,channelId:moreTags_channelId,origType:$1,location:'not-chat'}),\"\n }\n ]\n },\n ],\n\n start() {\n if (settings.store.tagSettings) return;\n // @ts-ignore\n if (!settings.store.visibility_WEBHOOK) settings.store.tagSettings = defaultSettings;\n else {\n const newSettings = { ...defaultSettings };\n Object.entries(Vencord.PlainSettings.plugins.MoreUserTags).forEach(([name, value]) => {\n const [setting, tag] = name.split(\"_\");\n if (setting === \"visibility\") {\n switch (value) {\n case \"always\":\n // its the default\n break;\n case \"chat\":\n newSettings[tag].showInNotChat = false;\n break;\n case \"not-chat\":\n newSettings[tag].showInChat = false;\n break;\n case \"never\":\n newSettings[tag].showInChat = false;\n newSettings[tag].showInNotChat = false;\n break;\n }\n }\n settings.store.tagSettings = newSettings;\n delete Vencord.Settings.plugins.MoreUserTags[name];\n });\n }\n },\n\n getPermissions(user: User, channel: Channel): string[] {\n const guild = GuildStore.getGuild(channel?.guild_id);\n if (!guild) return [];\n\n const permissions = PermissionUtil.computePermissions({ user, context: guild, overwrites: channel.permissionOverwrites });\n return Object.entries(PermissionsBits)\n .map(([perm, permInt]) =>\n permissions & permInt ? perm : \"\"\n )\n .filter(Boolean);\n },\n\n getTagTypes() {\n const obj = {};\n let i = 100;\n tags.forEach(({ name }) => {\n obj[name] = ++i;\n obj[i] = name;\n obj[`${name}-BOT`] = ++i;\n obj[i] = `${name}-BOT`;\n obj[`${name}-OP`] = ++i;\n obj[i] = `${name}-OP`;\n });\n return obj;\n },\n\n isOPTag: (tag: number) => tag === Tag.Types.ORIGINAL_POSTER || tags.some(t => tag === Tag.Types[`${t.name}-OP`]),\n\n getTagText(passedTagName: string, strings: Record<string, string>) {\n if (!passedTagName) return strings.BOT_TAG_BOT;\n const [tagName, variant] = passedTagName.split(\"-\");\n const tag = tags.find(({ name }) => tagName === name);\n if (!tag) return strings.BOT_TAG_BOT;\n if (variant === \"BOT\" && tagName !== \"WEBHOOK\" && this.settings.store.dontShowForBots) return strings.BOT_TAG_BOT;\n\n const tagText = settings.store.tagSettings?.[tag.name]?.text || tag.displayName;\n switch (variant) {\n case \"OP\":\n return `${strings.BOT_TAG_FORUM_ORIGINAL_POSTER} \u2022 ${tagText}`;\n case \"BOT\":\n return `${strings.BOT_TAG_BOT} \u2022 ${tagText}`;\n default:\n return tagText;\n }\n },\n\n getTag({\n message, user, channelId, origType, location, channel\n }: {\n message?: Message,\n user: User & { isClyde(): boolean; },\n channel?: Channel & { isForumPost(): boolean; },\n channelId?: string;\n origType?: number;\n location: \"chat\" | \"not-chat\";\n }): number | null {\n if (!user)\n return null;\n if (location === \"chat\" && user.id === \"1\")\n return Tag.Types.OFFICIAL;\n if (user.isClyde())\n return Tag.Types.AI;\n\n let type = typeof origType === \"number\" ? origType : null;\n\n channel ??= ChannelStore.getChannel(channelId!) as any;\n if (!channel) return type;\n\n const settings = this.settings.store;\n const perms = this.getPermissions(user, channel);\n\n for (const tag of tags) {\n if (location === \"chat\" && !settings.tagSettings[tag.name].showInChat) continue;\n if (location === \"not-chat\" && !settings.tagSettings[tag.name].showInNotChat) continue;\n\n if (\n tag.permissions?.some(perm => perms.includes(perm)) ||\n (tag.condition?.(message!, user, channel))\n ) {\n if (channel.isForumPost() && channel.ownerId === user.id)\n type = Tag.Types[`${tag.name}-OP`];\n else if (user.bot && !isWebhook(message!, user) && !settings.dontShowBotTag)\n type = Tag.Types[`${tag.name}-BOT`];\n else\n type = Tag.Types[tag.name];\n break;\n }\n }\n return type;\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { definePluginSettings } from \"@api/Settings\";\nimport { makeRange } from \"@components/PluginSettings/components/SettingSliderComponent\";\nimport { Devs } from \"@utils/constants\";\nimport { sleep } from \"@utils/misc\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { RelationshipStore, SelectedChannelStore, UserStore } from \"@webpack/common\";\nimport { Message, ReactionEmoji } from \"discord-types/general\";\n\ninterface IMessageCreate {\n type: \"MESSAGE_CREATE\";\n optimistic: boolean;\n isPushNotification: boolean;\n channelId: string;\n message: Message;\n}\n\ninterface IReactionAdd {\n type: \"MESSAGE_REACTION_ADD\";\n optimistic: boolean;\n channelId: string;\n messageId: string;\n messageAuthorId: string;\n userId: \"195136840355807232\";\n emoji: ReactionEmoji;\n}\n\ninterface IVoiceChannelEffectSendEvent {\n type: string;\n emoji?: ReactionEmoji; // Just in case...\n channelId: string;\n userId: string;\n animationType: number;\n animationId: number;\n}\n\nconst MOYAI = \"\uD83D\uDDFF\";\nconst MOYAI_URL =\n \"https://raw.githubusercontent.com/MeguminSama/VencordPlugins/main/plugins/moyai/moyai.mp3\";\nconst MOYAI_URL_HD =\n \"https://raw.githubusercontent.com/MeguminSama/VencordPlugins/main/plugins/moyai/moyai_hd.wav\";\n\nconst settings = definePluginSettings({\n volume: {\n description: \"Volume of the \uD83D\uDDFF\uD83D\uDDFF\uD83D\uDDFF\",\n type: OptionType.SLIDER,\n markers: makeRange(0, 1, 0.1),\n default: 0.5,\n stickToMarkers: false\n },\n quality: {\n description: \"Quality of the \uD83D\uDDFF\uD83D\uDDFF\uD83D\uDDFF\",\n type: OptionType.SELECT,\n options: [\n { label: \"Normal\", value: \"Normal\", default: true },\n { label: \"HD\", value: \"HD\" }\n ],\n },\n triggerWhenUnfocused: {\n description: \"Trigger the \uD83D\uDDFF even when the window is unfocused\",\n type: OptionType.BOOLEAN,\n default: true\n },\n ignoreBots: {\n description: \"Ignore bots\",\n type: OptionType.BOOLEAN,\n default: true\n },\n ignoreBlocked: {\n description: \"Ignore blocked users\",\n type: OptionType.BOOLEAN,\n default: true\n }\n});\n\nexport default definePlugin({\n name: \"Moyai\",\n authors: [Devs.Megu, Devs.Nuckyz],\n description: \"\uD83D\uDDFF\uD83D\uDDFF\uD83D\uDDFF\uD83D\uDDFF\uD83D\uDDFF\uD83D\uDDFF\uD83D\uDDFF\uD83D\uDDFF\",\n settings,\n\n flux: {\n async MESSAGE_CREATE({ optimistic, type, message, channelId }: IMessageCreate) {\n if (optimistic || type !== \"MESSAGE_CREATE\") return;\n if (message.state === \"SENDING\") return;\n if (settings.store.ignoreBots && message.author?.bot) return;\n if (settings.store.ignoreBlocked && RelationshipStore.isBlocked(message.author?.id)) return;\n if (!message.content) return;\n if (channelId !== SelectedChannelStore.getChannelId()) return;\n\n const moyaiCount = getMoyaiCount(message.content);\n\n for (let i = 0; i < moyaiCount; i++) {\n boom();\n await sleep(300);\n }\n },\n\n MESSAGE_REACTION_ADD({ optimistic, type, channelId, userId, messageAuthorId, emoji }: IReactionAdd) {\n if (optimistic || type !== \"MESSAGE_REACTION_ADD\") return;\n if (settings.store.ignoreBots && UserStore.getUser(userId)?.bot) return;\n if (settings.store.ignoreBlocked && RelationshipStore.isBlocked(messageAuthorId)) return;\n if (channelId !== SelectedChannelStore.getChannelId()) return;\n\n const name = emoji.name.toLowerCase();\n if (name !== MOYAI && !name.includes(\"moyai\") && !name.includes(\"moai\")) return;\n\n boom();\n },\n\n VOICE_CHANNEL_EFFECT_SEND({ emoji }: IVoiceChannelEffectSendEvent) {\n if (!emoji?.name) return;\n const name = emoji.name.toLowerCase();\n if (name !== MOYAI && !name.includes(\"moyai\") && !name.includes(\"moai\")) return;\n\n boom();\n }\n }\n});\n\nfunction countOccurrences(sourceString: string, subString: string) {\n let i = 0;\n let lastIdx = 0;\n while ((lastIdx = sourceString.indexOf(subString, lastIdx) + 1) !== 0)\n i++;\n\n return i;\n}\n\nfunction countMatches(sourceString: string, pattern: RegExp) {\n if (!pattern.global)\n throw new Error(\"pattern must be global\");\n\n let i = 0;\n while (pattern.test(sourceString))\n i++;\n\n return i;\n}\n\nconst customMoyaiRe = /<a?:\\w*moy?ai\\w*:\\d{17,20}>/gi;\n\nfunction getMoyaiCount(message: string) {\n const count = countOccurrences(message, MOYAI)\n + countMatches(message, customMoyaiRe);\n\n return Math.min(count, 10);\n}\n\nfunction boom() {\n if (!settings.store.triggerWhenUnfocused && !document.hasFocus()) return;\n const audioElement = document.createElement(\"audio\");\n\n audioElement.src = settings.store.quality === \"HD\"\n ? MOYAI_URL_HD\n : MOYAI_URL;\n\n audioElement.volume = settings.store.volume;\n audioElement.play();\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { definePluginSettings } from \"@api/Settings\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { findByPropsLazy } from \"@webpack\";\n\nconst { updateGuildNotificationSettings } = findByPropsLazy(\"updateGuildNotificationSettings\");\n\nconst settings = definePluginSettings({\n guild: {\n description: \"Mute Guild\",\n type: OptionType.BOOLEAN,\n default: true\n },\n everyone: {\n description: \"Suppress @everyone and @here\",\n type: OptionType.BOOLEAN,\n default: true\n },\n role: {\n description: \"Suppress All Role @mentions\",\n type: OptionType.BOOLEAN,\n default: true\n }\n});\n\nexport default definePlugin({\n name: \"MuteNewGuild\",\n description: \"Mutes newly joined guilds\",\n authors: [Devs.Glitch, Devs.Nuckyz, Devs.carince],\n patches: [\n {\n find: \",acceptInvite(\",\n replacement: {\n match: /INVITE_ACCEPT_SUCCESS.+?,(\\i)=null!==.+?;/,\n replace: (m, guildId) => `${m}$self.handleMute(${guildId});`\n }\n },\n {\n find: \"{joinGuild:\",\n replacement: {\n match: /guildId:(\\i),lurker:(\\i).{0,20}}\\)\\);/,\n replace: (m, guildId, lurker) => `${m}if(!${lurker})$self.handleMute(${guildId});`\n }\n }\n ],\n settings,\n\n handleMute(guildId: string | null) {\n if (guildId === \"@me\" || guildId === \"null\" || guildId == null) return;\n updateGuildNotificationSettings(guildId,\n {\n muted: settings.store.guild,\n suppress_everyone: settings.store.everyone,\n suppress_roles: settings.store.role\n }\n );\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Devs } from \"@utils/constants\";\nimport { isNonNullish } from \"@utils/guards\";\nimport definePlugin from \"@utils/types\";\nimport { findByPropsLazy } from \"@webpack\";\nimport { Avatar, ChannelStore, Clickable, RelationshipStore, ScrollerThin, UserStore } from \"@webpack/common\";\nimport { Channel, User } from \"discord-types/general\";\n\nconst SelectedChannelActionCreators = findByPropsLazy(\"selectPrivateChannel\");\nconst AvatarUtils = findByPropsLazy(\"getChannelIconURL\");\nconst UserUtils = findByPropsLazy(\"getGlobalName\");\n\nconst ProfileListClasses = findByPropsLazy(\"emptyIconFriends\", \"emptyIconGuilds\");\nconst GuildLabelClasses = findByPropsLazy(\"guildNick\", \"guildAvatarWithoutIcon\");\n\nfunction getGroupDMName(channel: Channel) {\n return channel.name ||\n channel.recipients\n .map(UserStore.getUser)\n .filter(isNonNullish)\n .map(c => RelationshipStore.getNickname(c.id) || UserUtils.getName(c))\n .join(\", \");\n}\n\nexport default definePlugin({\n name: \"MutualGroupDMs\",\n description: \"Shows mutual group dms in profiles\",\n authors: [Devs.amia],\n\n patches: [\n {\n find: \".Messages.USER_PROFILE_MODAL\", // Note: the module is lazy-loaded\n replacement: {\n match: /(?<=\\.MUTUAL_GUILDS\\}\\),)(?=(\\i\\.bot).{0,20}(\\(0,\\i\\.jsx\\)\\(.{0,100}id:))/,\n replace: '($1||arguments[0].isCurrentUser)?null:$2\"MUTUAL_GDMS\",children:\"Mutual Groups\"}),'\n }\n },\n {\n find: \".UserProfileSections.USER_INFO_CONNECTIONS:\",\n replacement: {\n match: /(?<={user:(\\i),onClose:(\\i)}\\);)(?=case \\i\\.\\i\\.MUTUAL_FRIENDS)/,\n replace: \"case \\\"MUTUAL_GDMS\\\":return $self.renderMutualGDMs($1,$2);\"\n }\n }\n ],\n\n renderMutualGDMs(user: User, onClose: () => void) {\n const entries = ChannelStore.getSortedPrivateChannels().filter(c => c.isGroupDM() && c.recipients.includes(user.id)).map(c => (\n <Clickable\n className={ProfileListClasses.listRow}\n onClick={() => {\n onClose();\n SelectedChannelActionCreators.selectPrivateChannel(c.id);\n }}\n >\n <Avatar\n src={AvatarUtils.getChannelIconURL({ id: c.id, icon: c.icon, size: 32 })}\n size=\"SIZE_40\"\n className={ProfileListClasses.listAvatar}\n >\n </Avatar>\n <div className={ProfileListClasses.listRowContent}>\n <div className={ProfileListClasses.listName}>{getGroupDMName(c)}</div>\n <div className={GuildLabelClasses.guildNick}>{c.recipients.length + 1} Members</div>\n </div>\n </Clickable>\n ));\n\n return (\n <ScrollerThin\n className={ProfileListClasses.listScroller}\n fade={true}\n onClose={onClose}\n >\n {entries.length > 0\n ? entries\n : (\n <div className={ProfileListClasses.empty}>\n <div className={ProfileListClasses.emptyIconFriends}></div>\n <div className={ProfileListClasses.emptyText}>No group dms in common</div>\n </div>\n )\n }\n </ScrollerThin>\n );\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Settings } from \"@api/Settings\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { findByPropsLazy } from \"@webpack\";\n\nconst RelationshipStore = findByPropsLazy(\"getRelationships\", \"isBlocked\");\n\nexport default definePlugin({\n name: \"NoBlockedMessages\",\n description: \"Hides all blocked messages from chat completely.\",\n authors: [Devs.rushii, Devs.Samu],\n patches: [\n {\n find: \"Messages.BLOCKED_MESSAGES_HIDE\",\n replacement: [\n {\n match: /let\\{[^}]*collapsedReason[^}]*\\}/,\n replace: \"return null;$&\"\n }\n ]\n },\n ...[\n 'displayName=\"MessageStore\"',\n 'displayName=\"ReadStateStore\"'\n ].map(find => ({\n find,\n predicate: () => Settings.plugins.NoBlockedMessages.ignoreBlockedMessages === true,\n replacement: [\n {\n match: /(?<=MESSAGE_CREATE:function\\((\\i)\\){)/,\n replace: (_, props) => `if($self.isBlocked(${props}.message))return;`\n }\n ]\n }))\n ],\n options: {\n ignoreBlockedMessages: {\n description: \"Completely ignores (recent) incoming messages from blocked users (locally).\",\n type: OptionType.BOOLEAN,\n default: false,\n restartNeeded: true,\n },\n },\n isBlocked: message =>\n RelationshipStore.isBlocked(message.author.id)\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\n\nexport default definePlugin({\n name: \"NoDevtoolsWarning\",\n description: \"Disables the 'HOLD UP' banner in the console. As a side effect, also prevents Discord from hiding your token, which prevents random logouts.\",\n authors: [Devs.Ven],\n patches: [{\n find: \"setDevtoolsCallbacks\",\n replacement: {\n match: /if\\(null!=\\i&&\"0.0.0\"===\\i\\.remoteApp\\.getVersion\\(\\)\\)/,\n replace: \"if(true)\"\n }\n }]\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\n\nexport default definePlugin({\n name: \"NoF1\",\n description: \"Disables F1 help bind.\",\n authors: [Devs.Cyn],\n patches: [\n {\n find: ',\"f1\"],comboKeysBindGlobal:',\n replacement: {\n match: ',\"f1\"],comboKeysBindGlobal:',\n replace: \"],comboKeysBindGlobal:\",\n },\n },\n ],\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\n(window.VencordStyles ??= new Map()).set(\"src/plugins/noMosaic/styles.css\", {\n name: \"src/plugins/noMosaic/styles.css\",\n source: \"[class^=\\\"nonMediaAttachmentsContainer_\\\"] [class*=\\\"messageAttachment_\\\"] {\\n position: relative;\\n}\\n\",\n classNames: {},\n dom: null,\n});\n\nexport default \"src/plugins/noMosaic/styles.css\";\n", "/*\n * Vencord, a Discord client mod\n * Copyright (c) 2023 Vendicated and contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport { definePluginSettings } from \"@api/Settings\";\nimport { disableStyle, enableStyle } from \"@api/Styles\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin, { OptionType } from \"@utils/types\";\n\nimport style from \"./styles.css?managed\";\n\nconst settings = definePluginSettings({\n inlineVideo: {\n description: \"Play videos without carousel modal\",\n type: OptionType.BOOLEAN,\n default: true,\n restartNeeded: true\n },\n mediaLayoutType: {\n description: \"Choose media layout type\",\n type: OptionType.SELECT,\n restartNeeded: true,\n options: [\n { label: \"STATIC, render loading image but image isn't resposive, no problem unless discord window width is too small\", value: \"STATIC\", default: true },\n { label: \"RESPONSIVE, image is responsive but not render loading image, cause messages shift when loaded\", value: \"RESPONSIVE\" },\n ]\n }\n});\n\nexport default definePlugin({\n name: \"NoMosaic\",\n authors: [Devs.AutumnVN],\n description: \"Removes Discord new image mosaic\",\n tags: [\"image\", \"mosaic\", \"media\"],\n\n settings,\n\n patches: [\n {\n find: \".oneByTwoLayoutThreeGrid\",\n replacement: [{\n match: /mediaLayoutType:\\i\\.\\i\\.MOSAIC/,\n replace: \"mediaLayoutType:$self.mediaLayoutType()\",\n },\n {\n match: /null!==\\(\\i=\\i\\.get\\(\\i\\)\\)&&void 0!==\\i\\?\\i:\"INVALID\"/,\n replace: '\"INVALID\"',\n }]\n },\n {\n find: \"renderAttachments(\",\n predicate: () => settings.store.inlineVideo,\n replacement: {\n match: /url:(\\i)\\.url\\}\\);return /,\n replace: \"$&$1.content_type?.startsWith('image/')&&\"\n }\n },\n {\n find: \"Messages.REMOVE_ATTACHMENT_TOOLTIP_TEXT\",\n replacement: {\n match: /\\i===\\i\\.\\i\\.MOSAIC/,\n replace: \"true\"\n }\n }\n ],\n\n mediaLayoutType() {\n return settings.store.mediaLayoutType;\n },\n\n start() {\n enableStyle(style);\n },\n\n stop() {\n disableStyle(style);\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { definePluginSettings } from \"@api/Settings\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { findByPropsLazy } from \"@webpack\";\n\nconst MessageRequestStore = findByPropsLazy(\"getMessageRequestsCount\");\n\nconst settings = definePluginSettings({\n hideFriendRequestsCount: {\n type: OptionType.BOOLEAN,\n description: \"Hide incoming friend requests count\",\n default: true,\n restartNeeded: true\n },\n hideMessageRequestsCount: {\n type: OptionType.BOOLEAN,\n description: \"Hide message requests count\",\n default: true,\n restartNeeded: true\n },\n hidePremiumOffersCount: {\n type: OptionType.BOOLEAN,\n description: \"Hide nitro offers count\",\n default: true,\n restartNeeded: true\n }\n});\n\nexport default definePlugin({\n name: \"NoPendingCount\",\n description: \"Removes the ping count of incoming friend requests, message requests, and nitro offers.\",\n authors: [Devs.amia],\n\n settings: settings,\n\n // Functions used to determine the top left count indicator can be found in the single module that calls getUnacknowledgedOffers(...)\n // or by searching for \"showProgressBadge:\"\n patches: [\n {\n find: \"getPendingCount(){\",\n predicate: () => settings.store.hideFriendRequestsCount,\n replacement: {\n match: /(?<=getPendingCount\\(\\)\\{)/,\n replace: \"return 0;\"\n }\n },\n {\n find: \"getMessageRequestsCount(){\",\n predicate: () => settings.store.hideMessageRequestsCount,\n replacement: {\n match: /(?<=getMessageRequestsCount\\(\\)\\{)/,\n replace: \"return 0;\"\n }\n },\n // This prevents the Message Requests tab from always hiding due to the previous patch (and is compatible with spam requests)\n // In short, only the red badge is hidden. Button visibility behavior isn't changed.\n {\n find: \".getSpamChannelsCount(),\",\n predicate: () => settings.store.hideMessageRequestsCount,\n replacement: {\n match: /(?<=getSpamChannelsCount\\(\\),\\i=)\\i\\.getMessageRequestsCount\\(\\)/,\n replace: \"$self.getRealMessageRequestCount()\"\n }\n },\n {\n find: \"showProgressBadge:\",\n predicate: () => settings.store.hidePremiumOffersCount,\n replacement: {\n // The two groups inside the first group grab the minified names of the variables,\n // they are then referenced later to find unviewedTrialCount + unviewedDiscountCount.\n match: /(?<=\\{unviewedTrialCount:(\\i),unviewedDiscountCount:(\\i)\\}.{0,200}\\i=)\\1\\+\\2/,\n replace: \"0\"\n }\n }\n ],\n\n getRealMessageRequestCount() {\n return MessageRequestStore.getMessageRequestChannelIds().size;\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\n\nexport default definePlugin({\n name: \"NoProfileThemes\",\n description: \"Completely removes Nitro profile themes\",\n authors: [Devs.TheKodeToad],\n patches: [\n {\n find: \".NITRO_BANNER,\",\n replacement: {\n // = isPremiumAtLeast(user.premiumType, TIER_2)\n match: /=(?=\\i\\.\\i\\.isPremiumAtLeast\\(null==(\\i))/,\n // = user.banner && isPremiumAtLeast(user.premiumType, TIER_2)\n replace: \"=(arguments[0]?.bannerSrc||$1?.banner)&&\"\n }\n },\n {\n find: \".avatarPositionPremiumNoBanner,default:\",\n replacement: {\n // premiumUserWithoutBanner: foo().avatarPositionPremiumNoBanner, default: foo().avatarPositionNormal\n match: /\\.avatarPositionPremiumNoBanner(?=,default:\\i\\.(\\i))/,\n // premiumUserWithoutBanner: foo().avatarPositionNormal...\n replace: \".$1\"\n }\n },\n {\n find: \"hasThemeColors(){\",\n replacement: {\n match: /get canUsePremiumProfileCustomization\\(\\){return /,\n replace: \"$&false &&\"\n }\n }\n ]\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { definePluginSettings } from \"@api/Settings\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport type { Message } from \"discord-types/general\";\n\nconst settings = definePluginSettings({\n userList: {\n description:\n \"List of users to allow or exempt pings for (separated by commas or spaces)\",\n type: OptionType.STRING,\n default: \"1234567890123445,1234567890123445\",\n },\n shouldPingListed: {\n description: \"Behaviour\",\n type: OptionType.SELECT,\n options: [\n {\n label: \"Do not ping the listed users\",\n value: false,\n },\n {\n label: \"Only ping the listed users\",\n value: true,\n default: true,\n },\n ],\n },\n inverseShiftReply: {\n description: \"Invert Discord's shift replying behaviour (enable to make shift reply mention user)\",\n type: OptionType.BOOLEAN,\n default: false,\n }\n});\n\nexport default definePlugin({\n name: \"NoReplyMention\",\n description: \"Disables reply pings by default\",\n authors: [Devs.DustyAngel47, Devs.axyie, Devs.pylix, Devs.outfoxxed],\n settings,\n\n shouldMention(message: Message, isHoldingShift: boolean) {\n const isListed = settings.store.userList.includes(message.author.id);\n const isExempt = settings.store.shouldPingListed ? isListed : !isListed;\n return settings.store.inverseShiftReply ? isHoldingShift !== isExempt : !isHoldingShift && isExempt;\n },\n\n patches: [\n {\n find: \",\\\"Message\\\")}function\",\n replacement: {\n match: /:(\\i),shouldMention:!(\\i)\\.shiftKey/,\n replace: \":$1,shouldMention:$self.shouldMention($1,$2.shiftKey)\"\n }\n }\n ],\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\n\nexport default definePlugin({\n name: \"NoScreensharePreview\",\n description: \"Disables screenshare previews from being sent.\",\n authors: [Devs.Nuckyz],\n patches: [\n {\n find: '\"ApplicationStreamPreviewUploadManager\"',\n replacement: {\n match: /await \\i\\.\\i\\.(makeChunkedRequest\\(|post\\(\\{url:)\\i\\.\\i\\.STREAM_PREVIEW.+?\\}\\)/g,\n replace: \"0\"\n }\n }\n ]\n});\n", "/*\n * Vencord, a Discord client mod\n * Copyright (c) 2023 Vendicated and contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\n\nexport default definePlugin({\n name: \"NoTypingAnimation\",\n authors: [Devs.AutumnVN],\n description: \"Disables the CPU-intensive typing dots animation\",\n patches: [{\n find: \"dotCycle\",\n replacement: {\n match: /document.hasFocus\\(\\)/,\n replace: \"false\"\n }\n }]\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Sofia Lima\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\n\n\nexport default definePlugin({\n name: \"NoUnblockToJump\",\n description: \"Allows you to jump to messages of blocked users without unblocking them\",\n authors: [Devs.dzshn],\n patches: [\n {\n find: '.id,\"Search Results\"',\n replacement: {\n match: /if\\(.{1,10}\\)(.{1,10}\\.show\\({.{1,50}UNBLOCK_TO_JUMP_TITLE)/,\n replace: \"if(false)$1\"\n }\n },\n {\n find: \"renderJumpButton()\",\n replacement: {\n match: /if\\(.{1,10}\\)(.{1,10}\\.show\\({.{1,50}UNBLOCK_TO_JUMP_TITLE)/,\n replace: \"if(false)$1\"\n }\n },\n {\n find: \"flash:!0,returnMessageId\",\n replacement: {\n match: /.\\?(.{1,10}\\.show\\({.{1,50}UNBLOCK_TO_JUMP_TITLE)/,\n replace: \"false?$1\"\n }\n }\n ]\n});\n", "/*\n * Vencord, a Discord client mod\n * Copyright (c) 2023 Vendicated and contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\n\nexport default definePlugin({\n name: \"NormalizeMessageLinks\",\n description: \"Strip canary/ptb from message links\",\n authors: [Devs.bb010g],\n patches: [\n {\n find: \".Messages.COPY_MESSAGE_LINK,\",\n replacement: {\n match: /\\.concat\\(location\\.host\\)/,\n replace: \".concat($self.normalizeHost(location.host))\",\n },\n },\n ],\n normalizeHost(host: string) {\n return host.replace(/(^|\\b)(canary\\.|ptb\\.)(discord.com)$/, \"$1$3\");\n },\n});\n", "/*\n * Vencord, a Discord client mod\n * Copyright (c) 2023 Vendicated and contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport { definePluginSettings } from \"@api/Settings\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin, { OptionType } from \"@utils/types\";\n\nconst settings = definePluginSettings({\n notificationVolume: {\n type: OptionType.SLIDER,\n description: \"Notification volume\",\n markers: [0, 25, 50, 75, 100],\n default: 100,\n stickToMarkers: false\n }\n});\n\nexport default definePlugin({\n name: \"NotificationVolume\",\n description: \"Save your ears and set a separate volume for notifications and in-app sounds\",\n authors: [Devs.philipbry],\n settings,\n patches: [\n {\n find: \"_ensureAudio(){\",\n replacement: {\n match: /onloadeddata=\\(\\)=>\\{.\\.volume=/,\n replace: \"$&$self.settings.store.notificationVolume/100*\"\n },\n },\n ],\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\n\nexport default definePlugin({\n name: \"NSFWGateBypass\",\n description: \"Allows you to access NSFW channels without setting/verifying your age\",\n authors: [Devs.Commandtechno],\n patches: [\n {\n find: \".nsfwAllowed=null\",\n replacement: {\n match: /(?<=\\.nsfwAllowed=)null!==.+?(?=[,;])/,\n replace: \"!0\",\n },\n },\n ],\n});\n", "/*\n * Vencord, a Discord client mod\n * Copyright (c) 2023 Vendicated and contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport { definePluginSettings } from \"@api/Settings\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { ChannelStore, ReadStateStore, UserStore } from \"@webpack/common\";\nimport { MessageJSON } from \"discord-types/general\";\n\nconst enum ChannelType {\n DM = 1,\n GROUP_DM = 3\n}\n\nconst settings = definePluginSettings({\n channelToAffect: {\n type: OptionType.SELECT,\n description: \"Select the type of DM for the plugin to affect\",\n options: [\n { label: \"Both\", value: \"both_dms\", default: true },\n { label: \"User DMs\", value: \"user_dm\" },\n { label: \"Group DMs\", value: \"group_dm\" },\n ]\n },\n allowMentions: {\n type: OptionType.BOOLEAN,\n description: \"Receive audio pings for @mentions\",\n default: false,\n },\n allowEveryone: {\n type: OptionType.BOOLEAN,\n description: \"Receive audio pings for @everyone and @here in group DMs\",\n default: false,\n },\n});\n\nexport default definePlugin({\n name: \"OnePingPerDM\",\n description: \"If unread messages are sent by a user in DMs multiple times, you'll only receive one audio ping. Read the messages to reset the limit\",\n authors: [Devs.ProffDea],\n settings,\n patches: [{\n find: \".getDesktopType()===\",\n replacement: [{\n match: /(\\i\\.\\i\\.getDesktopType\\(\\)===\\i\\.\\i\\.NEVER)\\)/,\n replace: \"$&if(!$self.isPrivateChannelRead(arguments[0]?.message))return;else \"\n },\n {\n match: /sound:(\\i\\?\\i:void 0,volume:\\i,onClick)/,\n replace: \"sound:!$self.isPrivateChannelRead(arguments[0]?.message)?undefined:$1\"\n }]\n }],\n isPrivateChannelRead(message: MessageJSON) {\n const channelType = ChannelStore.getChannel(message.channel_id)?.type;\n if (\n (channelType !== ChannelType.DM && channelType !== ChannelType.GROUP_DM) ||\n (channelType === ChannelType.DM && settings.store.channelToAffect === \"group_dm\") ||\n (channelType === ChannelType.GROUP_DM && settings.store.channelToAffect === \"user_dm\") ||\n (settings.store.allowMentions && message.mentions.some(m => m.id === UserStore.getCurrentUser().id)) ||\n (settings.store.allowEveryone && message.mention_everyone)\n ) {\n return true;\n }\n return ReadStateStore.getOldestUnreadMessageId(message.channel_id) === message.id;\n },\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\n\nexport default definePlugin({\n name: \"oneko\",\n description: \"cat follow mouse (real)\",\n // Listing adryd here because this literally just evals her script\n authors: [Devs.Ven, Devs.adryd],\n\n start() {\n fetch(\"https://raw.githubusercontent.com/adryd325/oneko.js/8fa8a1864aa71cd7a794d58bc139e755e96a236c/oneko.js\")\n .then(x => x.text())\n .then(s => s.replace(\"./oneko.gif\", \"https://raw.githubusercontent.com/adryd325/oneko.js/14bab15a755d0e35cd4ae19c931d96d306f99f42/oneko.gif\")\n .replace(\"(isReducedMotion)\", \"(false)\"))\n .then(eval);\n },\n\n stop() {\n document.getElementById(\"oneko\")?.remove();\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { definePluginSettings } from \"@api/Settings\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin, { OptionType, PluginNative } from \"@utils/types\";\nimport { showToast, Toasts } from \"@webpack/common\";\nimport type { MouseEvent } from \"react\";\n\nconst ShortUrlMatcher = /^https:\\/\\/(spotify\\.link|s\\.team)\\/.+$/;\nconst SpotifyMatcher = /^https:\\/\\/open\\.spotify\\.com\\/(track|album|artist|playlist|user|episode)\\/(.+)(?:\\?.+?)?$/;\nconst SteamMatcher = /^https:\\/\\/(steamcommunity\\.com|(?:help|store)\\.steampowered\\.com)\\/.+$/;\nconst EpicMatcher = /^https:\\/\\/store\\.epicgames\\.com\\/(.+)$/;\n\nconst settings = definePluginSettings({\n spotify: {\n type: OptionType.BOOLEAN,\n description: \"Open Spotify links in the Spotify app\",\n default: true,\n },\n steam: {\n type: OptionType.BOOLEAN,\n description: \"Open Steam links in the Steam app\",\n default: true,\n },\n epic: {\n type: OptionType.BOOLEAN,\n description: \"Open Epic Games links in the Epic Games Launcher\",\n default: true,\n }\n});\n\nconst Native = VencordNative.pluginHelpers.OpenInApp as PluginNative<typeof import(\"./native\")>;\n\nexport default definePlugin({\n name: \"OpenInApp\",\n description: \"Open Spotify, Steam and Epic Games URLs in their respective apps instead of your browser\",\n authors: [Devs.Ven],\n settings,\n\n patches: [\n {\n find: \"trackAnnouncementMessageLinkClicked({\",\n replacement: {\n match: /(?<=handleClick:function\\(\\)\\{return (\\i)\\}.+?)function \\1\\(.+?\\)\\{/,\n replace: \"async $& if(await $self.handleLink(...arguments)) return;\"\n }\n },\n // Make Spotify profile activity links open in app on web\n {\n find: \"WEB_OPEN(\",\n predicate: () => !IS_DISCORD_DESKTOP && settings.store.spotify,\n replacement: {\n match: /\\i\\.\\i\\.isProtocolRegistered\\(\\)(.{0,100})window.open/g,\n replace: \"true$1VencordNative.native.openExternal\"\n }\n },\n {\n find: \".CONNECTED_ACCOUNT_VIEWED,\",\n replacement: {\n match: /(?<=href:\\i,onClick:\\i=>\\{)(?=.{0,10}\\i=(\\i)\\.type,.{0,100}CONNECTED_ACCOUNT_VIEWED)/,\n replace: \"$self.handleAccountView(arguments[0],$1.type,$1.id);\"\n }\n }\n ],\n\n async handleLink(data: { href: string; }, event?: MouseEvent) {\n if (!data) return false;\n\n let url = data.href;\n if (!IS_WEB && ShortUrlMatcher.test(url)) {\n event?.preventDefault();\n // CORS jumpscare\n url = await Native.resolveRedirect(url);\n }\n\n spotify: {\n if (!settings.store.spotify) break spotify;\n\n const match = SpotifyMatcher.exec(url);\n if (!match) break spotify;\n\n const [, type, id] = match;\n VencordNative.native.openExternal(`spotify:${type}:${id}`);\n\n event?.preventDefault();\n return true;\n }\n\n steam: {\n if (!settings.store.steam) break steam;\n\n if (!SteamMatcher.test(url)) break steam;\n\n VencordNative.native.openExternal(`steam://openurl/${url}`);\n event?.preventDefault();\n\n // Steam does not focus itself so show a toast so it's slightly less confusing\n showToast(\"Opened link in Steam\", Toasts.Type.SUCCESS);\n return true;\n }\n\n epic: {\n if (!settings.store.epic) break epic;\n\n const match = EpicMatcher.exec(url);\n if (!match) break epic;\n\n VencordNative.native.openExternal(`com.epicgames.launcher://store/${match[1]}`);\n event?.preventDefault();\n\n return true;\n }\n\n // in case short url didn't end up being something we can handle\n if (event?.defaultPrevented) {\n window.open(url, \"_blank\");\n return true;\n }\n\n return false;\n },\n\n handleAccountView(event: { preventDefault(): void; }, platformType: string, userId: string) {\n if (platformType === \"spotify\" && settings.store.spotify) {\n VencordNative.native.openExternal(`spotify:user:${userId}`);\n event.preventDefault();\n } else if (platformType === \"steam\" && settings.store.steam) {\n VencordNative.native.openExternal(`steam://openurl/https://steamcommunity.com/profiles/${userId}`);\n showToast(\"Opened link in Steam\", Toasts.Type.SUCCESS);\n event.preventDefault();\n }\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { definePluginSettings } from \"@api/Settings\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { FluxDispatcher } from \"@webpack/common\";\n\nconst enum Intensity {\n Normal,\n Better,\n ProjectX,\n}\n\nconst settings = definePluginSettings({\n superIntensePartyMode: {\n description: \"Party intensity\",\n type: OptionType.SELECT,\n options: [\n { label: \"Normal\", value: Intensity.Normal, default: true },\n { label: \"Better\", value: Intensity.Better },\n { label: \"Project X\", value: Intensity.ProjectX },\n ],\n restartNeeded: false,\n onChange: setSettings\n },\n});\n\nexport default definePlugin({\n name: \"Party mode \uD83C\uDF89\",\n description: \"Allows you to use party mode cause the party never ends \u2728\",\n authors: [Devs.UwUDev],\n settings,\n\n start() {\n setPoggerState(true);\n setSettings(settings.store.superIntensePartyMode);\n },\n\n stop() {\n setPoggerState(false);\n },\n});\n\nfunction setPoggerState(state: boolean) {\n FluxDispatcher.dispatch({\n type: \"POGGERMODE_SETTINGS_UPDATE\",\n settings: {\n enabled: state,\n settingsVisible: state\n }\n });\n}\n\nfunction setSettings(intensity: Intensity) {\n const state = {\n screenshakeEnabledLocations: { 0: true, 1: true, 2: true },\n shakeIntensity: 1,\n confettiSize: 16,\n confettiCount: 5,\n combosRequiredCount: 1\n };\n\n switch (intensity) {\n case Intensity.Normal: {\n Object.assign(state, {\n screenshakeEnabledLocations: { 0: true, 1: false, 2: false },\n combosRequiredCount: 5\n });\n break;\n }\n case Intensity.Better: {\n Object.assign(state, {\n confettiSize: 12,\n confettiCount: 8,\n });\n break;\n }\n case Intensity.ProjectX: {\n Object.assign(state, {\n shakeIntensity: 20,\n confettiSize: 25,\n confettiCount: 15,\n });\n break;\n }\n }\n\n FluxDispatcher.dispatch({\n type: \"POGGERMODE_SETTINGS_UPDATE\",\n settings: state\n });\n}\n", "/*\n * Vencord, a Discord client mod\n * Copyright (c) 2023 Vendicated and contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport { definePluginSettings } from \"@api/Settings\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin, { OptionType } from \"@utils/types\";\n\nconst settings = definePluginSettings({\n lockout: {\n type: OptionType.BOOLEAN,\n default: true,\n description: 'Bypass the permission lockout prevention (\"Pretty sure you don\\'t want to do this\")',\n restartNeeded: true\n },\n onboarding: {\n type: OptionType.BOOLEAN,\n default: true,\n description: 'Bypass the onboarding requirements (\"Making this change will make your server incompatible [...]\")',\n restartNeeded: true\n }\n});\n\nexport default definePlugin({\n name: \"PermissionFreeWill\",\n description: \"Disables the client-side restrictions for channel permission management.\",\n authors: [Devs.lewisakura],\n\n patches: [\n // Permission lockout, just set the check to true\n {\n find: \".showPermissionLockoutModal(\",\n replacement: [\n {\n match: /case\"DENY\":.{0,50}if\\((?=\\i\\.\\i\\.can)/,\n replace: \"$&true||\"\n }\n ],\n predicate: () => settings.store.lockout\n },\n // Onboarding, same thing but we need to prevent the check\n {\n find: \".ONBOARDING_CHANNEL_THRESHOLD_WARNING\",\n replacement: [\n {\n // are we java yet?\n match: /(?<=(?:isDefaultChannelThresholdMetAfterDelete|checkDefaultChannelThresholdMetAfterChannelPermissionDeny):function\\(\\)\\{)return \\i(?=\\})/g,\n replace: \"return () => true\"\n }\n ],\n predicate: () => settings.store.onboarding\n }\n ],\n settings\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { classNameFactory } from \"@api/Styles\";\nimport { wordsToTitle } from \"@utils/text\";\nimport { GuildStore, i18n, Parser } from \"@webpack/common\";\nimport { Guild, GuildMember, Role } from \"discord-types/general\";\nimport type { ReactNode } from \"react\";\n\nimport { PermissionsSortOrder, settings } from \".\";\nimport { PermissionType } from \"./components/RolesAndUsersPermissions\";\n\nexport const cl = classNameFactory(\"vc-permviewer-\");\n\nfunction formatPermissionWithoutMatchingString(permission: string) {\n return wordsToTitle(permission.toLowerCase().split(\"_\"));\n}\n\n// because discord is unable to be consistent with their names\nconst PermissionKeyMap = {\n MANAGE_GUILD: \"MANAGE_SERVER\",\n MANAGE_GUILD_EXPRESSIONS: \"MANAGE_EXPRESSIONS\",\n CREATE_GUILD_EXPRESSIONS: \"CREATE_EXPRESSIONS\",\n MODERATE_MEMBERS: \"MODERATE_MEMBER\", // HELLOOOO ??????\n STREAM: \"VIDEO\",\n SEND_VOICE_MESSAGES: \"ROLE_PERMISSIONS_SEND_VOICE_MESSAGE\",\n} as const;\n\nexport function getPermissionString(permission: string) {\n permission = PermissionKeyMap[permission] || permission;\n\n return i18n.Messages[permission] ||\n // shouldn't get here but just in case\n formatPermissionWithoutMatchingString(permission);\n}\n\nexport function getPermissionDescription(permission: string): ReactNode {\n // DISCORD PLEEEEEEEEAAAAASE IM BEGGING YOU :(\n if (permission === \"USE_APPLICATION_COMMANDS\")\n permission = \"USE_APPLICATION_COMMANDS_GUILD\";\n else if (permission === \"SEND_VOICE_MESSAGES\")\n permission = \"SEND_VOICE_MESSAGE_GUILD\";\n else if (permission !== \"STREAM\")\n permission = PermissionKeyMap[permission] || permission;\n\n const msg = i18n.Messages[`ROLE_PERMISSIONS_${permission}_DESCRIPTION`] as any;\n if (msg?.hasMarkdown)\n return Parser.parse(msg.message);\n\n if (typeof msg === \"string\") return msg;\n\n return \"\";\n}\n\nexport function getSortedRoles({ roles, id }: Guild, member: GuildMember) {\n return [...member.roles, id]\n .map(id => roles[id])\n .sort((a, b) => b.position - a.position);\n}\n\nexport function sortUserRoles(roles: Role[]) {\n switch (settings.store.permissionsSortOrder) {\n case PermissionsSortOrder.HighestRole:\n return roles.sort((a, b) => b.position - a.position);\n case PermissionsSortOrder.LowestRole:\n return roles.sort((a, b) => a.position - b.position);\n default:\n return roles;\n }\n}\n\nexport function sortPermissionOverwrites<T extends { id: string; type: number; }>(overwrites: T[], guildId: string) {\n const guild = GuildStore.getGuild(guildId);\n\n return overwrites.sort((a, b) => {\n if (a.type !== PermissionType.Role || b.type !== PermissionType.Role) return 0;\n\n const roleA = guild.roles[a.id];\n const roleB = guild.roles[b.id];\n\n return roleB.position - roleA.position;\n });\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nexport function PermissionDeniedIcon() {\n return (\n <svg\n height=\"24\"\n width=\"24\"\n viewBox=\"0 0 24 24\"\n >\n <title>Denied</title>\n <path fill=\"var(--status-danger)\" d=\"M18.4 4L12 10.4L5.6 4L4 5.6L10.4 12L4 18.4L5.6 20L12 13.6L18.4 20L20 18.4L13.6 12L20 5.6L18.4 4Z\" />\n </svg>\n );\n}\n\nexport function PermissionAllowedIcon() {\n return (\n <svg\n height=\"24\"\n width=\"24\"\n viewBox=\"0 0 24 24\"\n >\n <title>Allowed</title>\n <path fill=\"var(--text-positive)\" d=\"M8.99991 16.17L4.82991 12L3.40991 13.41L8.99991 19L20.9999 7.00003L19.5899 5.59003L8.99991 16.17ZZ\" />\n </svg>\n );\n}\n\nexport function PermissionDefaultIcon() {\n return (\n <svg\n height=\"24\"\n width=\"24\"\n viewBox=\"0 0 16 16\"\n >\n <g>\n <title>Not overwritten</title>\n <polygon fill=\"var(--text-normal)\" points=\"12 2.32 10.513 2 4 13.68 5.487 14\" />\n </g>\n </svg>\n );\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport ErrorBoundary from \"@components/ErrorBoundary\";\nimport { Flex } from \"@components/Flex\";\nimport { InfoIcon, OwnerCrownIcon } from \"@components/Icons\";\nimport { getUniqueUsername } from \"@utils/discord\";\nimport { ModalCloseButton, ModalContent, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from \"@utils/modal\";\nimport { ContextMenuApi, FluxDispatcher, GuildMemberStore, Menu, PermissionsBits, Text, Tooltip, useEffect, UserStore, useState, useStateFromStores } from \"@webpack/common\";\nimport type { Guild } from \"discord-types/general\";\n\nimport { settings } from \"..\";\nimport { cl, getPermissionDescription, getPermissionString } from \"../utils\";\nimport { PermissionAllowedIcon, PermissionDefaultIcon, PermissionDeniedIcon } from \"./icons\";\n\nexport const enum PermissionType {\n Role = 0,\n User = 1,\n Owner = 2\n}\n\nexport interface RoleOrUserPermission {\n type: PermissionType;\n id?: string;\n permissions?: bigint;\n overwriteAllow?: bigint;\n overwriteDeny?: bigint;\n}\n\nfunction openRolesAndUsersPermissionsModal(permissions: Array<RoleOrUserPermission>, guild: Guild, header: string) {\n return openModal(modalProps => (\n <RolesAndUsersPermissions\n modalProps={modalProps}\n permissions={permissions}\n guild={guild}\n header={header}\n />\n ));\n}\n\nfunction RolesAndUsersPermissionsComponent({ permissions, guild, modalProps, header }: { permissions: Array<RoleOrUserPermission>; guild: Guild; modalProps: ModalProps; header: string; }) {\n permissions.sort((a, b) => a.type - b.type);\n\n useStateFromStores(\n [GuildMemberStore],\n () => GuildMemberStore.getMemberIds(guild.id),\n null,\n (old, current) => old.length === current.length\n );\n\n useEffect(() => {\n const usersToRequest = permissions\n .filter(p => p.type === PermissionType.User && !GuildMemberStore.isMember(guild.id, p.id!))\n .map(({ id }) => id);\n\n FluxDispatcher.dispatch({\n type: \"GUILD_MEMBERS_REQUEST\",\n guildIds: [guild.id],\n userIds: usersToRequest\n });\n }, []);\n\n const [selectedItemIndex, selectItem] = useState(0);\n const selectedItem = permissions[selectedItemIndex];\n\n return (\n <ModalRoot\n {...modalProps}\n size={ModalSize.LARGE}\n >\n <ModalHeader>\n <Text className={cl(\"perms-title\")} variant=\"heading-lg/semibold\">{header} permissions:</Text>\n <ModalCloseButton onClick={modalProps.onClose} />\n </ModalHeader>\n\n <ModalContent>\n {!selectedItem && (\n <div className={cl(\"perms-no-perms\")}>\n <Text variant=\"heading-lg/normal\">No permissions to display!</Text>\n </div>\n )}\n\n {selectedItem && (\n <div className={cl(\"perms-container\")}>\n <div className={cl(\"perms-list\")}>\n {permissions.map((permission, index) => {\n const user = UserStore.getUser(permission.id ?? \"\");\n const role = guild.roles[permission.id ?? \"\"];\n\n return (\n <button\n className={cl(\"perms-list-item-btn\")}\n onClick={() => selectItem(index)}\n >\n <div\n className={cl(\"perms-list-item\", { \"perms-list-item-active\": selectedItemIndex === index })}\n onContextMenu={e => {\n if ((settings.store as any).unsafeViewAsRole && permission.type === PermissionType.Role)\n ContextMenuApi.openContextMenu(e, () => (\n <RoleContextMenu\n guild={guild}\n roleId={permission.id!}\n onClose={modalProps.onClose}\n />\n ));\n }}\n >\n {(permission.type === PermissionType.Role || permission.type === PermissionType.Owner) && (\n <span\n className={cl(\"perms-role-circle\")}\n style={{ backgroundColor: role?.colorString ?? \"var(--primary-300)\" }}\n />\n )}\n {permission.type === PermissionType.User && user !== undefined && (\n <img\n className={cl(\"perms-user-img\")}\n src={user.getAvatarURL(void 0, void 0, false)}\n />\n )}\n <Text variant=\"text-md/normal\">\n {\n permission.type === PermissionType.Role\n ? role?.name ?? \"Unknown Role\"\n : permission.type === PermissionType.User\n ? (user && getUniqueUsername(user)) ?? \"Unknown User\"\n : (\n <Flex style={{ gap: \"0.2em\", justifyItems: \"center\" }}>\n @owner\n <OwnerCrownIcon\n height={18}\n width={18}\n aria-hidden=\"true\"\n />\n </Flex>\n )\n }\n </Text>\n </div>\n </button>\n );\n })}\n </div>\n <div className={cl(\"perms-perms\")}>\n {Object.entries(PermissionsBits).map(([permissionName, bit]) => (\n <div className={cl(\"perms-perms-item\")}>\n <div className={cl(\"perms-perms-item-icon\")}>\n {(() => {\n const { permissions, overwriteAllow, overwriteDeny } = selectedItem;\n\n if (permissions)\n return (permissions & bit) === bit\n ? PermissionAllowedIcon()\n : PermissionDeniedIcon();\n\n if (overwriteAllow && (overwriteAllow & bit) === bit)\n return PermissionAllowedIcon();\n if (overwriteDeny && (overwriteDeny & bit) === bit)\n return PermissionDeniedIcon();\n\n return PermissionDefaultIcon();\n })()}\n </div>\n <Text variant=\"text-md/normal\">{getPermissionString(permissionName)}</Text>\n\n <Tooltip text={getPermissionDescription(permissionName) || \"No Description\"}>\n {props => <InfoIcon {...props} />}\n </Tooltip>\n </div>\n ))}\n </div>\n </div>\n )}\n </ModalContent>\n </ModalRoot >\n );\n}\n\nfunction RoleContextMenu({ guild, roleId, onClose }: { guild: Guild; roleId: string; onClose: () => void; }) {\n return (\n <Menu.Menu\n navId={cl(\"role-context-menu\")}\n onClose={ContextMenuApi.closeContextMenu}\n aria-label=\"Role Options\"\n >\n <Menu.MenuItem\n id=\"vc-pw-view-as-role\"\n label=\"View As Role\"\n action={() => {\n const role = guild.roles[roleId];\n if (!role) return;\n\n onClose();\n\n FluxDispatcher.dispatch({\n type: \"IMPERSONATE_UPDATE\",\n guildId: guild.id,\n data: {\n type: \"ROLES\",\n roles: {\n [roleId]: role\n }\n }\n });\n }}\n />\n </Menu.Menu>\n );\n}\n\nconst RolesAndUsersPermissions = ErrorBoundary.wrap(RolesAndUsersPermissionsComponent);\n\nexport default openRolesAndUsersPermissionsModal;\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { classNameFactory } from \"@api/Styles\";\nimport { Text, Tooltip, useState } from \"@webpack/common\";\nexport const cl = classNameFactory(\"vc-expandableheader-\");\nimport \"./ExpandableHeader.css\";\n\nexport interface ExpandableHeaderProps {\n onMoreClick?: () => void;\n moreTooltipText?: string;\n onDropDownClick?: (state: boolean) => void;\n defaultState?: boolean;\n headerText: string;\n children: React.ReactNode;\n buttons?: React.ReactNode[];\n}\n\nexport default function ExpandableHeader({ children, onMoreClick, buttons, moreTooltipText, defaultState = false, onDropDownClick, headerText }: ExpandableHeaderProps) {\n const [showContent, setShowContent] = useState(defaultState);\n\n return (\n <>\n <div style={{\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n marginBottom: \"8px\"\n }}>\n <Text\n tag=\"h2\"\n variant=\"eyebrow\"\n style={{\n color: \"var(--header-primary)\",\n display: \"inline\"\n }}\n >\n {headerText}\n </Text>\n\n <div className={cl(\"center-flex\")}>\n {\n buttons ?? null\n }\n\n {\n onMoreClick && // only show more button if callback is provided\n <Tooltip text={moreTooltipText}>\n {tooltipProps => (\n <button\n {...tooltipProps}\n className={cl(\"btn\")}\n onClick={onMoreClick}>\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n >\n <path fill=\"var(--text-normal)\" d=\"M7 12.001C7 10.8964 6.10457 10.001 5 10.001C3.89543 10.001 3 10.8964 3 12.001C3 13.1055 3.89543 14.001 5 14.001C6.10457 14.001 7 13.1055 7 12.001ZM14 12.001C14 10.8964 13.1046 10.001 12 10.001C10.8954 10.001 10 10.8964 10 12.001C10 13.1055 10.8954 14.001 12 14.001C13.1046 14.001 14 13.1055 14 12.001ZM19 10.001C20.1046 10.001 21 10.8964 21 12.001C21 13.1055 20.1046 14.001 19 14.001C17.8954 14.001 17 13.1055 17 12.001C17 10.8964 17.8954 10.001 19 10.001Z\" />\n </svg>\n </button>\n )}\n </Tooltip>\n }\n\n\n <Tooltip text={showContent ? \"Hide \" + headerText : \"Show \" + headerText}>\n {tooltipProps => (\n <button\n {...tooltipProps}\n className={cl(\"btn\")}\n onClick={() => {\n setShowContent(v => !v);\n onDropDownClick?.(showContent);\n }}\n >\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n transform={showContent ? \"scale(1 -1)\" : \"scale(1 1)\"}\n >\n <path fill=\"var(--text-normal)\" d=\"M16.59 8.59003L12 13.17L7.41 8.59003L6 10L12 16L18 10L16.59 8.59003Z\" />\n </svg>\n </button>\n )}\n </Tooltip>\n </div>\n </div>\n {showContent && children}\n </>\n );\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport ErrorBoundary from \"@components/ErrorBoundary\";\nimport ExpandableHeader from \"@components/ExpandableHeader\";\nimport { classes } from \"@utils/misc\";\nimport { filters, findBulk, proxyLazyWebpack } from \"@webpack\";\nimport { i18n, PermissionsBits, Text, Tooltip, useMemo, UserStore } from \"@webpack/common\";\nimport type { Guild, GuildMember } from \"discord-types/general\";\n\nimport { PermissionsSortOrder, settings } from \"..\";\nimport { cl, getPermissionString, getSortedRoles, sortUserRoles } from \"../utils\";\nimport openRolesAndUsersPermissionsModal, { PermissionType, type RoleOrUserPermission } from \"./RolesAndUsersPermissions\";\n\ninterface UserPermission {\n permission: string;\n roleColor: string;\n rolePosition: number;\n}\n\ntype UserPermissions = Array<UserPermission>;\n\nconst Classes = proxyLazyWebpack(() =>\n Object.assign({}, ...findBulk(\n filters.byProps(\"roles\", \"rolePill\", \"rolePillBorder\"),\n filters.byProps(\"roleCircle\", \"dotBorderBase\", \"dotBorderColor\"),\n filters.byProps(\"roleNameOverflow\", \"root\", \"roleName\", \"roleRemoveButton\")\n ))\n) as Record<\"roles\" | \"rolePill\" | \"rolePillBorder\" | \"desaturateUserColors\" | \"flex\" | \"alignCenter\" | \"justifyCenter\" | \"svg\" | \"background\" | \"dot\" | \"dotBorderColor\" | \"roleCircle\" | \"dotBorderBase\" | \"flex\" | \"alignCenter\" | \"justifyCenter\" | \"wrap\" | \"root\" | \"role\" | \"roleRemoveButton\" | \"roleDot\" | \"roleFlowerStar\" | \"roleRemoveIcon\" | \"roleRemoveIconFocused\" | \"roleVerifiedIcon\" | \"roleName\" | \"roleNameOverflow\" | \"actionButton\" | \"overflowButton\" | \"addButton\" | \"addButtonIcon\" | \"overflowRolesPopout\" | \"overflowRolesPopoutArrowWrapper\" | \"overflowRolesPopoutArrow\" | \"popoutBottom\" | \"popoutTop\" | \"overflowRolesPopoutHeader\" | \"overflowRolesPopoutHeaderIcon\" | \"overflowRolesPopoutHeaderText\" | \"roleIcon\", string>;\n\nfunction UserPermissionsComponent({ guild, guildMember, showBorder }: { guild: Guild; guildMember: GuildMember; showBorder: boolean; }) {\n const stns = settings.use([\"permissionsSortOrder\"]);\n\n const [rolePermissions, userPermissions] = useMemo(() => {\n const userPermissions: UserPermissions = [];\n\n const userRoles = getSortedRoles(guild, guildMember);\n\n const rolePermissions: Array<RoleOrUserPermission> = userRoles.map(role => ({\n type: PermissionType.Role,\n ...role\n }));\n\n if (guild.ownerId === guildMember.userId) {\n rolePermissions.push({\n type: PermissionType.Owner,\n permissions: Object.values(PermissionsBits).reduce((prev, curr) => prev | curr, 0n)\n });\n\n const OWNER = i18n.Messages.GUILD_OWNER || \"Server Owner\";\n userPermissions.push({\n permission: OWNER,\n roleColor: \"var(--primary-300)\",\n rolePosition: Infinity\n });\n }\n\n sortUserRoles(userRoles);\n\n for (const [permission, bit] of Object.entries(PermissionsBits)) {\n for (const { permissions, colorString, position } of userRoles) {\n if ((permissions & bit) === bit) {\n userPermissions.push({\n permission: getPermissionString(permission),\n roleColor: colorString || \"var(--primary-300)\",\n rolePosition: position\n });\n\n break;\n }\n }\n }\n\n userPermissions.sort((a, b) => b.rolePosition - a.rolePosition);\n\n return [rolePermissions, userPermissions];\n }, [stns.permissionsSortOrder]);\n\n const { root, role, roleRemoveButton, roleNameOverflow, roles, rolePill, rolePillBorder, roleCircle, roleName } = Classes;\n\n return (\n <ExpandableHeader\n headerText=\"Permissions\"\n moreTooltipText=\"Role Details\"\n onMoreClick={() =>\n openRolesAndUsersPermissionsModal(\n rolePermissions,\n guild,\n guildMember.nick || UserStore.getUser(guildMember.userId).username\n )\n }\n defaultState={settings.store.defaultPermissionsDropdownState}\n buttons={[\n (<Tooltip text={`Sorting by ${stns.permissionsSortOrder === PermissionsSortOrder.HighestRole ? \"Highest Role\" : \"Lowest Role\"}`}>\n {tooltipProps => (\n <button\n {...tooltipProps}\n className={cl(\"userperms-sortorder-btn\")}\n onClick={() => {\n stns.permissionsSortOrder = stns.permissionsSortOrder === PermissionsSortOrder.HighestRole ? PermissionsSortOrder.LowestRole : PermissionsSortOrder.HighestRole;\n }}\n >\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 96 960 960\"\n transform={stns.permissionsSortOrder === PermissionsSortOrder.HighestRole ? \"scale(1 1)\" : \"scale(1 -1)\"}\n >\n <path fill=\"var(--text-normal)\" d=\"M440 896V409L216 633l-56-57 320-320 320 320-56 57-224-224v487h-80Z\" />\n </svg>\n </button>\n )}\n </Tooltip>)\n ]}>\n {userPermissions.length > 0 && (\n <div className={classes(root, roles)}>\n {userPermissions.map(({ permission, roleColor }) => (\n <div className={classes(role, rolePill, showBorder ? rolePillBorder : null)}>\n <div className={roleRemoveButton}>\n <span\n className={roleCircle}\n style={{ backgroundColor: roleColor }}\n />\n </div>\n <div className={roleName}>\n <Text\n className={roleNameOverflow}\n variant=\"text-xs/medium\"\n >\n {permission}\n </Text>\n </div>\n </div>\n ))}\n </div>\n )}\n </ExpandableHeader>\n );\n}\n\nexport default ErrorBoundary.wrap(UserPermissionsComponent, { noop: true });\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport \"./styles.css\";\n\nimport { addContextMenuPatch, findGroupChildrenByChildId, NavContextMenuPatchCallback, removeContextMenuPatch } from \"@api/ContextMenu\";\nimport { definePluginSettings } from \"@api/Settings\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { ChannelStore, GuildMemberStore, GuildStore, Menu, PermissionsBits, UserStore } from \"@webpack/common\";\nimport type { Guild, GuildMember } from \"discord-types/general\";\n\nimport openRolesAndUsersPermissionsModal, { PermissionType, RoleOrUserPermission } from \"./components/RolesAndUsersPermissions\";\nimport UserPermissions from \"./components/UserPermissions\";\nimport { getSortedRoles, sortPermissionOverwrites } from \"./utils\";\n\nexport const enum PermissionsSortOrder {\n HighestRole,\n LowestRole\n}\n\nconst enum MenuItemParentType {\n User,\n Channel,\n Guild\n}\n\nexport const settings = definePluginSettings({\n permissionsSortOrder: {\n description: \"The sort method used for defining which role grants an user a certain permission\",\n type: OptionType.SELECT,\n options: [\n { label: \"Highest Role\", value: PermissionsSortOrder.HighestRole, default: true },\n { label: \"Lowest Role\", value: PermissionsSortOrder.LowestRole }\n ],\n },\n defaultPermissionsDropdownState: {\n description: \"Whether the permissions dropdown on user popouts should be open by default\",\n type: OptionType.BOOLEAN,\n default: false,\n }\n});\n\nfunction MenuItem(guildId: string, id?: string, type?: MenuItemParentType) {\n if (type === MenuItemParentType.User && !GuildMemberStore.isMember(guildId, id!)) return null;\n\n return (\n <Menu.MenuItem\n id=\"perm-viewer-permissions\"\n label=\"Permissions\"\n action={() => {\n const guild = GuildStore.getGuild(guildId);\n\n let permissions: RoleOrUserPermission[];\n let header: string;\n\n switch (type) {\n case MenuItemParentType.User: {\n const member = GuildMemberStore.getMember(guildId, id!);\n\n permissions = getSortedRoles(guild, member)\n .map(role => ({\n type: PermissionType.Role,\n ...role\n }));\n\n if (guild.ownerId === id) {\n permissions.push({\n type: PermissionType.Owner,\n permissions: Object.values(PermissionsBits).reduce((prev, curr) => prev | curr, 0n)\n });\n }\n\n header = member.nick ?? UserStore.getUser(member.userId).username;\n\n break;\n }\n\n case MenuItemParentType.Channel: {\n const channel = ChannelStore.getChannel(id!);\n\n permissions = sortPermissionOverwrites(Object.values(channel.permissionOverwrites).map(({ id, allow, deny, type }) => ({\n type: type as PermissionType,\n id,\n overwriteAllow: allow,\n overwriteDeny: deny\n })), guildId);\n\n header = channel.name;\n\n break;\n }\n\n default: {\n permissions = Object.values(guild.roles).map(role => ({\n type: PermissionType.Role,\n ...role\n }));\n\n header = guild.name;\n\n break;\n }\n }\n\n openRolesAndUsersPermissionsModal(permissions, guild, header);\n }}\n />\n );\n}\n\nfunction makeContextMenuPatch(childId: string | string[], type?: MenuItemParentType): NavContextMenuPatchCallback {\n return (children, props) => () => {\n if (!props || (type === MenuItemParentType.User && !props.user) || (type === MenuItemParentType.Guild && !props.guild)) return children;\n\n const group = findGroupChildrenByChildId(childId, children);\n\n const item = (() => {\n switch (type) {\n case MenuItemParentType.User:\n return MenuItem(props.guildId, props.user.id, type);\n case MenuItemParentType.Channel:\n return MenuItem(props.guild.id, props.channel.id, type);\n case MenuItemParentType.Guild:\n return MenuItem(props.guild.id);\n default:\n return null;\n }\n })();\n\n if (item == null) return;\n\n if (group)\n group.push(item);\n else if (childId === \"roles\" && props.guildId)\n // \"roles\" may not be present due to the member not having any roles. In that case, add it above \"Copy ID\"\n children.splice(-1, 0, <Menu.MenuGroup>{item}</Menu.MenuGroup>);\n };\n}\n\nexport default definePlugin({\n name: \"PermissionsViewer\",\n description: \"View the permissions a user or channel has, and the roles of a server\",\n authors: [Devs.Nuckyz, Devs.Ven],\n settings,\n\n patches: [\n {\n find: \".popularApplicationCommandIds,\",\n replacement: {\n match: /showBorder:(.{0,60})}\\),(?<=guild:(\\i),guildMember:(\\i),.+?)/,\n replace: (m, showBoder, guild, guildMember) => `${m}$self.UserPermissions(${guild},${guildMember},${showBoder}),`\n }\n }\n ],\n\n UserPermissions: (guild: Guild, guildMember: GuildMember | undefined, showBoder: boolean) => !!guildMember && <UserPermissions guild={guild} guildMember={guildMember} showBorder={showBoder} />,\n\n userContextMenuPatch: makeContextMenuPatch(\"roles\", MenuItemParentType.User),\n channelContextMenuPatch: makeContextMenuPatch([\"mute-channel\", \"unmute-channel\"], MenuItemParentType.Channel),\n guildContextMenuPatch: makeContextMenuPatch(\"privacy\", MenuItemParentType.Guild),\n\n start() {\n addContextMenuPatch(\"user-context\", this.userContextMenuPatch);\n addContextMenuPatch(\"channel-context\", this.channelContextMenuPatch);\n addContextMenuPatch([\"guild-context\", \"guild-header-popout\"], this.guildContextMenuPatch);\n },\n\n stop() {\n removeContextMenuPatch(\"user-context\", this.userContextMenuPatch);\n removeContextMenuPatch(\"channel-context\", this.channelContextMenuPatch);\n removeContextMenuPatch([\"guild-context\", \"guild-header-popout\"], this.guildContextMenuPatch);\n },\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { ApplicationCommandInputType, ApplicationCommandOptionType, Argument, CommandContext, findOption, sendBotMessage } from \"@api/Commands\";\nimport { Devs } from \"@utils/constants\";\nimport { makeLazy } from \"@utils/lazy\";\nimport definePlugin from \"@utils/types\";\nimport { findByPropsLazy } from \"@webpack\";\nimport { UploadHandler, UserUtils } from \"@webpack/common\";\nimport { applyPalette, GIFEncoder, quantize } from \"gifenc\";\n\nconst DRAFT_TYPE = 0;\nconst DEFAULT_DELAY = 20;\nconst DEFAULT_RESOLUTION = 128;\nconst FRAMES = 10;\n\nconst getFrames = makeLazy(() => Promise.all(\n Array.from(\n { length: FRAMES },\n (_, i) => loadImage(`https://raw.githubusercontent.com/VenPlugs/petpet/main/frames/pet${i}.gif`)\n ))\n);\n\nconst UploadStore = findByPropsLazy(\"getUploads\");\n\nfunction loadImage(source: File | string) {\n const isFile = source instanceof File;\n const url = isFile ? URL.createObjectURL(source) : source;\n\n return new Promise<HTMLImageElement>((resolve, reject) => {\n const img = new Image();\n img.onload = () => {\n if (isFile)\n URL.revokeObjectURL(url);\n resolve(img);\n };\n img.onerror = (event, _source, _lineno, _colno, err) => reject(err || event);\n img.crossOrigin = \"Anonymous\";\n img.src = url;\n });\n}\n\nasync function resolveImage(options: Argument[], ctx: CommandContext, noServerPfp: boolean): Promise<File | string | null> {\n for (const opt of options) {\n switch (opt.name) {\n case \"image\":\n const upload = UploadStore.getUploads(ctx.channel.id, DRAFT_TYPE)[0];\n if (upload) {\n if (!upload.isImage) throw \"Upload is not an image\";\n return upload.item.file;\n }\n break;\n case \"url\":\n return opt.value;\n case \"user\":\n try {\n const user = await UserUtils.getUser(opt.value);\n return user.getAvatarURL(noServerPfp ? void 0 : ctx.guild?.id, 2048).replace(/\\?size=\\d+$/, \"?size=2048\");\n } catch (err) {\n console.error(\"[petpet] Failed to fetch user\\n\", err);\n throw \"Failed to fetch user. Check the console for more info.\";\n }\n }\n }\n return null;\n}\n\nexport default definePlugin({\n name: \"petpet\",\n description: \"Adds a /petpet slash command to create headpet gifs from any image\",\n authors: [Devs.Ven],\n dependencies: [\"CommandsAPI\"],\n commands: [\n {\n inputType: ApplicationCommandInputType.BUILT_IN,\n name: \"petpet\",\n description: \"Create a petpet gif. You can only specify one of the image options\",\n options: [\n {\n name: \"delay\",\n description: \"The delay between each frame. Defaults to 20.\",\n type: ApplicationCommandOptionType.INTEGER\n },\n {\n name: \"resolution\",\n description: \"Resolution for the gif. Defaults to 120. If you enter an insane number and it freezes Discord that's your fault.\",\n type: ApplicationCommandOptionType.INTEGER\n },\n {\n name: \"image\",\n description: \"Image attachment to use\",\n type: ApplicationCommandOptionType.ATTACHMENT\n },\n {\n name: \"url\",\n description: \"URL to fetch image from\",\n type: ApplicationCommandOptionType.STRING\n },\n {\n name: \"user\",\n description: \"User whose avatar to use as image\",\n type: ApplicationCommandOptionType.USER\n },\n {\n name: \"no-server-pfp\",\n description: \"Use the normal avatar instead of the server specific one when using the 'user' option\",\n type: ApplicationCommandOptionType.BOOLEAN\n }\n ],\n execute: async (opts, cmdCtx) => {\n const frames = await getFrames();\n\n const noServerPfp = findOption(opts, \"no-server-pfp\", false);\n try {\n var url = await resolveImage(opts, cmdCtx, noServerPfp);\n if (!url) throw \"No Image specified!\";\n } catch (err) {\n sendBotMessage(cmdCtx.channel.id, {\n content: String(err),\n });\n return;\n }\n\n const avatar = await loadImage(url);\n\n const delay = findOption(opts, \"delay\", DEFAULT_DELAY);\n const resolution = findOption(opts, \"resolution\", DEFAULT_RESOLUTION);\n\n const gif = GIFEncoder();\n\n const canvas = document.createElement(\"canvas\");\n canvas.width = canvas.height = resolution;\n const ctx = canvas.getContext(\"2d\")!;\n\n for (let i = 0; i < FRAMES; i++) {\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n\n const j = i < FRAMES / 2 ? i : FRAMES - i;\n const width = 0.8 + j * 0.02;\n const height = 0.8 - j * 0.05;\n const offsetX = (1 - width) * 0.5 + 0.1;\n const offsetY = 1 - height - 0.08;\n\n ctx.drawImage(avatar, offsetX * resolution, offsetY * resolution, width * resolution, height * resolution);\n ctx.drawImage(frames[i], 0, 0, resolution, resolution);\n\n const { data } = ctx.getImageData(0, 0, resolution, resolution);\n const palette = quantize(data, 256);\n const index = applyPalette(data, palette);\n\n gif.writeFrame(index, resolution, resolution, {\n transparent: true,\n palette,\n delay,\n });\n }\n\n gif.finish();\n const file = new File([gif.bytesView()], \"petpet.gif\", { type: \"image/gif\" });\n // Immediately after the command finishes, Discord clears all input, including pending attachments.\n // Thus, setTimeout is needed to make this execute after Discord cleared the input\n setTimeout(() => UploadHandler.promptToUpload([file], cmdCtx.channel, DRAFT_TYPE), 10);\n },\n },\n ]\n});\n", "/*\n * Vencord, a Discord client mod\n * Copyright (c) 2023 Vendicated and contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport \"./styles.css\";\n\nimport { definePluginSettings } from \"@api/Settings\";\nimport ErrorBoundary from \"@components/ErrorBoundary\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { React, Tooltip } from \"@webpack/common\";\n\nconst settings = definePluginSettings({\n loop: {\n description: \"Whether to make the PiP video loop or not\",\n type: OptionType.BOOLEAN,\n default: true,\n restartNeeded: false\n }\n});\n\nexport default definePlugin({\n name: \"PictureInPicture\",\n description: \"Adds picture in picture to videos (next to the Download button)\",\n authors: [Devs.Lumap],\n settings,\n patches: [\n {\n find: \".nonMediaAttachment]\",\n replacement: {\n match: /\\.nonMediaAttachment\\]:!(\\i).{0,10}children:\\[(\\S)/,\n replace: \"$&,$1&&$2&&$self.renderPiPButton(),\"\n },\n },\n ],\n\n renderPiPButton: ErrorBoundary.wrap(() => {\n return (\n <Tooltip text=\"Toggle Picture in Picture\">\n {tooltipProps => (\n <div\n {...tooltipProps}\n className=\"vc-pip-button\"\n role=\"button\"\n style={{\n cursor: \"pointer\",\n paddingTop: \"4px\",\n paddingLeft: \"4px\",\n paddingRight: \"4px\",\n }}\n onClick={e => {\n const video = e.currentTarget.parentNode!.parentNode!.querySelector(\"video\")!;\n const videoClone = document.body.appendChild(video.cloneNode(true)) as HTMLVideoElement;\n\n videoClone.loop = settings.store.loop;\n videoClone.style.display = \"none\";\n videoClone.onleavepictureinpicture = () => videoClone.remove();\n\n function launchPiP() {\n videoClone.currentTime = video.currentTime;\n videoClone.requestPictureInPicture();\n video.pause();\n videoClone.play();\n }\n\n if (videoClone.readyState === 4 /* HAVE_ENOUGH_DATA */)\n launchPiP();\n else\n videoClone.onloadedmetadata = launchPiP;\n }}\n >\n <svg width=\"24px\" height=\"24px\" viewBox=\"0 0 24 24\">\n <path\n fill=\"currentColor\"\n d=\"M21 3a1 1 0 0 1 1 1v7h-2V5H4v14h6v2H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h18zm0 10a1 1 0 0 1 1 1v6a1 1 0 0 1-1 1h-8a1 1 0 0 1-1-1v-6a1 1 0 0 1 1-1h8zm-1 2h-6v4h6v-4z\"\n />\n </svg>\n </div>\n )}\n </Tooltip>\n );\n }, { noop: true })\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { definePluginSettings, Settings, useSettings } from \"@api/Settings\";\nimport { OptionType } from \"@utils/types\";\nimport { findStoreLazy } from \"@webpack\";\n\nexport const enum PinOrder {\n LastMessage,\n Custom\n}\n\nexport const settings = definePluginSettings({\n pinOrder: {\n type: OptionType.SELECT,\n description: \"Which order should pinned DMs be displayed in?\",\n options: [\n { label: \"Most recent message\", value: PinOrder.LastMessage, default: true },\n { label: \"Custom (right click channels to reorder)\", value: PinOrder.Custom }\n ]\n }\n});\n\nconst PrivateChannelSortStore = findStoreLazy(\"PrivateChannelSortStore\");\n\nexport let snapshotArray: string[];\nlet snapshot: Set<string> | undefined;\n\nconst getArray = () => (Settings.plugins.PinDMs.pinnedDMs || void 0)?.split(\",\") as string[] | undefined;\nconst save = (pins: string[]) => {\n snapshot = void 0;\n Settings.plugins.PinDMs.pinnedDMs = pins.join(\",\");\n};\nconst takeSnapshot = () => {\n snapshotArray = getArray() ?? [];\n return snapshot = new Set<string>(snapshotArray);\n};\nconst requireSnapshot = () => snapshot ?? takeSnapshot();\n\nexport function usePinnedDms() {\n useSettings([\"plugins.PinDMs.pinnedDMs\"]);\n\n return requireSnapshot();\n}\n\nexport function isPinned(id: string) {\n return requireSnapshot().has(id);\n}\n\nexport function togglePin(id: string) {\n const snapshot = requireSnapshot();\n if (!snapshot.delete(id)) {\n snapshot.add(id);\n }\n\n save([...snapshot]);\n}\n\nexport function sortedSnapshot() {\n requireSnapshot();\n if (settings.store.pinOrder === PinOrder.LastMessage)\n return PrivateChannelSortStore.getPrivateChannelIds().filter(isPinned);\n\n return snapshotArray;\n}\n\nexport function getPinAt(idx: number) {\n return sortedSnapshot()[idx];\n}\n\nexport function movePin(id: string, direction: -1 | 1) {\n const pins = getArray()!;\n const a = pins.indexOf(id);\n const b = a + direction;\n\n [pins[a], pins[b]] = [pins[b], pins[a]];\n\n save(pins);\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { addContextMenuPatch, findGroupChildrenByChildId, NavContextMenuPatchCallback, removeContextMenuPatch } from \"@api/ContextMenu\";\nimport { Menu } from \"@webpack/common\";\n\nimport { isPinned, movePin, PinOrder, settings, snapshotArray, togglePin } from \"./settings\";\n\nfunction PinMenuItem(channelId: string) {\n const pinned = isPinned(channelId);\n const canMove = pinned && settings.store.pinOrder === PinOrder.Custom;\n\n return (\n <>\n <Menu.MenuItem\n id=\"pin-dm\"\n label={pinned ? \"Unpin DM\" : \"Pin DM\"}\n action={() => togglePin(channelId)}\n />\n {canMove && snapshotArray[0] !== channelId && (\n <Menu.MenuItem\n id=\"move-pin-up\"\n label=\"Move Pin Up\"\n action={() => movePin(channelId, -1)}\n />\n )}\n {canMove && snapshotArray[snapshotArray.length - 1] !== channelId && (\n <Menu.MenuItem\n id=\"move-pin-down\"\n label=\"Move Pin Down\"\n action={() => movePin(channelId, +1)}\n />\n )}\n </>\n );\n}\n\nconst GroupDMContext: NavContextMenuPatchCallback = (children, props) => () => {\n const container = findGroupChildrenByChildId(\"leave-channel\", children);\n if (container)\n container.unshift(PinMenuItem(props.channel.id));\n};\n\nconst UserContext: NavContextMenuPatchCallback = (children, props) => () => {\n const container = findGroupChildrenByChildId(\"close-dm\", children);\n if (container) {\n const idx = container.findIndex(c => c?.props?.id === \"close-dm\");\n container.splice(idx, 0, PinMenuItem(props.channel.id));\n }\n};\n\nexport function addContextMenus() {\n addContextMenuPatch(\"gdm-context\", GroupDMContext);\n addContextMenuPatch(\"user-context\", UserContext);\n}\n\nexport function removeContextMenus() {\n removeContextMenuPatch(\"gdm-context\", GroupDMContext);\n removeContextMenuPatch(\"user-context\", UserContext);\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\nimport { Channel } from \"discord-types/general\";\n\nimport { addContextMenus, removeContextMenus } from \"./contextMenus\";\nimport { getPinAt, isPinned, settings, snapshotArray, sortedSnapshot, usePinnedDms } from \"./settings\";\n\nexport default definePlugin({\n name: \"PinDMs\",\n description: \"Allows you to pin private channels to the top of your DM list. To pin/unpin or reorder pins, right click DMs\",\n authors: [Devs.Ven, Devs.Strencher],\n\n settings,\n\n start: addContextMenus,\n stop: removeContextMenus,\n\n usePinCount(channelIds: string[]) {\n const pinnedDms = usePinnedDms();\n // See comment on 2nd patch for reasoning\n return channelIds.length ? [pinnedDms.size] : [];\n },\n\n getChannel(channels: Record<string, Channel>, idx: number) {\n return channels[getPinAt(idx)];\n },\n\n isPinned,\n getSnapshot: sortedSnapshot,\n\n getScrollOffset(channelId: string, rowHeight: number, padding: number, preRenderedChildren: number, originalOffset: number) {\n if (!isPinned(channelId))\n return (\n (rowHeight + padding) * 2 // header\n + rowHeight * snapshotArray.length // pins\n + originalOffset // original pin offset minus pins\n );\n\n return rowHeight * (snapshotArray.indexOf(channelId) + preRenderedChildren) + padding;\n },\n\n patches: [\n // Patch DM list\n {\n find: \".privateChannelsHeaderContainer,\",\n replacement: [\n {\n // filter Discord's privateChannelIds list to remove pins, and pass\n // pinCount as prop. This needs to be here so that the entire DM list receives\n // updates on pin/unpin\n match: /(?<=\\i,{channels:\\i,)privateChannelIds:(\\i),/,\n replace: \"privateChannelIds:$1.filter(c=>!$self.isPinned(c)),pinCount:$self.usePinCount($1),\"\n },\n {\n // sections is an array of numbers, where each element is a section and\n // the number is the amount of rows. Add our pinCount in second place\n // - Section 1: buttons for pages like Friends & Library\n // - Section 2: our pinned dms\n // - Section 3: the normal dm list\n match: /(?<=renderRow:this\\.renderRow,)sections:\\[\\i,/,\n // For some reason, adding our sections when no private channels are ready yet\n // makes DMs infinitely load. Thus usePinCount returns either a single element\n // array with the count, or an empty array. Due to spreading, only in the former\n // case will an element be added to the outer array\n // Thanks for the fix, Strencher!\n replace: \"$&...this.props.pinCount??[],\"\n },\n {\n // Patch renderSection (renders the header) to set the text to \"Pinned DMs\" instead of \"Direct Messages\"\n // lookbehind is used to lookup parameter name. We could use arguments[0], but\n // if children ever is wrapped in an iife, it will break\n match: /children:(\\i\\.\\i\\.Messages.DIRECT_MESSAGES)(?<=renderSection=(\\i)=>{.+?)/,\n replace: \"children:$2.section===1?'Pinned DMs':$1\"\n },\n {\n // Patch channel lookup inside renderDM\n // channel=channels[channelIds[row]];\n match: /(?<=renderDM=\\((\\i),(\\i)\\)=>{.*?this.state,\\i=\\i\\[\\i\\],\\i=)((\\i)\\[\\i\\]);/,\n // section 1 is us, manually get our own channel\n // section === 1 ? getChannel(channels, row) : channels[channelIds[row]];\n replace: \"$1===1?$self.getChannel($4,$2):$3;\"\n },\n {\n // Fix getRowHeight's check for whether this is the DMs section\n // DMS (inlined) === section\n match: /(?<=getRowHeight=\\(.{2,50}?)1===\\i/,\n // DMS (inlined) === section - 1\n replace: \"$&-1\"\n },\n {\n // Override scrollToChannel to properly account for pinned channels\n match: /(?<=scrollTo\\(\\{to:\\i\\}\\):\\(\\i\\+=)(\\d+)\\*\\(.+?(?=,)/,\n replace: \"$self.getScrollOffset(arguments[0],$1,this.props.padding,this.state.preRenderedChildren,$&)\"\n }\n ]\n },\n\n // Fix Alt Up/Down navigation\n {\n find: \".Routes.APPLICATION_STORE&&\",\n replacement: {\n // channelIds = __OVERLAY__ ? stuff : [...getStaticPaths(),...channelIds)]\n match: /(?<=\\i=__OVERLAY__\\?\\i:\\[\\.\\.\\.\\i\\(\\),\\.\\.\\.)\\i/,\n // ....concat(pins).concat(toArray(channelIds).filter(c => !isPinned(c)))\n replace: \"$self.getSnapshot().concat($&.filter(c=>!$self.isPinned(c)))\"\n }\n },\n // fix alt+shift+up/down\n {\n find: \".getFlattenedGuildIds()],\",\n replacement: {\n match: /(?<=\\i===\\i\\.ME\\?)\\i\\.\\i\\.getPrivateChannelIds\\(\\)/,\n replace: \"$self.getSnapshot().concat($&.filter(c=>!$self.isPinned(c)))\"\n }\n },\n ]\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\n\nexport default definePlugin({\n name: \"PlainFolderIcon\",\n description: \"Doesn't show the small guild icons in folders\",\n authors: [Devs.botato],\n patches: [{\n find: \".expandedFolderIconWrapper\",\n replacement: [{\n match: /\\(\\w\\|\\|\\w\\)&&(\\(.{0,40}\\(.{1,3}\\.animated)/,\n replace: \"$1\",\n }]\n }]\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Channel, User } from \"discord-types/general/index.js\";\n\ninterface DecoratorProps {\n activities: any[];\n channel: Channel;\n /**\n * Only for DM members\n */\n channelName?: string;\n /**\n * Only for server members\n */\n currentUser?: User;\n guildId?: string;\n isMobile: boolean;\n isOwner?: boolean;\n isTyping: boolean;\n selected: boolean;\n status: string;\n user: User;\n [key: string]: any;\n}\nexport type Decorator = (props: DecoratorProps) => JSX.Element | null;\ntype OnlyIn = \"guilds\" | \"dms\";\n\nexport const decorators = new Map<string, { decorator: Decorator, onlyIn?: OnlyIn; }>();\n\nexport function addDecorator(identifier: string, decorator: Decorator, onlyIn?: OnlyIn) {\n decorators.set(identifier, { decorator, onlyIn });\n}\n\nexport function removeDecorator(identifier: string) {\n decorators.delete(identifier);\n}\n\nexport function __getDecorators(props: DecoratorProps): (JSX.Element | null)[] {\n const isInGuild = !!(props.guildId);\n return Array.from(decorators.values(), decoratorObj => {\n const { decorator, onlyIn } = decoratorObj;\n // this can most likely be done cleaner\n if (!onlyIn || (onlyIn === \"guilds\" && isInGuild) || (onlyIn === \"dms\" && !isInGuild)) {\n return decorator(props);\n }\n return null;\n });\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Channel, Message } from \"discord-types/general/index.js\";\n\ninterface DecorationProps {\n author: {\n /**\n * Will be username if the user has no nickname\n */\n nick: string;\n iconRoleId: string;\n guildMemberAvatar: string;\n colorRoleName: string;\n colorString: string;\n };\n channel: Channel;\n compact: boolean;\n decorations: {\n /**\n * Element for the [BOT] tag if there is one\n */\n 0: JSX.Element | null;\n /**\n * Other decorations (including ones added with this api)\n */\n 1: JSX.Element[];\n };\n message: Message;\n [key: string]: any;\n}\nexport type Decoration = (props: DecorationProps) => JSX.Element | null;\n\nexport const decorations = new Map<string, Decoration>();\n\nexport function addDecoration(identifier: string, decoration: Decoration) {\n decorations.set(identifier, decoration);\n}\n\nexport function removeDecoration(identifier: string) {\n decorations.delete(identifier);\n}\n\nexport function __addDecorationsToMessage(props: DecorationProps): (JSX.Element | null)[] {\n return [...decorations.values()].map(decoration => {\n return decoration(props);\n });\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { addBadge, BadgePosition, ProfileBadge, removeBadge } from \"@api/Badges\";\nimport { addDecorator, removeDecorator } from \"@api/MemberListDecorators\";\nimport { addDecoration, removeDecoration } from \"@api/MessageDecorations\";\nimport { Settings } from \"@api/Settings\";\nimport ErrorBoundary from \"@components/ErrorBoundary\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { findByPropsLazy, findStoreLazy } from \"@webpack\";\nimport { PresenceStore, Tooltip, UserStore } from \"@webpack/common\";\nimport { User } from \"discord-types/general\";\n\nconst SessionsStore = findStoreLazy(\"SessionsStore\");\n\nfunction Icon(path: string, opts?: { viewBox?: string; width?: number; height?: number; }) {\n return ({ color, tooltip, small }: { color: string; tooltip: string; small: boolean; }) => (\n <Tooltip text={tooltip} >\n {(tooltipProps: any) => (\n <svg\n {...tooltipProps}\n height={(opts?.height ?? 20) - (small ? 3 : 0)}\n width={(opts?.width ?? 20) - (small ? 3 : 0)}\n viewBox={opts?.viewBox ?? \"0 0 24 24\"}\n fill={color}\n >\n <path d={path} />\n </svg>\n )}\n </Tooltip>\n );\n}\n\nconst Icons = {\n desktop: Icon(\"M4 2.5c-1.103 0-2 .897-2 2v11c0 1.104.897 2 2 2h7v2H7v2h10v-2h-4v-2h7c1.103 0 2-.896 2-2v-11c0-1.103-.897-2-2-2H4Zm16 2v9H4v-9h16Z\"),\n web: Icon(\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2Zm-1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93Zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39Z\"),\n mobile: Icon(\"M 187 0 L 813 0 C 916.277 0 1000 83.723 1000 187 L 1000 1313 C 1000 1416.277 916.277 1500 813 1500 L 187 1500 C 83.723 1500 0 1416.277 0 1313 L 0 187 C 0 83.723 83.723 0 187 0 Z M 125 1000 L 875 1000 L 875 250 L 125 250 Z M 500 1125 C 430.964 1125 375 1180.964 375 1250 C 375 1319.036 430.964 1375 500 1375 C 569.036 1375 625 1319.036 625 1250 C 625 1180.964 569.036 1125 500 1125 Z\", { viewBox: \"0 0 1000 1500\", height: 17, width: 17 }),\n console: Icon(\"M14.8 2.7 9 3.1V47h3.3c1.7 0 6.2.3 10 .7l6.7.6V2l-4.2.2c-2.4.1-6.9.3-10 .5zm1.8 6.4c1 1.7-1.3 3.6-2.7 2.2C12.7 10.1 13.5 8 15 8c.5 0 1.2.5 1.6 1.1zM16 33c0 6-.4 10-1 10s-1-4-1-10 .4-10 1-10 1 4 1 10zm15-8v23.3l3.8-.7c2-.3 4.7-.6 6-.6H43V3h-2.2c-1.3 0-4-.3-6-.6L31 1.7V25z\", { viewBox: \"0 0 50 50\" }),\n};\ntype Platform = keyof typeof Icons;\n\nconst StatusUtils = findByPropsLazy(\"useStatusFillColor\", \"StatusTypes\");\n\nconst PlatformIcon = ({ platform, status, small }: { platform: Platform, status: string; small: boolean; }) => {\n const tooltip = platform[0].toUpperCase() + platform.slice(1);\n const Icon = Icons[platform] ?? Icons.desktop;\n\n return <Icon color={StatusUtils.useStatusFillColor(status)} tooltip={tooltip} small={small} />;\n};\n\nconst getStatus = (id: string): Record<Platform, string> => PresenceStore.getState()?.clientStatuses?.[id];\n\nconst PlatformIndicator = ({ user, wantMargin = true, wantTopMargin = false, small = false }: { user: User; wantMargin?: boolean; wantTopMargin?: boolean; small?: boolean; }) => {\n if (!user || user.bot) return null;\n\n if (user.id === UserStore.getCurrentUser().id) {\n const sessions = SessionsStore.getSessions();\n if (typeof sessions !== \"object\") return null;\n const sortedSessions = Object.values(sessions).sort(({ status: a }: any, { status: b }: any) => {\n if (a === b) return 0;\n if (a === \"online\") return 1;\n if (b === \"online\") return -1;\n if (a === \"idle\") return 1;\n if (b === \"idle\") return -1;\n return 0;\n });\n\n const ownStatus = Object.values(sortedSessions).reduce((acc: any, curr: any) => {\n if (curr.clientInfo.client !== \"unknown\")\n acc[curr.clientInfo.client] = curr.status;\n return acc;\n }, {});\n\n const { clientStatuses } = PresenceStore.getState();\n clientStatuses[UserStore.getCurrentUser().id] = ownStatus;\n }\n\n const status = PresenceStore.getState()?.clientStatuses?.[user.id] as Record<Platform, string>;\n if (!status) return null;\n\n const icons = Object.entries(status).map(([platform, status]) => (\n <PlatformIcon\n key={platform}\n platform={platform as Platform}\n status={status}\n small={small}\n />\n ));\n\n if (!icons.length) return null;\n\n return (\n <span\n className=\"vc-platform-indicator\"\n style={{\n display: \"inline-flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n marginLeft: wantMargin ? 4 : 0,\n verticalAlign: \"top\",\n position: \"relative\",\n top: wantTopMargin ? 2 : 0,\n padding: !wantMargin ? 1 : 0,\n gap: 2\n }}\n\n >\n {icons}\n </span>\n );\n};\n\nconst badge: ProfileBadge = {\n component: p => <PlatformIndicator {...p} wantMargin={false} />,\n position: BadgePosition.START,\n shouldShow: userInfo => !!Object.keys(getStatus(userInfo.user.id) ?? {}).length,\n key: \"indicator\"\n};\n\nconst indicatorLocations = {\n list: {\n description: \"In the member list\",\n onEnable: () => addDecorator(\"platform-indicator\", props =>\n <ErrorBoundary noop>\n <PlatformIndicator user={props.user} small={true} />\n </ErrorBoundary>\n ),\n onDisable: () => removeDecorator(\"platform-indicator\")\n },\n badges: {\n description: \"In user profiles, as badges\",\n onEnable: () => addBadge(badge),\n onDisable: () => removeBadge(badge)\n },\n messages: {\n description: \"Inside messages\",\n onEnable: () => addDecoration(\"platform-indicator\", props =>\n <ErrorBoundary noop>\n <PlatformIndicator user={props.message?.author} wantTopMargin={true} />\n </ErrorBoundary>\n ),\n onDisable: () => removeDecoration(\"platform-indicator\")\n }\n};\n\nexport default definePlugin({\n name: \"PlatformIndicators\",\n description: \"Adds platform indicators (Desktop, Mobile, Web...) to users\",\n authors: [Devs.kemo, Devs.TheSun, Devs.Nuckyz, Devs.Ven],\n dependencies: [\"MessageDecorationsAPI\", \"MemberListDecoratorsAPI\"],\n\n start() {\n const settings = Settings.plugins.PlatformIndicators;\n const { displayMode } = settings;\n\n // transfer settings from the old ones, which had a select menu instead of booleans\n if (displayMode) {\n if (displayMode !== \"both\") settings[displayMode] = true;\n else {\n settings.list = true;\n settings.badges = true;\n }\n settings.messages = true;\n delete settings.displayMode;\n }\n\n Object.entries(indicatorLocations).forEach(([key, value]) => {\n if (settings[key]) value.onEnable();\n });\n },\n\n stop() {\n Object.entries(indicatorLocations).forEach(([_, value]) => {\n value.onDisable();\n });\n },\n\n patches: [\n {\n find: \".Masks.STATUS_ONLINE_MOBILE\",\n predicate: () => Settings.plugins.PlatformIndicators.colorMobileIndicator,\n replacement: [\n {\n // Return the STATUS_ONLINE_MOBILE mask if the user is on mobile, no matter the status\n match: /\\.STATUS_TYPING;switch(?=.+?(if\\(\\i\\)return \\i\\.\\i\\.Masks\\.STATUS_ONLINE_MOBILE))/,\n replace: \".STATUS_TYPING;$1;switch\"\n },\n {\n // Return the STATUS_ONLINE_MOBILE mask if the user is on mobile, no matter the status\n match: /switch\\(\\i\\)\\{case \\i\\.\\i\\.ONLINE:(if\\(\\i\\)return\\{[^}]+\\})/,\n replace: \"$1;$&\"\n }\n ]\n },\n {\n find: \".AVATAR_STATUS_MOBILE_16;\",\n predicate: () => Settings.plugins.PlatformIndicators.colorMobileIndicator,\n replacement: [\n {\n // Return the AVATAR_STATUS_MOBILE size mask if the user is on mobile, no matter the status\n match: /\\i===\\i\\.\\i\\.ONLINE&&(?=.{0,70}\\.AVATAR_STATUS_MOBILE_16;)/,\n replace: \"\"\n },\n {\n // Fix sizes for mobile indicators which aren't online\n match: /(?<=\\(\\i\\.status,)(\\i)(?=,(\\i),\\i\\))/,\n replace: (_, userStatus, isMobile) => `${isMobile}?\"online\":${userStatus}`\n },\n {\n // Make isMobile true no matter the status\n match: /(?<=\\i&&!\\i)&&\\i===\\i\\.\\i\\.ONLINE/,\n replace: \"\"\n }\n ]\n },\n {\n find: \"}isMobileOnline(\",\n predicate: () => Settings.plugins.PlatformIndicators.colorMobileIndicator,\n replacement: {\n // Make isMobileOnline return true no matter what is the user status\n match: /(?<=\\i\\[\\i\\.\\i\\.MOBILE\\])===\\i\\.\\i\\.ONLINE/,\n replace: \"!= null\"\n }\n }\n ],\n\n options: {\n ...Object.fromEntries(\n Object.entries(indicatorLocations).map(([key, value]) => {\n return [key, {\n type: OptionType.BOOLEAN,\n description: `Show indicators ${value.description.toLowerCase()}`,\n // onChange doesn't give any way to know which setting was changed, so restart required\n restartNeeded: true,\n default: true\n }];\n })\n ),\n colorMobileIndicator: {\n type: OptionType.BOOLEAN,\n description: \"Whether to make the mobile indicator match the color of the user status.\",\n default: true,\n restartNeeded: true\n }\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { generateId, sendBotMessage } from \"@api/Commands\";\nimport ErrorBoundary from \"@components/ErrorBoundary\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\nimport { findByPropsLazy } from \"@webpack\";\nimport { Button, ButtonLooks, ButtonWrapperClasses, DraftStore, DraftType, SelectedChannelStore, Tooltip, UserStore, useStateFromStores } from \"@webpack/common\";\nimport { MessageAttachment } from \"discord-types/general\";\n\ninterface Props {\n type: {\n analyticsName: string;\n isEmpty: boolean;\n attachments: boolean;\n };\n}\n\nconst UploadStore = findByPropsLazy(\"getUploads\");\n\nconst getDraft = (channelId: string) => DraftStore.getDraft(channelId, DraftType.ChannelMessage);\n\n\nconst getImageBox = (url: string): Promise<{ width: number, height: number; } | null> =>\n new Promise(res => {\n const img = new Image();\n img.onload = () =>\n res({ width: img.width, height: img.height });\n\n img.onerror = () =>\n res(null);\n\n img.src = url;\n });\n\n\nconst getAttachments = async (channelId: string) =>\n await Promise.all(\n UploadStore.getUploads(channelId, DraftType.ChannelMessage)\n .map(async (upload: any) => {\n const { isImage, filename, spoiler, item: { file } } = upload;\n const url = URL.createObjectURL(file);\n const attachment: MessageAttachment = {\n id: generateId(),\n filename: spoiler ? \"SPOILER_\" + filename : filename,\n // weird eh? if i give it the normal content type the preview doenst work\n content_type: undefined,\n size: await upload.getSize(),\n spoiler,\n // discord adds query params to the url, so we need to add a hash to prevent that\n url: url + \"#\",\n proxy_url: url + \"#\",\n };\n\n if (isImage) {\n const box = await getImageBox(url);\n if (!box) return attachment;\n\n attachment.width = box.width;\n attachment.height = box.height;\n }\n\n return attachment;\n })\n );\n\n\nexport function PreviewButton(chatBoxProps: Props) {\n const { isEmpty, attachments } = chatBoxProps.type;\n\n const channelId = SelectedChannelStore.getChannelId();\n const draft = useStateFromStores([DraftStore], () => getDraft(channelId));\n\n if (chatBoxProps.type.analyticsName !== \"normal\") return null;\n\n const hasAttachments = attachments && UploadStore.getUploads(channelId, DraftType.ChannelMessage).length > 0;\n const hasContent = !isEmpty && draft?.length > 0;\n\n if (!hasContent && !hasAttachments) return null;\n\n return (\n <Tooltip text=\"Preview Message\">\n {tooltipProps => (\n <Button\n {...tooltipProps}\n onClick={async () =>\n sendBotMessage(\n channelId,\n {\n content: getDraft(channelId),\n author: UserStore.getCurrentUser(),\n attachments: hasAttachments ? await getAttachments(channelId) : undefined,\n }\n )}\n size=\"\"\n look={ButtonLooks.BLANK}\n innerClassName={ButtonWrapperClasses.button}\n style={{ padding: \"0 2px\", height: \"100%\" }}\n >\n <div className={ButtonWrapperClasses.buttonWrapper}>\n <img width={24} height={24} src=\"https://discord.com/assets/4c5a77a89716352686f590a6f014770c.svg\" />\n </div>\n </Button>\n )}\n </Tooltip>\n );\n\n}\n\nexport default definePlugin({\n name: \"PreviewMessage\",\n description: \"Lets you preview your message before sending it.\",\n authors: [Devs.Aria],\n patches: [\n {\n find: \"ChannelTextAreaButtons\",\n replacement: {\n match: /(\\i)\\.push.{1,30}disabled:(\\i),.{1,20}\\},\"gift\"\\)\\)/,\n replace: \"$&,(()=>{try{$2||$1.push($self.chatBarIcon(arguments[0]))}catch{}})()\",\n }\n },\n ],\n\n chatBarIcon: ErrorBoundary.wrap(PreviewButton, { noop: true }),\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Link } from \"@components/Link\";\nimport { Forms, React } from \"@webpack/common\";\n\nexport default function PronounsAboutComponent() {\n return (\n <React.Fragment>\n <Forms.FormTitle tag=\"h3\">More Information</Forms.FormTitle>\n <Forms.FormText>To add your own pronouns, visit{\" \"}\n <Link href=\"https://pronoundb.org\">pronoundb.org</Link>\n </Forms.FormText>\n <Forms.FormDivider />\n <Forms.FormText>\n The two pronoun formats are lowercase and capitalized. Example:\n <ul>\n <li>Lowercase: they/them</li>\n <li>Capitalized: They/Them</li>\n </ul>\n Text like \"Ask me my pronouns\" or \"Any pronouns\" will always be capitalized. <br /><br />\n You can also configure whether or not to display pronouns for the current user (since you probably already know them)\n </Forms.FormText>\n </React.Fragment>\n );\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { definePluginSettings } from \"@api/Settings\";\nimport { OptionType } from \"@utils/types\";\n\nimport { PronounsFormat, PronounSource } from \"./pronoundbUtils\";\n\nexport const settings = definePluginSettings({\n pronounsFormat: {\n type: OptionType.SELECT,\n description: \"The format for pronouns to appear in chat\",\n options: [\n {\n label: \"Lowercase\",\n value: PronounsFormat.Lowercase,\n default: true\n },\n {\n label: \"Capitalized\",\n value: PronounsFormat.Capitalized\n }\n ]\n },\n pronounSource: {\n type: OptionType.SELECT,\n description: \"Where to source pronouns from\",\n options: [\n {\n label: \"Prefer PronounDB, fall back to Discord\",\n value: PronounSource.PreferPDB,\n default: true\n },\n {\n label: \"Prefer Discord, fall back to PronounDB (might lead to inconsistency between pronouns in chat and profile)\",\n value: PronounSource.PreferDiscord\n }\n ]\n },\n showSelf: {\n type: OptionType.BOOLEAN,\n description: \"Enable or disable showing pronouns for the current user\",\n default: true\n },\n showInMessages: {\n type: OptionType.BOOLEAN,\n description: \"Show in messages\",\n default: true\n },\n showInProfile: {\n type: OptionType.BOOLEAN,\n description: \"Show in profile\",\n default: true\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nexport interface UserProfileProps {\n userId: string;\n}\n\nexport interface UserProfilePronounsProps {\n currentPronouns: string | null;\n hidePersonalInformation: boolean;\n}\n\nexport interface PronounsResponse {\n [id: string]: PronounCode;\n}\n\nexport type PronounCode = keyof typeof PronounMapping;\n\nexport const PronounMapping = {\n hh: \"He/Him\",\n hi: \"He/It\",\n hs: \"He/She\",\n ht: \"He/They\",\n ih: \"It/Him\",\n ii: \"It/Its\",\n is: \"It/She\",\n it: \"It/They\",\n shh: \"She/He\",\n sh: \"She/Her\",\n si: \"She/It\",\n st: \"She/They\",\n th: \"They/He\",\n ti: \"They/It\",\n ts: \"They/She\",\n tt: \"They/Them\",\n any: \"Any pronouns\",\n other: \"Other pronouns\",\n ask: \"Ask me my pronouns\",\n avoid: \"Avoid pronouns, use my name\",\n unspecified: \"Unspecified\"\n} as const;\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Settings } from \"@api/Settings\";\nimport { VENCORD_USER_AGENT } from \"@utils/constants\";\nimport { debounce } from \"@utils/debounce\";\nimport { getCurrentChannel } from \"@utils/discord\";\nimport { useAwaiter } from \"@utils/react\";\nimport { UserProfileStore, UserStore } from \"@webpack/common\";\n\nimport { settings } from \"./settings\";\nimport { PronounCode, PronounMapping, PronounsResponse } from \"./types\";\n\ntype PronounsWithSource = [string | null, string];\nconst EmptyPronouns: PronounsWithSource = [null, \"\"];\n\nexport const enum PronounsFormat {\n Lowercase = \"LOWERCASE\",\n Capitalized = \"CAPITALIZED\"\n}\n\nexport const enum PronounSource {\n PreferPDB,\n PreferDiscord\n}\n\n// A map of cached pronouns so the same request isn't sent twice\nconst cache: Record<string, PronounCode> = {};\n// A map of ids and callbacks that should be triggered on fetch\nconst requestQueue: Record<string, ((pronouns: PronounCode) => void)[]> = {};\n\n// Executes all queued requests and calls their callbacks\nconst bulkFetch = debounce(async () => {\n const ids = Object.keys(requestQueue);\n const pronouns = await bulkFetchPronouns(ids);\n for (const id of ids) {\n // Call all callbacks for the id\n requestQueue[id]?.forEach(c => c(pronouns[id]));\n delete requestQueue[id];\n }\n});\n\nfunction getDiscordPronouns(id: string, useGlobalProfile: boolean = false) {\n const globalPronouns = UserProfileStore.getUserProfile(id)?.pronouns;\n\n if (useGlobalProfile) return globalPronouns;\n\n return (\n UserProfileStore.getGuildMemberProfile(id, getCurrentChannel()?.guild_id)?.pronouns\n || globalPronouns\n );\n}\n\nexport function useFormattedPronouns(id: string, useGlobalProfile: boolean = false): PronounsWithSource {\n // Discord is so stupid you can put tons of newlines in pronouns\n const discordPronouns = getDiscordPronouns(id, useGlobalProfile)?.trim().replace(NewLineRe, \" \");\n\n const [result] = useAwaiter(() => fetchPronouns(id), {\n fallbackValue: getCachedPronouns(id),\n onError: e => console.error(\"Fetching pronouns failed: \", e)\n });\n\n if (settings.store.pronounSource === PronounSource.PreferDiscord && discordPronouns)\n return [discordPronouns, \"Discord\"];\n\n if (result && result !== \"unspecified\")\n return [formatPronouns(result), \"PronounDB\"];\n\n return [discordPronouns, \"Discord\"];\n}\n\nexport function useProfilePronouns(id: string, useGlobalProfile: boolean = false): PronounsWithSource {\n const pronouns = useFormattedPronouns(id, useGlobalProfile);\n\n if (!settings.store.showInProfile) return EmptyPronouns;\n if (!settings.store.showSelf && id === UserStore.getCurrentUser().id) return EmptyPronouns;\n\n return pronouns;\n}\n\n\nconst NewLineRe = /\\n+/g;\n\n// Gets the cached pronouns, if you're too impatient for a promise!\nexport function getCachedPronouns(id: string): string | null {\n const cached = cache[id];\n if (cached && cached !== \"unspecified\") return cached;\n\n return cached || null;\n}\n\n// Fetches the pronouns for one id, returning a promise that resolves if it was cached, or once the request is completed\nexport function fetchPronouns(id: string): Promise<string> {\n return new Promise(res => {\n const cached = getCachedPronouns(id);\n if (cached) return res(cached);\n\n // If there is already a request added, then just add this callback to it\n if (id in requestQueue) return requestQueue[id].push(res);\n\n // If not already added, then add it and call the debounced function to make sure the request gets executed\n requestQueue[id] = [res];\n bulkFetch();\n });\n}\n\nasync function bulkFetchPronouns(ids: string[]): Promise<PronounsResponse> {\n const params = new URLSearchParams();\n params.append(\"platform\", \"discord\");\n params.append(\"ids\", ids.join(\",\"));\n\n try {\n const req = await fetch(\"https://pronoundb.org/api/v1/lookup-bulk?\" + params.toString(), {\n method: \"GET\",\n headers: {\n \"Accept\": \"application/json\",\n \"X-PronounDB-Source\": VENCORD_USER_AGENT\n }\n });\n return await req.json()\n .then((res: PronounsResponse) => {\n Object.assign(cache, res);\n return res;\n });\n } catch (e) {\n // If the request errors, treat it as if no pronouns were found for all ids, and log it\n console.error(\"PronounDB fetching failed: \", e);\n const dummyPronouns = Object.fromEntries(ids.map(id => [id, \"unspecified\"] as const));\n Object.assign(cache, dummyPronouns);\n return dummyPronouns;\n }\n}\n\nexport function formatPronouns(pronouns: string): string {\n const { pronounsFormat } = Settings.plugins.PronounDB as { pronounsFormat: PronounsFormat, enabled: boolean; };\n // For capitalized pronouns, just return the mapping (it is by default capitalized)\n if (pronounsFormat === PronounsFormat.Capitalized) return PronounMapping[pronouns];\n // If it is set to lowercase and a special code (any, ask, avoid), then just return the capitalized text\n else if (\n pronounsFormat === PronounsFormat.Lowercase\n && [\"any\", \"ask\", \"avoid\", \"other\"].includes(pronouns)\n ) return PronounMapping[pronouns];\n // Otherwise (lowercase and not a special code), then convert the mapping to lowercase\n else return PronounMapping[pronouns].toLowerCase();\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport ErrorBoundary from \"@components/ErrorBoundary\";\nimport { classes } from \"@utils/misc\";\nimport { findByPropsLazy } from \"@webpack\";\nimport { UserStore } from \"@webpack/common\";\nimport { Message } from \"discord-types/general\";\n\nimport { useFormattedPronouns } from \"../pronoundbUtils\";\nimport { settings } from \"../settings\";\n\nconst styles: Record<string, string> = findByPropsLazy(\"timestampInline\");\n\nconst AUTO_MODERATION_ACTION = 24;\n\nfunction shouldShow(message: Message): boolean {\n if (!settings.store.showInMessages)\n return false;\n if (message.author.bot || message.author.system || message.type === AUTO_MODERATION_ACTION)\n return false;\n if (!settings.store.showSelf && message.author.id === UserStore.getCurrentUser().id)\n return false;\n\n return true;\n}\n\nexport const PronounsChatComponentWrapper = ErrorBoundary.wrap(({ message }: { message: Message; }) => {\n return shouldShow(message)\n ? <PronounsChatComponent message={message} />\n : null;\n}, { noop: true });\n\nexport const CompactPronounsChatComponentWrapper = ErrorBoundary.wrap(({ message }: { message: Message; }) => {\n return shouldShow(message)\n ? <CompactPronounsChatComponent message={message} />\n : null;\n}, { noop: true });\n\nfunction PronounsChatComponent({ message }: { message: Message; }) {\n const [result] = useFormattedPronouns(message.author.id);\n\n return result\n ? (\n <span\n className={classes(styles.timestampInline, styles.timestamp)}\n >\u2022 {result}</span>\n )\n : null;\n}\n\nexport const CompactPronounsChatComponent = ErrorBoundary.wrap(({ message }: { message: Message; }) => {\n const [result] = useFormattedPronouns(message.author.id);\n\n return result\n ? (\n <span\n className={classes(styles.timestampInline, styles.timestamp, \"vc-pronoundb-compact\")}\n >\u2022 {result}</span>\n )\n : null;\n}, { noop: true });\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport \"./styles.css\";\n\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\n\nimport PronounsAboutComponent from \"./components/PronounsAboutComponent\";\nimport { CompactPronounsChatComponentWrapper, PronounsChatComponentWrapper } from \"./components/PronounsChatComponent\";\nimport { useProfilePronouns } from \"./pronoundbUtils\";\nimport { settings } from \"./settings\";\n\nconst PRONOUN_TOOLTIP_PATCH = {\n match: /text:(.{0,10}.Messages\\.USER_PROFILE_PRONOUNS)(?=,)/,\n replace: '$& + (typeof vcPronounSource !== \"undefined\" ? ` (${vcPronounSource})` : \"\")'\n};\n\nexport default definePlugin({\n name: \"PronounDB\",\n authors: [Devs.Tyman, Devs.TheKodeToad, Devs.Ven],\n description: \"Adds pronouns to user messages using pronoundb\",\n patches: [\n // Add next to username (compact mode)\n {\n find: \"showCommunicationDisabledStyles\",\n replacement: {\n match: /(\"span\",{id:\\i,className:\\i,children:\\i}\\))/,\n replace: \"$1, $self.CompactPronounsChatComponentWrapper(arguments[0])\"\n }\n },\n // Patch the chat timestamp element (normal mode)\n {\n find: \"showCommunicationDisabledStyles\",\n replacement: {\n match: /(?<=return\\s*\\(0,\\i\\.jsxs?\\)\\(.+!\\i&&)(\\(0,\\i.jsxs?\\)\\(.+?\\{.+?\\}\\))/,\n replace: \"[$1, $self.PronounsChatComponentWrapper(arguments[0])]\"\n }\n },\n // Patch the profile popout username header to use our pronoun hook instead of Discord's pronouns\n {\n find: \".userTagNoNickname\",\n replacement: [\n {\n match: /{user:(\\i),[^}]*,pronouns:(\\i),[^}]*}=\\i;/,\n replace: \"$&let vcPronounSource;[$2,vcPronounSource]=$self.useProfilePronouns($1.id);\"\n },\n PRONOUN_TOOLTIP_PATCH\n ]\n },\n // Patch the profile modal username header to use our pronoun hook instead of Discord's pronouns\n {\n find: \".nameTagSmall)\",\n replacement: [\n {\n match: /\\.getName\\(\\i\\);(?<=displayProfile.{0,200})/,\n replace: \"$&const [vcPronounce,vcPronounSource]=$self.useProfilePronouns(arguments[0].user.id,true);if(arguments[0].displayProfile&&vcPronounce)arguments[0].displayProfile.pronouns=vcPronounce;\"\n },\n PRONOUN_TOOLTIP_PATCH\n ]\n }\n ],\n\n settings,\n\n settingsAboutComponent: PronounsAboutComponent,\n\n // Re-export the components on the plugin object so it is easily accessible in patches\n PronounsChatComponentWrapper,\n CompactPronounsChatComponentWrapper,\n useProfilePronouns\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { addButton, removeButton } from \"@api/MessagePopover\";\nimport { Devs } from \"@utils/constants\";\nimport { insertTextIntoChatInputBox } from \"@utils/discord\";\nimport definePlugin from \"@utils/types\";\nimport { ChannelStore, PermissionsBits, PermissionStore } from \"@webpack/common\";\n\nexport default definePlugin({\n name: \"QuickMention\",\n authors: [Devs.kemo],\n description: \"Adds a quick mention button to the message actions bar\",\n dependencies: [\"MessagePopoverAPI\"],\n\n start() {\n addButton(\"QuickMention\", msg => {\n const channel = ChannelStore.getChannel(msg.channel_id);\n if (channel.guild_id && !PermissionStore.can(PermissionsBits.SEND_MESSAGES, channel)) return null;\n\n return {\n label: \"Quick Mention\",\n icon: this.Icon,\n message: msg,\n channel,\n onClick: () => insertTextIntoChatInputBox(`<@${msg.author.id}> `)\n };\n });\n },\n stop() {\n removeButton(\"QuickMention\");\n },\n\n Icon: () => (\n <svg\n className=\"icon\"\n height=\"24\"\n width=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n >\n <path\n d=\"M12 2C6.486 2 2 6.486 2 12C2 17.515 6.486 22 12 22C14.039 22 15.993 21.398 17.652 20.259L16.521 18.611C15.195 19.519 13.633 20 12 20C7.589 20 4 16.411 4 12C4 7.589 7.589 4 12 4C16.411 4 20 7.589 20 12V12.782C20 14.17 19.402 15 18.4 15L18.398 15.018C18.338 15.005 18.273 15 18.209 15H18C17.437 15 16.6 14.182 16.6 13.631V12C16.6 9.464 14.537 7.4 12 7.4C9.463 7.4 7.4 9.463 7.4 12C7.4 14.537 9.463 16.6 12 16.6C13.234 16.6 14.35 16.106 15.177 15.313C15.826 16.269 16.93 17 18 17L18.002 16.981C18.064 16.994 18.129 17 18.195 17H18.4C20.552 17 22 15.306 22 12.782V12C22 6.486 17.514 2 12 2ZM12 14.599C10.566 14.599 9.4 13.433 9.4 11.999C9.4 10.565 10.566 9.399 12 9.399C13.434 9.399 14.6 10.565 14.6 11.999C14.6 13.433 13.434 14.599 12 14.599Z\"\n />\n </svg>\n ),\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { definePluginSettings, Settings } from \"@api/Settings\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { findByPropsLazy } from \"@webpack\";\nimport { ChannelStore, FluxDispatcher as Dispatcher, MessageStore, PermissionsBits, PermissionStore, SelectedChannelStore, UserStore } from \"@webpack/common\";\nimport { Message } from \"discord-types/general\";\n\nconst Kangaroo = findByPropsLazy(\"jumpToMessage\");\n\nconst isMac = navigator.platform.includes(\"Mac\"); // bruh\nlet replyIdx = -1;\nlet editIdx = -1;\n\n\nconst enum MentionOptions {\n DISABLED,\n ENABLED,\n NO_REPLY_MENTION_PLUGIN\n}\n\nconst settings = definePluginSettings({\n shouldMention: {\n type: OptionType.SELECT,\n description: \"Ping reply by default\",\n options: [\n {\n label: \"Follow NoReplyMention\",\n value: MentionOptions.NO_REPLY_MENTION_PLUGIN,\n default: true\n },\n { label: \"Enabled\", value: MentionOptions.ENABLED },\n { label: \"Disabled\", value: MentionOptions.DISABLED },\n ]\n }\n});\n\nexport default definePlugin({\n name: \"QuickReply\",\n authors: [Devs.obscurity, Devs.Ven, Devs.pylix],\n description: \"Reply to (ctrl + up/down) and edit (ctrl + shift + up/down) messages via keybinds\",\n settings,\n\n start() {\n Dispatcher.subscribe(\"DELETE_PENDING_REPLY\", onDeletePendingReply);\n Dispatcher.subscribe(\"MESSAGE_END_EDIT\", onEndEdit);\n Dispatcher.subscribe(\"MESSAGE_START_EDIT\", onStartEdit);\n Dispatcher.subscribe(\"CREATE_PENDING_REPLY\", onCreatePendingReply);\n document.addEventListener(\"keydown\", onKeydown);\n },\n\n stop() {\n Dispatcher.unsubscribe(\"DELETE_PENDING_REPLY\", onDeletePendingReply);\n Dispatcher.unsubscribe(\"MESSAGE_END_EDIT\", onEndEdit);\n Dispatcher.unsubscribe(\"MESSAGE_START_EDIT\", onStartEdit);\n Dispatcher.unsubscribe(\"CREATE_PENDING_REPLY\", onCreatePendingReply);\n document.removeEventListener(\"keydown\", onKeydown);\n },\n});\n\nconst onDeletePendingReply = () => replyIdx = -1;\nconst onEndEdit = () => editIdx = -1;\n\nfunction calculateIdx(messages: Message[], id: string) {\n const idx = messages.findIndex(m => m.id === id);\n return idx === -1\n ? idx\n : messages.length - idx - 1;\n}\n\nfunction onStartEdit({ channelId, messageId, _isQuickEdit }: any) {\n if (_isQuickEdit) return;\n\n const meId = UserStore.getCurrentUser().id;\n\n const messages = MessageStore.getMessages(channelId)._array.filter(m => m.author.id === meId);\n editIdx = calculateIdx(messages, messageId);\n}\n\nfunction onCreatePendingReply({ message, _isQuickReply }: { message: Message; _isQuickReply: boolean; }) {\n if (_isQuickReply) return;\n\n replyIdx = calculateIdx(MessageStore.getMessages(message.channel_id)._array, message.id);\n}\n\nconst isCtrl = (e: KeyboardEvent) => isMac ? e.metaKey : e.ctrlKey;\nconst isAltOrMeta = (e: KeyboardEvent) => e.altKey || (!isMac && e.metaKey);\n\nfunction onKeydown(e: KeyboardEvent) {\n const isUp = e.key === \"ArrowUp\";\n if (!isUp && e.key !== \"ArrowDown\") return;\n if (!isCtrl(e) || isAltOrMeta(e)) return;\n\n if (e.shiftKey)\n nextEdit(isUp);\n else\n nextReply(isUp);\n}\n\nfunction jumpIfOffScreen(channelId: string, messageId: string) {\n const element = document.getElementById(\"message-content-\" + messageId);\n if (!element) return;\n\n const vh = Math.max(document.documentElement.clientHeight, window.innerHeight);\n const rect = element.getBoundingClientRect();\n const isOffscreen = rect.bottom < 200 || rect.top - vh >= -200;\n\n if (isOffscreen) {\n Kangaroo.jumpToMessage({\n channelId,\n messageId,\n flash: false,\n jumpType: \"INSTANT\"\n });\n }\n}\n\nfunction getNextMessage(isUp: boolean, isReply: boolean) {\n let messages: Array<Message & { deleted?: boolean; }> = MessageStore.getMessages(SelectedChannelStore.getChannelId())._array;\n if (!isReply) { // we are editing so only include own\n const meId = UserStore.getCurrentUser().id;\n messages = messages.filter(m => m.author.id === meId);\n }\n\n const mutate = (i: number) => isUp\n ? Math.min(messages.length - 1, i + 1)\n : Math.max(-1, i - 1);\n\n const findNextNonDeleted = (i: number) => {\n do {\n i = mutate(i);\n } while (i !== -1 && messages[messages.length - i - 1]?.deleted === true);\n return i;\n };\n\n let i: number;\n if (isReply)\n replyIdx = i = findNextNonDeleted(replyIdx);\n else\n editIdx = i = findNextNonDeleted(editIdx);\n\n return i === - 1 ? undefined : messages[messages.length - i - 1];\n}\n\nfunction shouldMention(message) {\n const { enabled, userList, shouldPingListed } = Settings.plugins.NoReplyMention;\n const shouldPing = !enabled || (shouldPingListed === userList.includes(message.author.id));\n\n switch (settings.store.shouldMention) {\n case MentionOptions.NO_REPLY_MENTION_PLUGIN: return shouldPing;\n case MentionOptions.DISABLED: return false;\n default: return true;\n }\n}\n\n// handle next/prev reply\nfunction nextReply(isUp: boolean) {\n const currChannel = ChannelStore.getChannel(SelectedChannelStore.getChannelId());\n if (currChannel.guild_id && !PermissionStore.can(PermissionsBits.SEND_MESSAGES, currChannel)) return;\n const message = getNextMessage(isUp, true);\n\n if (!message)\n return void Dispatcher.dispatch({\n type: \"DELETE_PENDING_REPLY\",\n channelId: SelectedChannelStore.getChannelId(),\n });\n const channel = ChannelStore.getChannel(message.channel_id);\n const meId = UserStore.getCurrentUser().id;\n\n Dispatcher.dispatch({\n type: \"CREATE_PENDING_REPLY\",\n channel,\n message,\n shouldMention: shouldMention(message),\n showMentionToggle: channel.guild_id !== null && message.author.id !== meId,\n _isQuickReply: true\n });\n jumpIfOffScreen(channel.id, message.id);\n}\n\n// handle next/prev edit\nfunction nextEdit(isUp: boolean) {\n const currChannel = ChannelStore.getChannel(SelectedChannelStore.getChannelId());\n if (currChannel.guild_id && !PermissionStore.can(PermissionsBits.SEND_MESSAGES, currChannel)) return;\n const message = getNextMessage(isUp, false);\n\n if (!message)\n return Dispatcher.dispatch({\n type: \"MESSAGE_END_EDIT\",\n channelId: SelectedChannelStore.getChannelId()\n });\n Dispatcher.dispatch({\n type: \"MESSAGE_START_EDIT\",\n channelId: message.channel_id,\n messageId: message.id,\n content: message.content,\n _isQuickEdit: true\n });\n jumpIfOffScreen(message.channel_id, message.id);\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\nimport { React } from \"@webpack/common\";\n\nlet ERROR_CODES: any;\n\nexport default definePlugin({\n name: \"ReactErrorDecoder\",\n description: 'Replaces \"Minifed React Error\" with the actual error.',\n authors: [Devs.Cyn, Devs.maisymoe],\n patches: [\n {\n find: '\"https://reactjs.org/docs/error-decoder.html?invariant=\"',\n replacement: {\n match: /(function .\\(.\\)){(for\\(var .=\"https:\\/\\/reactjs\\.org\\/docs\\/error-decoder\\.html\\?invariant=\"\\+.,.=1;.<arguments\\.length;.\\+\\+\\).\\+=\"&args\\[\\]=\"\\+encodeURIComponent\\(arguments\\[.\\]\\);return\"Minified React error #\"\\+.\\+\"; visit \"\\+.\\+\" for the full message or use the non-minified dev environment for full errors and additional helpful warnings.\")}/,\n replace: (_, func, original) =>\n `${func}{var decoded=$self.decodeError.apply(null, arguments);if(decoded)return decoded;${original}}`,\n },\n },\n ],\n\n async start() {\n const CODES_URL = `https://raw.githubusercontent.com/facebook/react/v${React.version}/scripts/error-codes/codes.json`;\n\n ERROR_CODES = await fetch(CODES_URL)\n .then(res => res.json())\n .catch(e => console.error(\"[ReactErrorDecoder] Failed to fetch React error codes\\n\", e));\n },\n\n stop() {\n ERROR_CODES = undefined;\n },\n\n decodeError(code: number, ...args: any) {\n let index = 0;\n return ERROR_CODES?.[code]?.replace(/%s/g, () => {\n const arg = args[index];\n index++;\n return arg;\n });\n },\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Logger } from \"@utils/Logger\";\n\nconst logger = new Logger(\"ServerListAPI\");\n\nexport const enum ServerListRenderPosition {\n Above,\n In,\n}\n\nconst renderFunctionsAbove = new Set<Function>();\nconst renderFunctionsIn = new Set<Function>();\n\nfunction getRenderFunctions(position: ServerListRenderPosition) {\n return position === ServerListRenderPosition.Above ? renderFunctionsAbove : renderFunctionsIn;\n}\n\nexport function addServerListElement(position: ServerListRenderPosition, renderFunction: Function) {\n getRenderFunctions(position).add(renderFunction);\n}\n\nexport function removeServerListElement(position: ServerListRenderPosition, renderFunction: Function) {\n getRenderFunctions(position).delete(renderFunction);\n}\n\nexport const renderAll = (position: ServerListRenderPosition) => {\n const ret: Array<JSX.Element> = [];\n\n for (const renderFunction of getRenderFunctions(position)) {\n try {\n ret.unshift(renderFunction());\n } catch (e) {\n logger.error(\"Failed to render server list element:\", e);\n }\n }\n\n return ret;\n};\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { addServerListElement, removeServerListElement, ServerListRenderPosition } from \"@api/ServerList\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\nimport { Button, FluxDispatcher, GuildChannelStore, GuildStore, React, ReadStateStore } from \"@webpack/common\";\n\nfunction onClick() {\n const channels: Array<any> = [];\n\n Object.values(GuildStore.getGuilds()).forEach(guild => {\n GuildChannelStore.getChannels(guild.id).SELECTABLE.forEach((c: { channel: { id: string; }; }) => {\n if (!ReadStateStore.hasUnread(c.channel.id)) return;\n\n channels.push({\n channelId: c.channel.id,\n // messageId: c.channel?.lastMessageId,\n messageId: ReadStateStore.lastMessageId(c.channel.id),\n readStateType: 0\n });\n });\n });\n\n FluxDispatcher.dispatch({\n type: \"BULK_ACK\",\n context: \"APP\",\n channels: channels\n });\n}\n\nconst ReadAllButton = () => (\n <Button\n onClick={onClick}\n size={Button.Sizes.MIN}\n color={Button.Colors.BRAND}\n style={{ marginTop: \"2px\", marginBottom: \"8px\", marginLeft: \"9px\" }}\n >Read all</Button>\n);\n\nexport default definePlugin({\n name: \"ReadAllNotificationsButton\",\n description: \"Read all server notifications with a single button click!\",\n authors: [Devs.kemo],\n dependencies: [\"ServerListAPI\"],\n\n renderReadAllButton: () => <ReadAllButton />,\n\n start() {\n addServerListElement(ServerListRenderPosition.Above, this.renderReadAllButton);\n },\n\n stop() {\n removeServerListElement(ServerListRenderPosition.Above, this.renderReadAllButton);\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { definePluginSettings } from \"@api/Settings\";\nimport { OptionType } from \"@utils/types\";\n\nexport default definePluginSettings({\n notices: {\n type: OptionType.BOOLEAN,\n description: \"Also show a notice at the top of your screen when removed (use this if you don't want to miss any notifications).\",\n default: false\n },\n offlineRemovals: {\n type: OptionType.BOOLEAN,\n description: \"Notify you when starting discord if you were removed while offline.\",\n default: true\n },\n friends: {\n type: OptionType.BOOLEAN,\n description: \"Notify when a friend removes you\",\n default: true\n },\n friendRequestCancels: {\n type: OptionType.BOOLEAN,\n description: \"Notify when a friend request is cancelled\",\n default: true\n },\n servers: {\n type: OptionType.BOOLEAN,\n description: \"Notify when removed from a server\",\n default: true\n },\n groups: {\n type: OptionType.BOOLEAN,\n description: \"Notify when removed from a group chat\",\n default: true\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Channel } from \"discord-types/general\";\n\nexport interface ChannelDelete {\n type: \"CHANNEL_DELETE\";\n channel: Channel;\n}\n\nexport interface GuildDelete {\n type: \"GUILD_DELETE\";\n guild: {\n id: string;\n unavailable?: boolean;\n };\n}\n\nexport interface RelationshipRemove {\n type: \"RELATIONSHIP_REMOVE\";\n relationship: {\n id: string;\n nickname: string;\n type: number;\n };\n}\n\nexport interface SimpleGroupChannel {\n id: string;\n name: string;\n iconURL?: string;\n}\n\nexport interface SimpleGuild {\n id: string;\n name: string;\n iconURL?: string;\n}\n\nexport const enum ChannelType {\n GROUP_DM = 3,\n}\n\nexport const enum RelationshipType {\n FRIEND = 1,\n BLOCKED = 2,\n INCOMING_REQUEST = 3,\n OUTGOING_REQUEST = 4,\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { DataStore, Notices } from \"@api/index\";\nimport { showNotification } from \"@api/Notifications\";\nimport { getUniqueUsername, openUserProfile } from \"@utils/discord\";\nimport { ChannelStore, GuildMemberStore, GuildStore, RelationshipStore, UserStore, UserUtils } from \"@webpack/common\";\n\nimport settings from \"./settings\";\nimport { ChannelType, RelationshipType, SimpleGroupChannel, SimpleGuild } from \"./types\";\n\nconst guilds = new Map<string, SimpleGuild>();\nconst groups = new Map<string, SimpleGroupChannel>();\nconst friends = {\n friends: [] as string[],\n requests: [] as string[]\n};\n\nconst guildsKey = () => `relationship-notifier-guilds-${UserStore.getCurrentUser().id}`;\nconst groupsKey = () => `relationship-notifier-groups-${UserStore.getCurrentUser().id}`;\nconst friendsKey = () => `relationship-notifier-friends-${UserStore.getCurrentUser().id}`;\n\nasync function runMigrations() {\n DataStore.delMany([\"relationship-notifier-guilds\", \"relationship-notifier-groups\", \"relationship-notifier-friends\"]);\n}\n\nexport async function syncAndRunChecks() {\n await runMigrations();\n const [oldGuilds, oldGroups, oldFriends] = await DataStore.getMany([\n guildsKey(),\n groupsKey(),\n friendsKey()\n ]) as [Map<string, SimpleGuild> | undefined, Map<string, SimpleGroupChannel> | undefined, Record<\"friends\" | \"requests\", string[]> | undefined];\n\n await Promise.all([syncGuilds(), syncGroups(), syncFriends()]);\n\n if (settings.store.offlineRemovals) {\n if (settings.store.groups && oldGroups?.size) {\n for (const [id, group] of oldGroups) {\n if (!groups.has(id))\n notify(`You are no longer in the group ${group.name}.`, group.iconURL);\n }\n }\n\n if (settings.store.servers && oldGuilds?.size) {\n for (const [id, guild] of oldGuilds) {\n if (!guilds.has(id))\n notify(`You are no longer in the server ${guild.name}.`, guild.iconURL);\n }\n }\n\n if (settings.store.friends && oldFriends?.friends.length) {\n for (const id of oldFriends.friends) {\n if (friends.friends.includes(id)) continue;\n\n const user = await UserUtils.getUser(id).catch(() => void 0);\n if (user)\n notify(\n `You are no longer friends with ${getUniqueUsername(user)}.`,\n user.getAvatarURL(undefined, undefined, false),\n () => openUserProfile(user.id)\n );\n }\n }\n\n if (settings.store.friendRequestCancels && oldFriends?.requests?.length) {\n for (const id of oldFriends.requests) {\n if (\n friends.requests.includes(id) ||\n [RelationshipType.FRIEND, RelationshipType.BLOCKED, RelationshipType.OUTGOING_REQUEST].includes(RelationshipStore.getRelationshipType(id))\n ) continue;\n\n const user = await UserUtils.getUser(id).catch(() => void 0);\n if (user)\n notify(\n `Friend request from ${getUniqueUsername(user)} has been revoked.`,\n user.getAvatarURL(undefined, undefined, false),\n () => openUserProfile(user.id)\n );\n }\n }\n }\n}\n\nexport function notify(text: string, icon?: string, onClick?: () => void) {\n if (settings.store.notices)\n Notices.showNotice(text, \"OK\", () => Notices.popNotice());\n\n showNotification({\n title: \"Relationship Notifier\",\n body: text,\n icon,\n onClick\n });\n}\n\nexport function getGuild(id: string) {\n return guilds.get(id);\n}\n\nexport function deleteGuild(id: string) {\n guilds.delete(id);\n syncGuilds();\n}\n\nexport async function syncGuilds() {\n guilds.clear();\n\n const me = UserStore.getCurrentUser().id;\n for (const [id, { name, icon }] of Object.entries(GuildStore.getGuilds())) {\n if (GuildMemberStore.isMember(id, me))\n guilds.set(id, {\n id,\n name,\n iconURL: icon && `https://cdn.discordapp.com/icons/${id}/${icon}.png`\n });\n }\n await DataStore.set(guildsKey(), guilds);\n}\n\nexport function getGroup(id: string) {\n return groups.get(id);\n}\n\nexport function deleteGroup(id: string) {\n groups.delete(id);\n syncGroups();\n}\n\nexport async function syncGroups() {\n groups.clear();\n\n for (const { type, id, name, rawRecipients, icon } of ChannelStore.getSortedPrivateChannels()) {\n if (type === ChannelType.GROUP_DM)\n groups.set(id, {\n id,\n name: name || rawRecipients.map(r => r.username).join(\", \"),\n iconURL: icon && `https://cdn.discordapp.com/channel-icons/${id}/${icon}.png`\n });\n }\n\n await DataStore.set(groupsKey(), groups);\n}\n\nexport async function syncFriends() {\n friends.friends = [];\n friends.requests = [];\n\n const relationShips = RelationshipStore.getRelationships();\n for (const id in relationShips) {\n switch (relationShips[id]) {\n case RelationshipType.FRIEND:\n friends.friends.push(id);\n break;\n case RelationshipType.INCOMING_REQUEST:\n friends.requests.push(id);\n break;\n }\n }\n\n await DataStore.set(friendsKey(), friends);\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { getUniqueUsername, openUserProfile } from \"@utils/discord\";\nimport { UserUtils } from \"@webpack/common\";\n\nimport settings from \"./settings\";\nimport { ChannelDelete, ChannelType, GuildDelete, RelationshipRemove, RelationshipType } from \"./types\";\nimport { deleteGroup, deleteGuild, getGroup, getGuild, notify } from \"./utils\";\n\nlet manuallyRemovedFriend: string | undefined;\nlet manuallyRemovedGuild: string | undefined;\nlet manuallyRemovedGroup: string | undefined;\n\nexport const removeFriend = (id: string) => manuallyRemovedFriend = id;\nexport const removeGuild = (id: string) => manuallyRemovedGuild = id;\nexport const removeGroup = (id: string) => manuallyRemovedGroup = id;\n\nexport async function onRelationshipRemove({ relationship: { type, id } }: RelationshipRemove) {\n if (manuallyRemovedFriend === id) {\n manuallyRemovedFriend = undefined;\n return;\n }\n\n const user = await UserUtils.getUser(id)\n .catch(() => null);\n if (!user) return;\n\n switch (type) {\n case RelationshipType.FRIEND:\n if (settings.store.friends)\n notify(\n `${getUniqueUsername(user)} removed you as a friend.`,\n user.getAvatarURL(undefined, undefined, false),\n () => openUserProfile(user.id)\n );\n break;\n case RelationshipType.INCOMING_REQUEST:\n if (settings.store.friendRequestCancels)\n notify(\n `A friend request from ${getUniqueUsername(user)} has been removed.`,\n user.getAvatarURL(undefined, undefined, false),\n () => openUserProfile(user.id)\n );\n break;\n }\n}\n\nexport function onGuildDelete({ guild: { id, unavailable } }: GuildDelete) {\n if (!settings.store.servers) return;\n if (unavailable) return;\n\n if (manuallyRemovedGuild === id) {\n deleteGuild(id);\n manuallyRemovedGuild = undefined;\n return;\n }\n\n const guild = getGuild(id);\n if (guild) {\n deleteGuild(id);\n notify(`You were removed from the server ${guild.name}.`, guild.iconURL);\n }\n}\n\nexport function onChannelDelete({ channel: { id, type } }: ChannelDelete) {\n if (!settings.store.groups) return;\n if (type !== ChannelType.GROUP_DM) return;\n\n if (manuallyRemovedGroup === id) {\n deleteGroup(id);\n manuallyRemovedGroup = undefined;\n return;\n }\n\n const group = getGroup(id);\n if (group) {\n deleteGroup(id);\n notify(`You were removed from the group ${group.name}.`, group.iconURL);\n }\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\n\nimport { onChannelDelete, onGuildDelete, onRelationshipRemove, removeFriend, removeGroup, removeGuild } from \"./functions\";\nimport settings from \"./settings\";\nimport { syncAndRunChecks, syncFriends, syncGroups, syncGuilds } from \"./utils\";\n\nexport default definePlugin({\n name: \"RelationshipNotifier\",\n description: \"Notifies you when a friend, group chat, or server removes you.\",\n authors: [Devs.nick],\n settings,\n\n patches: [\n {\n find: \"removeRelationship:(\",\n replacement: {\n match: /(removeRelationship:\\((\\i),\\i,\\i\\)=>)/,\n replace: \"$1($self.removeFriend($2),0)||\"\n }\n },\n {\n find: \"async leaveGuild(\",\n replacement: {\n match: /(leaveGuild\\((\\i)\\){)/,\n replace: \"$1$self.removeGuild($2);\"\n }\n },\n {\n find: \"},closePrivateChannel(\",\n replacement: {\n match: /(closePrivateChannel\\((\\i)\\){)/,\n replace: \"$1$self.removeGroup($2);\"\n }\n }\n ],\n\n flux: {\n GUILD_CREATE: syncGuilds,\n GUILD_DELETE: onGuildDelete,\n CHANNEL_CREATE: syncGroups,\n CHANNEL_DELETE: onChannelDelete,\n RELATIONSHIP_ADD: syncFriends,\n RELATIONSHIP_UPDATE: syncFriends,\n RELATIONSHIP_REMOVE(e) {\n onRelationshipRemove(e);\n syncFriends();\n },\n CONNECTION_OPEN: syncAndRunChecks\n },\n\n async start() {\n setTimeout(() => {\n syncAndRunChecks();\n }, 5000);\n },\n\n removeFriend,\n removeGroup,\n removeGuild\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\nimport { findByPropsLazy } from \"@webpack\";\n\nconst SpoilerClasses = findByPropsLazy(\"spoilerContent\");\nconst MessagesClasses = findByPropsLazy(\"messagesWrapper\", \"messages\");\n\nexport default definePlugin({\n name: \"RevealAllSpoilers\",\n description: \"Reveal all spoilers in a message by Ctrl-clicking a spoiler, or in the chat with Ctrl+Shift-click\",\n authors: [Devs.whqwert],\n\n patches: [\n {\n find: \".removeObscurity=\",\n replacement: {\n match: /(?<=\\.removeObscurity=(\\i)=>{)/,\n replace: (_, event) => `$self.reveal(${event});`\n }\n }\n ],\n\n reveal(event: MouseEvent) {\n const { ctrlKey, shiftKey, target } = event;\n\n if (!ctrlKey) { return; }\n\n const { spoilerContent, hidden } = SpoilerClasses;\n const { messagesWrapper } = MessagesClasses;\n\n const parent = shiftKey\n ? document.querySelector(`div.${messagesWrapper}`)\n : (target as HTMLSpanElement).parentElement;\n\n for (const spoiler of parent!.querySelectorAll(`span.${spoilerContent}.${hidden}`)) {\n (spoiler as HTMLSpanElement).click();\n }\n }\n\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { addContextMenuPatch, findGroupChildrenByChildId, NavContextMenuPatchCallback, removeContextMenuPatch } from \"@api/ContextMenu\";\nimport { Flex } from \"@components/Flex\";\nimport { OpenExternalIcon } from \"@components/Icons\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\nimport { Menu } from \"@webpack/common\";\n\nconst Engines = {\n Google: \"https://lens.google.com/uploadbyurl?url=\",\n Yandex: \"https://yandex.com/images/search?rpt=imageview&url=\",\n SauceNAO: \"https://saucenao.com/search.php?url=\",\n IQDB: \"https://iqdb.org/?url=\",\n TinEye: \"https://www.tineye.com/search?url=\",\n ImgOps: \"https://imgops.com/start?url=\"\n} as const;\n\nfunction search(src: string, engine: string) {\n open(engine + encodeURIComponent(src), \"_blank\");\n}\n\nfunction makeSearchItem(src: string) {\n return (\n <Menu.MenuItem\n label=\"Search Image\"\n key=\"search-image\"\n id=\"search-image\"\n >\n {Object.keys(Engines).map((engine, i) => {\n const key = \"search-image-\" + engine;\n return (\n <Menu.MenuItem\n key={key}\n id={key}\n label={\n <Flex style={{ alignItems: \"center\", gap: \"0.5em\" }}>\n <img\n style={{\n borderRadius: i >= 3 // Do not round Google, Yandex & SauceNAO\n ? \"50%\"\n : void 0\n }}\n aria-hidden=\"true\"\n height={16}\n width={16}\n src={new URL(\"/favicon.ico\", Engines[engine]).toString().replace(\"lens.\", \"\")}\n />\n {engine}\n </Flex>\n }\n action={() => search(src, Engines[engine])}\n />\n );\n })}\n <Menu.MenuItem\n key=\"search-image-all\"\n id=\"search-image-all\"\n label={\n <Flex style={{ alignItems: \"center\", gap: \"0.5em\" }}>\n <OpenExternalIcon height={16} width={16} />\n All\n </Flex>\n }\n action={() => Object.values(Engines).forEach(e => search(src, e))}\n />\n </Menu.MenuItem>\n );\n}\n\nconst messageContextMenuPatch: NavContextMenuPatchCallback = (children, props) => () => {\n if (props?.reverseImageSearchType !== \"img\") return;\n\n const src = props.itemHref ?? props.itemSrc;\n\n const group = findGroupChildrenByChildId(\"copy-link\", children);\n group?.push(makeSearchItem(src));\n};\n\nconst imageContextMenuPatch: NavContextMenuPatchCallback = (children, props) => () => {\n if (!props?.src) return;\n\n const group = findGroupChildrenByChildId(\"copy-native-link\", children) ?? children;\n group.push(makeSearchItem(props.src));\n};\n\nexport default definePlugin({\n name: \"ReverseImageSearch\",\n description: \"Adds ImageSearch to image context menus\",\n authors: [Devs.Ven, Devs.Nuckyz],\n tags: [\"ImageUtilities\"],\n\n patches: [\n {\n find: \".Messages.MESSAGE_ACTIONS_MENU_LABEL\",\n replacement: {\n match: /favoriteableType:\\i,(?<=(\\i)\\.getAttribute\\(\"data-type\"\\).+?)/,\n replace: (m, target) => `${m}reverseImageSearchType:${target}.getAttribute(\"data-role\"),`\n }\n }\n ],\n\n start() {\n addContextMenuPatch(\"message\", messageContextMenuPatch);\n addContextMenuPatch(\"image-context\", imageContextMenuPatch);\n },\n\n stop() {\n removeContextMenuPatch(\"message\", messageContextMenuPatch);\n removeContextMenuPatch(\"image-context\", imageContextMenuPatch);\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { definePluginSettings } from \"@api/Settings\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { ChannelStore, GuildMemberStore, GuildStore } from \"@webpack/common\";\n\nconst settings = definePluginSettings({\n chatMentions: {\n type: OptionType.BOOLEAN,\n default: true,\n description: \"Show role colors in chat mentions (including in the message box)\",\n restartNeeded: true\n },\n memberList: {\n type: OptionType.BOOLEAN,\n default: true,\n description: \"Show role colors in member list role headers\",\n restartNeeded: true\n },\n voiceUsers: {\n type: OptionType.BOOLEAN,\n default: true,\n description: \"Show role colors in the voice chat user list\",\n restartNeeded: true\n }\n});\n\nexport default definePlugin({\n name: \"RoleColorEverywhere\",\n authors: [Devs.KingFish, Devs.lewisakura, Devs.AutumnVN],\n description: \"Adds the top role color anywhere possible\",\n patches: [\n // Chat Mentions\n {\n find: \"CLYDE_AI_MENTION_COLOR:null,\",\n replacement: [\n {\n match: /user:(\\i),channel:(\\i).{0,400}?\"@\"\\.concat\\(.+?\\)/,\n replace: \"$&,color:$self.getUserColor($1?.id,{channelId:$2?.id})\"\n }\n ],\n predicate: () => settings.store.chatMentions,\n },\n // Slate\n {\n find: \".userTooltip,children\",\n replacement: [\n {\n match: /let\\{id:(\\i),guildId:(\\i)[^}]*\\}.*?\\.default,{(?=children)/,\n replace: \"$&color:$self.getUserColor($1,{guildId:$2}),\"\n }\n ],\n predicate: () => settings.store.chatMentions,\n },\n {\n find: 'tutorialId:\"whos-online',\n replacement: [\n {\n match: /\\i.roleIcon,\\.\\.\\.\\i/,\n replace: \"$&,color:$self.roleGroupColor(arguments[0])\"\n },\n {\n match: /null,\\i,\" \u2014 \",\\i\\]/,\n replace: \"null,$self.roleGroupColor(arguments[0])]\"\n },\n ],\n predicate: () => settings.store.memberList,\n },\n {\n find: \"renderPrioritySpeaker\",\n replacement: [\n {\n match: /renderName\\(\\).{0,100}speaking:.{50,100}jsx.{5,10}{/,\n replace: \"$&...$self.getVoiceProps(this.props),\"\n }\n ],\n predicate: () => settings.store.voiceUsers,\n }\n ],\n settings,\n\n getColor(userId: string, { channelId, guildId }: { channelId?: string; guildId?: string; }) {\n if (!(guildId ??= ChannelStore.getChannel(channelId!)?.guild_id)) return null;\n return GuildMemberStore.getMember(guildId, userId)?.colorString ?? null;\n },\n\n getUserColor(userId: string, ids: { channelId?: string; guildId?: string; }) {\n const colorString = this.getColor(userId, ids);\n return colorString && parseInt(colorString.slice(1), 16);\n },\n\n roleGroupColor({ id, count, title, guildId, label }: { id: string; count: number; title: string; guildId: string; label: string; }) {\n const guild = GuildStore.getGuild(guildId);\n const role = guild?.roles[id];\n\n return (\n <span style={{\n color: role?.colorString,\n fontWeight: \"unset\",\n letterSpacing: \".05em\"\n }}>\n {title ?? label} &mdash; {count}\n </span>\n );\n },\n\n getVoiceProps({ user: { id: userId }, guildId }: { user: { id: string; }; guildId: string; }) {\n return {\n style: {\n color: this.getColor(userId, { guildId })\n }\n };\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { addContextMenuPatch, findGroupChildrenByChildId, NavContextMenuPatchCallback, removeContextMenuPatch } from \"@api/ContextMenu\";\nimport { ReplyIcon } from \"@components/Icons\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\nimport { findByPropsLazy } from \"@webpack\";\nimport { ChannelStore, i18n, Menu, PermissionsBits, PermissionStore, SelectedChannelStore } from \"@webpack/common\";\nimport { Message } from \"discord-types/general\";\n\n\nconst messageUtils = findByPropsLazy(\"replyToMessage\");\n\nconst messageContextMenuPatch: NavContextMenuPatchCallback = (children, { message }: { message: Message; }) => () => {\n // make sure the message is in the selected channel\n if (SelectedChannelStore.getChannelId() !== message.channel_id) return;\n const channel = ChannelStore.getChannel(message?.channel_id);\n if (!channel) return;\n if (channel.guild_id && !PermissionStore.can(PermissionsBits.SEND_MESSAGES, channel)) return;\n\n // dms and group chats\n const dmGroup = findGroupChildrenByChildId(\"pin\", children);\n if (dmGroup && !dmGroup.some(child => child?.props?.id === \"reply\")) {\n const pinIndex = dmGroup.findIndex(c => c?.props.id === \"pin\");\n return dmGroup.splice(pinIndex + 1, 0, (\n <Menu.MenuItem\n id=\"reply\"\n label={i18n.Messages.MESSAGE_ACTION_REPLY}\n icon={ReplyIcon}\n action={(e: React.MouseEvent) => messageUtils.replyToMessage(channel, message, e)}\n />\n ));\n }\n\n // servers\n const serverGroup = findGroupChildrenByChildId(\"mark-unread\", children);\n if (serverGroup && !serverGroup.some(child => child?.props?.id === \"reply\")) {\n return serverGroup.unshift((\n <Menu.MenuItem\n id=\"reply\"\n label={i18n.Messages.MESSAGE_ACTION_REPLY}\n icon={ReplyIcon}\n action={(e: React.MouseEvent) => messageUtils.replyToMessage(channel, message, e)}\n />\n ));\n }\n};\n\n\nexport default definePlugin({\n name: \"SearchReply\",\n description: \"Adds a reply button to search results\",\n authors: [Devs.Aria],\n\n start() {\n addContextMenuPatch(\"message\", messageContextMenuPatch);\n },\n\n stop() {\n removeContextMenuPatch(\"message\", messageContextMenuPatch);\n }\n});\n", "/*\n * Vencord, a Discord client mod\n * Copyright (c) 2023 Vendicated and contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\n\n// NOTE - Ultimately should probably be turned into a ringtone picker plugin\nexport default definePlugin({\n name: \"SecretRingToneEnabler\",\n description: \"Always play the secret version of the discord ringtone (except during special ringtone events)\",\n authors: [Devs.AndrewDLO, Devs.FieryFlames],\n patches: [\n {\n find: \"call_ringing_beat\\\"\",\n replacement: {\n match: /500===\\i\\.random\\(1,1e3\\)/,\n replace: \"true\"\n }\n },\n ],\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport \"./styles.css\";\n\nimport { addPreSendListener, removePreSendListener } from \"@api/MessageEvents\";\nimport { definePluginSettings } from \"@api/Settings\";\nimport { classNameFactory } from \"@api/Styles\";\nimport { Devs } from \"@utils/constants\";\nimport { getTheme, insertTextIntoChatInputBox, Theme } from \"@utils/discord\";\nimport { Margins } from \"@utils/margins\";\nimport { closeModal, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, openModal } from \"@utils/modal\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { Button, ButtonLooks, ButtonWrapperClasses, Forms, Parser, Select, Tooltip, useMemo, useState } from \"@webpack/common\";\n\nconst settings = definePluginSettings({\n replaceMessageContents: {\n description: \"Replace timestamps in message contents\",\n type: OptionType.BOOLEAN,\n default: true,\n },\n});\n\nfunction parseTime(time: string) {\n const cleanTime = time.slice(1, -1).replace(/(\\d)(AM|PM)$/i, \"$1 $2\");\n\n let ms = new Date(`${new Date().toDateString()} ${cleanTime}`).getTime() / 1000;\n if (isNaN(ms)) return time;\n\n // add 24h if time is in the past\n if (Date.now() / 1000 > ms) ms += 86400;\n\n return `<t:${Math.round(ms)}:t>`;\n}\n\nconst Formats = [\"\", \"t\", \"T\", \"d\", \"D\", \"f\", \"F\", \"R\"] as const;\ntype Format = typeof Formats[number];\n\nconst cl = classNameFactory(\"vc-st-\");\n\nfunction PickerModal({ rootProps, close }: { rootProps: ModalProps, close(): void; }) {\n const [value, setValue] = useState<string>();\n const [format, setFormat] = useState<Format>(\"\");\n const time = Math.round((new Date(value!).getTime() || Date.now()) / 1000);\n\n const formatTimestamp = (time: number, format: Format) => `<t:${time}${format && `:${format}`}>`;\n\n const [formatted, rendered] = useMemo(() => {\n const formatted = formatTimestamp(time, format);\n return [formatted, Parser.parse(formatted)];\n }, [time, format]);\n\n return (\n <ModalRoot {...rootProps}>\n <ModalHeader className={cl(\"modal-header\")}>\n <Forms.FormTitle tag=\"h2\">\n Timestamp Picker\n </Forms.FormTitle>\n\n <ModalCloseButton onClick={close} />\n </ModalHeader>\n\n <ModalContent className={cl(\"modal-content\")}>\n <input\n type=\"datetime-local\"\n value={value}\n onChange={e => setValue(e.currentTarget.value)}\n style={{\n colorScheme: getTheme() === Theme.Light ? \"light\" : \"dark\",\n }}\n />\n\n <Forms.FormTitle>Timestamp Format</Forms.FormTitle>\n <Select\n options={\n Formats.map(m => ({\n label: m,\n value: m\n }))\n }\n isSelected={v => v === format}\n select={v => setFormat(v)}\n serialize={v => v}\n renderOptionLabel={o => (\n <div className={cl(\"format-label\")}>\n {Parser.parse(formatTimestamp(time, o.value))}\n </div>\n )}\n renderOptionValue={() => rendered}\n />\n\n <Forms.FormTitle className={Margins.bottom8}>Preview</Forms.FormTitle>\n <Forms.FormText className={cl(\"preview-text\")}>\n {rendered} ({formatted})\n </Forms.FormText>\n </ModalContent>\n\n <ModalFooter>\n <Button\n onClick={() => {\n insertTextIntoChatInputBox(formatted + \" \");\n close();\n }}\n >Insert</Button>\n </ModalFooter>\n </ModalRoot>\n );\n}\n\nexport default definePlugin({\n name: \"SendTimestamps\",\n description: \"Send timestamps easily via chat box button & text shortcuts. Read the extended description!\",\n authors: [Devs.Ven, Devs.Tyler, Devs.Grzesiek11],\n dependencies: [\"MessageEventsAPI\"],\n\n settings: settings,\n\n patches: [\n {\n find: \"ChannelTextAreaButtons\",\n replacement: {\n match: /(\\i)\\.push.{1,30}disabled:(\\i),.{1,20}\\},\"gift\"\\)\\)/,\n replace: \"$&,(()=>{try{$2||$1.push($self.chatBarIcon(arguments[0]))}catch{}})()\",\n }\n },\n ],\n\n start() {\n this.listener = addPreSendListener((_, msg) => {\n if (settings.store.replaceMessageContents) {\n msg.content = msg.content.replace(/`\\d{1,2}:\\d{2} ?(?:AM|PM)?`/gi, parseTime);\n }\n });\n },\n\n stop() {\n removePreSendListener(this.listener);\n },\n\n chatBarIcon(chatBoxProps: { type: { analyticsName: string; }; }) {\n if (chatBoxProps.type.analyticsName !== \"normal\") return null;\n\n return (\n <Tooltip text=\"Insert Timestamp\">\n {({ onMouseEnter, onMouseLeave }) => (\n <div style={{ display: \"flex\" }}>\n <Button\n aria-haspopup=\"dialog\"\n aria-label=\"Insert Timestamp\"\n size=\"\"\n look={ButtonLooks.BLANK}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n innerClassName={ButtonWrapperClasses.button}\n onClick={() => {\n const key = openModal(props => (\n <PickerModal\n rootProps={props}\n close={() => closeModal(key)}\n />\n ));\n }}\n className={cl(\"button\")}\n >\n <div className={ButtonWrapperClasses.buttonWrapper}>\n <svg\n aria-hidden=\"true\"\n role=\"img\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n >\n <g fill=\"none\" fill-rule=\"evenodd\">\n <path fill=\"currentColor\" d=\"M19 3h-1V1h-2v2H8V1H6v2H5c-1.11 0-1.99.9-1.99 2L3 19a2 2 0 0 0 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V8h14v11zM7 10h5v5H7v-5z\" />\n <rect width=\"24\" height=\"24\" />\n </g>\n </svg>\n </div>\n </Button>\n </div>\n )\n }\n </Tooltip >\n );\n },\n\n settingsAboutComponent() {\n const samples = [\n \"12:00\",\n \"3:51\",\n \"17:59\",\n \"24:00\",\n \"12:00 AM\",\n \"0:13PM\"\n ].map(s => `\\`${s}\\``);\n\n return (\n <>\n <Forms.FormText>\n To quickly send send time only timestamps, include timestamps formatted as `HH:MM` (including the backticks!) in your message\n </Forms.FormText>\n <Forms.FormText>\n See below for examples.\n If you need anything more specific, use the Date button in the chat bar!\n </Forms.FormText>\n <Forms.FormText>\n Examples:\n <ul>\n {samples.map(s => (\n <li key={s}>\n <code>{s}</code> {\"->\"} {Parser.parse(parseTime(s))}\n </li>\n ))}\n </ul>\n </Forms.FormText>\n </>\n );\n },\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Sofia Lima\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { addServerListElement, removeServerListElement, ServerListRenderPosition } from \"@api/ServerList\";\nimport { Settings } from \"@api/Settings\";\nimport ErrorBoundary from \"@components/ErrorBoundary\";\nimport { Devs } from \"@utils/constants\";\nimport { useForceUpdater } from \"@utils/react\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { GuildStore, PresenceStore, RelationshipStore } from \"@webpack/common\";\n\nconst enum IndicatorType {\n SERVER = 1 << 0,\n FRIEND = 1 << 1,\n BOTH = SERVER | FRIEND,\n}\n\nlet onlineFriends = 0;\nlet guildCount = 0;\nlet forceUpdateFriendCount: () => void;\nlet forceUpdateGuildCount: () => void;\n\nfunction FriendsIndicator() {\n forceUpdateFriendCount = useForceUpdater();\n\n return (\n <span id=\"vc-friendcount\" style={{\n display: \"inline-block\",\n width: \"100%\",\n fontSize: \"12px\",\n fontWeight: \"600\",\n color: \"var(--header-secondary)\",\n textTransform: \"uppercase\",\n textAlign: \"center\",\n }}>\n {onlineFriends} online\n </span>\n );\n}\n\nfunction ServersIndicator() {\n forceUpdateGuildCount = useForceUpdater();\n\n return (\n <span id=\"vc-guildcount\" style={{\n display: \"inline-block\",\n width: \"100%\",\n fontSize: \"12px\",\n fontWeight: \"600\",\n color: \"var(--header-secondary)\",\n textTransform: \"uppercase\",\n textAlign: \"center\",\n }}>\n {guildCount} servers\n </span>\n );\n}\n\nfunction handlePresenceUpdate() {\n onlineFriends = 0;\n const relations = RelationshipStore.getRelationships();\n for (const id of Object.keys(relations)) {\n const type = relations[id];\n // FRIEND relationship type\n if (type === 1 && PresenceStore.getStatus(id) !== \"offline\") {\n onlineFriends += 1;\n }\n }\n forceUpdateFriendCount?.();\n}\n\nfunction handleGuildUpdate() {\n guildCount = GuildStore.getGuildCount();\n forceUpdateGuildCount?.();\n}\n\nexport default definePlugin({\n name: \"ServerListIndicators\",\n description: \"Add online friend count or server count in the server list\",\n authors: [Devs.dzshn],\n dependencies: [\"ServerListAPI\"],\n\n options: {\n mode: {\n description: \"mode\",\n type: OptionType.SELECT,\n options: [\n { label: \"Only online friend count\", value: IndicatorType.FRIEND, default: true },\n { label: \"Only server count\", value: IndicatorType.SERVER },\n { label: \"Both server and online friend counts\", value: IndicatorType.BOTH },\n ]\n }\n },\n\n renderIndicator: () => {\n const { mode } = Settings.plugins.ServerListIndicators;\n return <ErrorBoundary noop>\n <div style={{ marginBottom: \"4px\" }}>\n {!!(mode & IndicatorType.FRIEND) && <FriendsIndicator />}\n {!!(mode & IndicatorType.SERVER) && <ServersIndicator />}\n </div>\n </ErrorBoundary>;\n },\n\n flux: {\n PRESENCE_UPDATES: handlePresenceUpdate,\n GUILD_CREATE: handleGuildUpdate,\n GUILD_DELETE: handleGuildUpdate,\n },\n\n\n start() {\n addServerListElement(ServerListRenderPosition.Above, this.renderIndicator);\n\n handlePresenceUpdate();\n handleGuildUpdate();\n },\n\n stop() {\n removeServerListElement(ServerListRenderPosition.Above, this.renderIndicator);\n }\n});\n", "/*\n * Vencord, a Discord client mod\n * Copyright (c) 2023 Vendicated and contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport \"./styles.css\";\n\nimport { classNameFactory } from \"@api/Styles\";\nimport { openImageModal, openUserProfile } from \"@utils/discord\";\nimport { classes } from \"@utils/misc\";\nimport { ModalRoot, ModalSize, openModal } from \"@utils/modal\";\nimport { useAwaiter } from \"@utils/react\";\nimport { findByPropsLazy, findExportedComponentLazy } from \"@webpack\";\nimport { FluxDispatcher, Forms, GuildChannelStore, GuildMemberStore, moment, Parser, PresenceStore, RelationshipStore, ScrollerThin, SnowflakeUtils, TabBar, Timestamp, useEffect, UserStore, UserUtils, useState, useStateFromStores } from \"@webpack/common\";\nimport { Guild, User } from \"discord-types/general\";\n\nconst IconUtils = findByPropsLazy(\"getGuildBannerURL\");\nconst IconClasses = findByPropsLazy(\"icon\", \"acronym\", \"childWrapper\");\nconst FriendRow = findExportedComponentLazy(\"FriendRow\");\n\nconst cl = classNameFactory(\"vc-gp-\");\n\nexport function openGuildProfileModal(guild: Guild) {\n openModal(props =>\n <ModalRoot {...props} size={ModalSize.MEDIUM}>\n <GuildProfileModal guild={guild} />\n </ModalRoot>\n );\n}\n\nconst enum Tabs {\n ServerInfo,\n Friends,\n BlockedUsers\n}\n\ninterface GuildProps {\n guild: Guild;\n}\n\ninterface RelationshipProps extends GuildProps {\n setCount(count: number): void;\n}\n\nconst fetched = {\n friends: false,\n blocked: false\n};\n\nfunction renderTimestamp(timestamp: number) {\n return (\n <Timestamp timestamp={moment(timestamp)} />\n );\n}\n\nfunction GuildProfileModal({ guild }: GuildProps) {\n const [friendCount, setFriendCount] = useState<number>();\n const [blockedCount, setBlockedCount] = useState<number>();\n\n useEffect(() => {\n fetched.friends = false;\n fetched.blocked = false;\n }, []);\n\n const [currentTab, setCurrentTab] = useState(Tabs.ServerInfo);\n\n const bannerUrl = guild.banner && IconUtils.getGuildBannerURL({\n id: guild.id,\n banner: guild.banner\n }, true).replace(/\\?size=\\d+$/, \"?size=1024\");\n\n const iconUrl = guild.icon && IconUtils.getGuildIconURL({\n id: guild.id,\n icon: guild.icon,\n canAnimate: true,\n size: 512\n });\n\n return (\n <div className={cl(\"root\")}>\n {bannerUrl && currentTab === Tabs.ServerInfo && (\n <img\n className={cl(\"banner\")}\n src={bannerUrl}\n alt=\"\"\n onClick={() => openImageModal(bannerUrl)}\n />\n )}\n\n <div className={cl(\"header\")}>\n {guild.icon\n ? <img\n src={iconUrl}\n alt=\"\"\n onClick={() => openImageModal(iconUrl)}\n />\n : <div aria-hidden className={classes(IconClasses.childWrapper, IconClasses.acronym)}>{guild.acronym}</div>\n }\n\n <div className={cl(\"name-and-description\")}>\n <Forms.FormTitle tag=\"h5\" className={cl(\"name\")}>{guild.name}</Forms.FormTitle>\n {guild.description && <Forms.FormText>{guild.description}</Forms.FormText>}\n </div>\n </div>\n\n <TabBar\n type=\"top\"\n look=\"brand\"\n className={cl(\"tab-bar\")}\n selectedItem={currentTab}\n onItemSelect={setCurrentTab}\n >\n <TabBar.Item\n className={cl(\"tab\", { selected: currentTab === Tabs.ServerInfo })}\n id={Tabs.ServerInfo}\n >\n Server Info\n </TabBar.Item>\n <TabBar.Item\n className={cl(\"tab\", { selected: currentTab === Tabs.Friends })}\n id={Tabs.Friends}\n >\n Friends{friendCount !== undefined ? ` (${friendCount})` : \"\"}\n </TabBar.Item>\n <TabBar.Item\n className={cl(\"tab\", { selected: currentTab === Tabs.BlockedUsers })}\n id={Tabs.BlockedUsers}\n >\n Blocked Users{blockedCount !== undefined ? ` (${blockedCount})` : \"\"}\n </TabBar.Item>\n </TabBar>\n\n <div className={cl(\"tab-content\")}>\n {currentTab === Tabs.ServerInfo && <ServerInfoTab guild={guild} />}\n {currentTab === Tabs.Friends && <FriendsTab guild={guild} setCount={setFriendCount} />}\n {currentTab === Tabs.BlockedUsers && <BlockedUsersTab guild={guild} setCount={setBlockedCount} />}\n </div>\n </div>\n );\n}\n\n\nfunction Owner(guildId: string, owner: User) {\n const guildAvatar = GuildMemberStore.getMember(guildId, owner.id)?.avatar;\n const ownerAvatarUrl =\n guildAvatar\n ? IconUtils.getGuildMemberAvatarURLSimple({\n userId: owner!.id,\n avatar: guildAvatar,\n guildId,\n canAnimate: true\n }, true)\n : IconUtils.getUserAvatarURL(owner, true);\n\n return (\n <div className={cl(\"owner\")}>\n <img src={ownerAvatarUrl} alt=\"\" onClick={() => openImageModal(ownerAvatarUrl)} />\n {Parser.parse(`<@${owner.id}>`)}\n </div>\n );\n}\n\nfunction ServerInfoTab({ guild }: GuildProps) {\n const [owner] = useAwaiter(() => UserUtils.getUser(guild.ownerId), {\n deps: [guild.ownerId],\n fallbackValue: null\n });\n\n const Fields = {\n \"Server Owner\": owner ? Owner(guild.id, owner) : \"Loading...\",\n \"Created At\": renderTimestamp(SnowflakeUtils.extractTimestamp(guild.id)),\n \"Joined At\": guild.joinedAt ? renderTimestamp(guild.joinedAt.getTime()) : \"-\", // Not available in lurked guild\n \"Vanity Link\": guild.vanityURLCode ? (<a>{`discord.gg/${guild.vanityURLCode}`}</a>) : \"-\", // Making the anchor href valid would cause Discord to reload\n \"Preferred Locale\": guild.preferredLocale || \"-\",\n \"Verification Level\": [\"None\", \"Low\", \"Medium\", \"High\", \"Highest\"][guild.verificationLevel] || \"?\",\n \"Nitro Boosts\": `${guild.premiumSubscriberCount ?? 0} (Level ${guild.premiumTier ?? 0})`,\n \"Channels\": GuildChannelStore.getChannels(guild.id)?.count - 1 || \"?\", // - null category\n \"Roles\": Object.keys(guild.roles).length - 1, // - @everyone\n };\n\n return (\n <div className={cl(\"info\")}>\n {Object.entries(Fields).map(([name, node]) =>\n <div className={cl(\"server-info-pair\")} key={name}>\n <Forms.FormTitle tag=\"h5\">{name}</Forms.FormTitle>\n {typeof node === \"string\" ? <span>{node}</span> : node}\n </div>\n )}\n </div>\n );\n}\n\nfunction FriendsTab({ guild, setCount }: RelationshipProps) {\n return UserList(\"friends\", guild, RelationshipStore.getFriendIDs(), setCount);\n}\n\nfunction BlockedUsersTab({ guild, setCount }: RelationshipProps) {\n const blockedIds = Object.keys(RelationshipStore.getRelationships()).filter(id => RelationshipStore.isBlocked(id));\n return UserList(\"blocked\", guild, blockedIds, setCount);\n}\n\nfunction UserList(type: \"friends\" | \"blocked\", guild: Guild, ids: string[], setCount: (count: number) => void) {\n const missing = [] as string[];\n const members = [] as string[];\n\n for (const id of ids) {\n if (GuildMemberStore.isMember(guild.id, id))\n members.push(id);\n else\n missing.push(id);\n }\n\n // Used for side effects (rerender on member request success)\n useStateFromStores(\n [GuildMemberStore],\n () => GuildMemberStore.getMemberIds(guild.id),\n null,\n (old, curr) => old.length === curr.length\n );\n\n useEffect(() => {\n if (!fetched[type] && missing.length) {\n fetched[type] = true;\n FluxDispatcher.dispatch({\n type: \"GUILD_MEMBERS_REQUEST\",\n guildIds: [guild.id],\n userIds: missing\n });\n }\n }, []);\n\n useEffect(() => setCount(members.length), [members.length]);\n\n return (\n <ScrollerThin fade className={cl(\"scroller\")}>\n {members.map(id =>\n <FriendRow\n user={UserStore.getUser(id)}\n status={PresenceStore.getStatus(id) || \"offline\"}\n onSelect={() => openUserProfile(id)}\n onContextMenu={() => { }}\n />\n )}\n </ScrollerThin>\n );\n}\n", "/*\n * Vencord, a Discord client mod\n * Copyright (c) 2023 Vendicated and contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport { addContextMenuPatch, findGroupChildrenByChildId, NavContextMenuPatchCallback, removeContextMenuPatch } from \"@api/ContextMenu\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\nimport { Menu } from \"@webpack/common\";\nimport { Guild } from \"discord-types/general\";\n\nimport { openGuildProfileModal } from \"./GuildProfileModal\";\n\nconst Patch: NavContextMenuPatchCallback = (children, { guild }: { guild: Guild; }) => () => {\n const group = findGroupChildrenByChildId(\"privacy\", children);\n\n group?.push(\n <Menu.MenuItem\n id=\"vc-server-profile\"\n label=\"Server Info\"\n action={() => openGuildProfileModal(guild)}\n />\n );\n};\n\nexport default definePlugin({\n name: \"ServerProfile\",\n description: \"Allows you to view info about a server by right clicking it in the server list\",\n authors: [Devs.Ven, Devs.Nuckyz],\n tags: [\"guild\", \"info\"],\n\n start() {\n addContextMenuPatch([\"guild-context\", \"guild-header-popout\"], Patch);\n },\n\n stop() {\n removeContextMenuPatch([\"guild-context\", \"guild-header-popout\"], Patch);\n }\n});\n", "export default \"/* eslint-disable simple-header/header */\\nimport React from \\\"react\\\";\\n\\nconst handleClick = async () =>\\n console.log((await import(\\\"@webpack/common\\\")).Clipboard.copy(\\\"\\\\u200b\\\"));\\n\\nexport const Example: React.FC<{\\n real: boolean,\\n shigged?: number,\\n}> = ({ real, shigged }) => <>\\n <p>{`Shigg${real ? `ies${shigged === 0x1B ? \\\"t\\\" : \\\"\\\"}` : \\\"y\\\"}`}</p>\\n <button onClick={handleClick}>Click Me</button>\\n</>;\\n\"", "'use strict';\n\nvar has = Object.prototype.hasOwnProperty\n , prefix = '~';\n\n/**\n * Constructor to create a storage for our `EE` objects.\n * An `Events` instance is a plain object whose properties are event names.\n *\n * @constructor\n * @private\n */\nfunction Events() {}\n\n//\n// We try to not inherit from `Object.prototype`. In some engines creating an\n// instance in this way is faster than calling `Object.create(null)` directly.\n// If `Object.create(null)` is not supported we prefix the event names with a\n// character to make sure that the built-in object properties are not\n// overridden or used as an attack vector.\n//\nif (Object.create) {\n Events.prototype = Object.create(null);\n\n //\n // This hack is needed because the `__proto__` property is still inherited in\n // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.\n //\n if (!new Events().__proto__) prefix = false;\n}\n\n/**\n * Representation of a single event listener.\n *\n * @param {Function} fn The listener function.\n * @param {*} context The context to invoke the listener with.\n * @param {Boolean} [once=false] Specify if the listener is a one-time listener.\n * @constructor\n * @private\n */\nfunction EE(fn, context, once) {\n this.fn = fn;\n this.context = context;\n this.once = once || false;\n}\n\n/**\n * Add a listener for a given event.\n *\n * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} context The context to invoke the listener with.\n * @param {Boolean} once Specify if the listener is a one-time listener.\n * @returns {EventEmitter}\n * @private\n */\nfunction addListener(emitter, event, fn, context, once) {\n if (typeof fn !== 'function') {\n throw new TypeError('The listener must be a function');\n }\n\n var listener = new EE(fn, context || emitter, once)\n , evt = prefix ? prefix + event : event;\n\n if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;\n else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);\n else emitter._events[evt] = [emitter._events[evt], listener];\n\n return emitter;\n}\n\n/**\n * Clear event by name.\n *\n * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.\n * @param {(String|Symbol)} evt The Event name.\n * @private\n */\nfunction clearEvent(emitter, evt) {\n if (--emitter._eventsCount === 0) emitter._events = new Events();\n else delete emitter._events[evt];\n}\n\n/**\n * Minimal `EventEmitter` interface that is molded against the Node.js\n * `EventEmitter` interface.\n *\n * @constructor\n * @public\n */\nfunction EventEmitter() {\n this._events = new Events();\n this._eventsCount = 0;\n}\n\n/**\n * Return an array listing the events for which the emitter has registered\n * listeners.\n *\n * @returns {Array}\n * @public\n */\nEventEmitter.prototype.eventNames = function eventNames() {\n var names = []\n , events\n , name;\n\n if (this._eventsCount === 0) return names;\n\n for (name in (events = this._events)) {\n if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);\n }\n\n if (Object.getOwnPropertySymbols) {\n return names.concat(Object.getOwnPropertySymbols(events));\n }\n\n return names;\n};\n\n/**\n * Return the listeners registered for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Array} The registered listeners.\n * @public\n */\nEventEmitter.prototype.listeners = function listeners(event) {\n var evt = prefix ? prefix + event : event\n , handlers = this._events[evt];\n\n if (!handlers) return [];\n if (handlers.fn) return [handlers.fn];\n\n for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {\n ee[i] = handlers[i].fn;\n }\n\n return ee;\n};\n\n/**\n * Return the number of listeners listening to a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Number} The number of listeners.\n * @public\n */\nEventEmitter.prototype.listenerCount = function listenerCount(event) {\n var evt = prefix ? prefix + event : event\n , listeners = this._events[evt];\n\n if (!listeners) return 0;\n if (listeners.fn) return 1;\n return listeners.length;\n};\n\n/**\n * Calls each of the listeners registered for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Boolean} `true` if the event had listeners, else `false`.\n * @public\n */\nEventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {\n var evt = prefix ? prefix + event : event;\n\n if (!this._events[evt]) return false;\n\n var listeners = this._events[evt]\n , len = arguments.length\n , args\n , i;\n\n if (listeners.fn) {\n if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);\n\n switch (len) {\n case 1: return listeners.fn.call(listeners.context), true;\n case 2: return listeners.fn.call(listeners.context, a1), true;\n case 3: return listeners.fn.call(listeners.context, a1, a2), true;\n case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;\n case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;\n case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;\n }\n\n for (i = 1, args = new Array(len -1); i < len; i++) {\n args[i - 1] = arguments[i];\n }\n\n listeners.fn.apply(listeners.context, args);\n } else {\n var length = listeners.length\n , j;\n\n for (i = 0; i < length; i++) {\n if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);\n\n switch (len) {\n case 1: listeners[i].fn.call(listeners[i].context); break;\n case 2: listeners[i].fn.call(listeners[i].context, a1); break;\n case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;\n case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;\n default:\n if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {\n args[j - 1] = arguments[j];\n }\n\n listeners[i].fn.apply(listeners[i].context, args);\n }\n }\n }\n\n return true;\n};\n\n/**\n * Add a listener for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} [context=this] The context to invoke the listener with.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.on = function on(event, fn, context) {\n return addListener(this, event, fn, context, false);\n};\n\n/**\n * Add a one-time listener for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} [context=this] The context to invoke the listener with.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.once = function once(event, fn, context) {\n return addListener(this, event, fn, context, true);\n};\n\n/**\n * Remove the listeners of a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn Only remove the listeners that match this function.\n * @param {*} context Only remove the listeners that have this context.\n * @param {Boolean} once Only remove one-time listeners.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {\n var evt = prefix ? prefix + event : event;\n\n if (!this._events[evt]) return this;\n if (!fn) {\n clearEvent(this, evt);\n return this;\n }\n\n var listeners = this._events[evt];\n\n if (listeners.fn) {\n if (\n listeners.fn === fn &&\n (!once || listeners.once) &&\n (!context || listeners.context === context)\n ) {\n clearEvent(this, evt);\n }\n } else {\n for (var i = 0, events = [], length = listeners.length; i < length; i++) {\n if (\n listeners[i].fn !== fn ||\n (once && !listeners[i].once) ||\n (context && listeners[i].context !== context)\n ) {\n events.push(listeners[i]);\n }\n }\n\n //\n // Reset the array, or remove it completely if we have no more listeners.\n //\n if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;\n else clearEvent(this, evt);\n }\n\n return this;\n};\n\n/**\n * Remove all listeners, or those of the specified event.\n *\n * @param {(String|Symbol)} [event] The event name.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {\n var evt;\n\n if (event) {\n evt = prefix ? prefix + event : event;\n if (this._events[evt]) clearEvent(this, evt);\n } else {\n this._events = new Events();\n this._eventsCount = 0;\n }\n\n return this;\n};\n\n//\n// Alias methods names because people roll like that.\n//\nEventEmitter.prototype.off = EventEmitter.prototype.removeListener;\nEventEmitter.prototype.addListener = EventEmitter.prototype.on;\n\n//\n// Expose the prefix.\n//\nEventEmitter.prefixed = prefix;\n\n//\n// Allow `EventEmitter` to be imported as module namespace.\n//\nEventEmitter.EventEmitter = EventEmitter;\n\n//\n// Expose the module.\n//\nif ('undefined' !== typeof module) {\n module.exports = EventEmitter;\n}\n", "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.Channel = exports.ChannelPort = void 0;\nconst eventemitter3_1 = require(\"eventemitter3\");\nconst ipcPrefix = 'vapIpc';\nconst kEdgeCreate = Symbol.for('vapIpc.edgeCreate');\n/** A port essentially a broadcast network for pipes,\n * meaning that emissions from one pipe are sent to all other pipes.\n */\nclass ChannelPort {\n _pipes = new Map();\n _listeners = new Map();\n _createListenerMap() {\n return new Map();\n }\n _emit(sourceName, event, ...data) {\n for (const [pipeName, listenerMap] of this._listeners.entries()) {\n if (pipeName === sourceName)\n continue;\n const listener = listenerMap.get(event);\n if (listener)\n listener(...data);\n }\n }\n createPipe(name) {\n const existingPipe = this.getPipe(name);\n if (existingPipe)\n return existingPipe;\n const listenerMap = this._createListenerMap();\n this._listeners.set(name, listenerMap);\n const pipe = {\n emit: this._emit.bind(this, name),\n listen: (event, fn) => void listenerMap.set(event, fn),\n };\n this._pipes.set(name, pipe);\n return pipe;\n }\n getPipe(name) {\n return this._pipes.get(name) ?? null;\n }\n}\nexports.ChannelPort = ChannelPort;\n/** A channel is a node in a decentralized ipc network.\n * Each channel can talk to other channels through pipes,\n * and channels identify each other through handshakes.\n * The handshake will also let other channels know which channels\n * they can redirect messages to.\n * This implementation does **NOT** account for [ring topologies](https://en.wikipedia.org/wiki/Ring_network).\n **/\nclass Channel {\n id;\n // TODO: better debug logs\n /** edge id -> edge */\n _edges = new Map();\n /** nonce -> callback */\n _callbacks = new Map();\n /** message name -> caller */\n _callers = new Map();\n /** edge id -> pipe */\n _edgePipes = new Map();\n _pipes = [];\n _emitter = new eventemitter3_1.EventEmitter();\n _logger;\n _destroyed = false;\n constructor(id) {\n this.id = id;\n }\n addPipe(pipe) {\n pipe.listen(`${ipcPrefix}:handshake`, (edge) => {\n this._handleHandshake(pipe, edge);\n });\n pipe.listen(`${ipcPrefix}:message`, (message) => {\n this._handleMessage(pipe, message);\n });\n this._pipes.push(pipe);\n this._logger?.log(`Adding pipe to channel \"${this.id}\"`);\n }\n setLogger(logger) {\n this._logger = logger;\n }\n _handleHandshake(pipe, edge) {\n if (this.id === edge.id)\n return;\n // TODO: improve the way channels store edges\n this._logger?.log(`\uD83E\uDD1D \"${edge.id}\" -> \"${this.id}\" (edges: [${edge.channelIds.join(', ')}])`);\n const prevEdge = this._edges.get(edge.id);\n if (prevEdge) {\n const newEdgeIds = edge.channelIds.filter((edgeId) => !prevEdge?.channelIds.includes(edgeId));\n if (newEdgeIds.includes(this.id)) {\n newEdgeIds.splice(newEdgeIds.indexOf(this.id), 1);\n }\n if (!newEdgeIds.length)\n return;\n this._edges.set(edge.id, {\n ...edge,\n channelIds: [...prevEdge.channelIds, ...newEdgeIds],\n });\n }\n else {\n const edgeIds = [...edge.channelIds].filter((edgeId) => edgeId !== this.id);\n this._edges.set(edge.id, {\n ...edge,\n channelIds: edgeIds,\n });\n this._edgePipes.set(edge.id, pipe);\n }\n this._emitter.emit(kEdgeCreate, edge);\n this.handshakeAll();\n }\n _handleMessage(pipe, message) {\n if (message.proxiedBy === this.id)\n return;\n if (message.destination !== this.id) {\n return this._emitMessage({\n ...message,\n proxiedBy: this.id,\n });\n }\n // Event\n if (!message.nonce)\n return void this._emitter.emit(message.name, message.data);\n // Response\n const callback = this._callbacks.get(message.nonce);\n if (callback)\n return void callback(message.data);\n // Call\n const caller = this._callers.get(message.name);\n if (caller) {\n caller(message.data)\n .catch((error) => {\n console.error(error);\n return new Error(error?.message ?? `${error}`);\n })\n .then((data) => {\n this._emitMessage({\n name: message.name,\n source: this.id,\n destination: message.source,\n data,\n nonce: message.nonce,\n });\n });\n return;\n }\n }\n _emitHandshake(pipe) {\n const edge = this.getEdge();\n pipe.emit(`${ipcPrefix}:handshake`, edge);\n }\n _emitMessage(message) {\n const edgeId = this.findEdgeId(message.destination);\n if (!edgeId)\n return; // TODO: bucket edge emissions until handshake?\n const pipe = this._edgePipes.get(edgeId);\n pipe?.emit(`${ipcPrefix}:message`, message);\n }\n getEdge() {\n const edgeIds = [\n ...this._edges.keys(),\n ...[...this._edges.values()].map((edge) => edge.channelIds).flat(),\n ].filter((id, index, arr) => arr.indexOf(id) === index);\n return {\n id: this.id,\n channelIds: edgeIds,\n };\n }\n findEdgeId(destinaton) {\n for (const edge of this._edges.values()) {\n if (edge.id === destinaton || edge.channelIds.includes(destinaton)) {\n return edge.id;\n }\n }\n return null;\n }\n waitForEdge(destination) {\n const edgeId = this.findEdgeId(destination);\n if (edgeId)\n return Promise.resolve(edgeId);\n return new Promise((resolve) => {\n const checkEdge = (edge) => {\n if (edge.id === destination || edge.channelIds.includes(destination)) {\n this._emitter.off(kEdgeCreate, checkEdge);\n resolve(edge.id);\n }\n };\n this._emitter.on(kEdgeCreate, checkEdge);\n });\n }\n createNonce() {\n return Math.random().toString(16).slice(2);\n }\n send(messageData) {\n this._emitMessage({\n ...messageData,\n source: this.id,\n });\n }\n call(messageData, opts = {\n timeout: 10000,\n }) {\n const nonce = this.createNonce();\n const promise = new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n this._callbacks.delete(nonce);\n reject(new Error('Call timed out'));\n }, opts.timeout);\n this._callbacks.set(nonce, (data) => {\n this._callbacks.delete(nonce);\n clearTimeout(timeout);\n if (opts.signal?.aborted) {\n if (opts.signal.reason instanceof Error)\n reject(opts.signal.reason);\n }\n else {\n if (data instanceof Error)\n reject(data);\n else\n resolve(data);\n }\n });\n });\n this._emitMessage({\n ...messageData,\n source: this.id,\n nonce,\n });\n return promise;\n }\n on(name, fn) {\n this._emitter.on(name, fn);\n return this;\n }\n off(name, fn) {\n this._emitter.off(name, fn);\n return this;\n }\n once(name, fn) {\n this._emitter.once(name, fn);\n return;\n }\n onCall(name, caller) {\n this._callers.set(name, async (...data) => await caller(...data));\n }\n removeCaller() { }\n handshakeAll() {\n this._pipes.forEach((pipe) => this._emitHandshake(pipe));\n }\n destroy() {\n this._emitter.removeAllListeners();\n this._callbacks.clear();\n this._callers.clear();\n this._edgePipes.clear();\n this._pipes = [];\n this._destroyed = true;\n }\n}\nexports.Channel = Channel;\n", "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.RemoteClient = exports.RemoteHost = void 0;\n/** An RPC host, can be connected to by multiple clients */\nclass RemoteHost {\n channel;\n constructor(channel, spec) {\n this.channel = channel;\n for (const [name, fn] of Object.entries(spec)) {\n channel.onCall(name, async (input) => {\n const result = await fn(...input);\n return result;\n });\n }\n channel.handshakeAll();\n }\n}\nexports.RemoteHost = RemoteHost;\nclass RemoteClient {\n hostName;\n channel;\n constructor(hostName, channel) {\n this.hostName = hostName;\n this.channel = channel;\n }\n async connect() {\n await this.channel.waitForEdge(this.hostName);\n }\n run(name, ...output) {\n return this.channel.call({\n name,\n destination: this.hostName,\n data: output,\n });\n }\n}\nexports.RemoteClient = RemoteClient;\n", "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.WorkerClient = exports.createWorkerHost = void 0;\nconst channel_1 = require(\"./channel\");\nconst rpc_1 = require(\"./rpc\");\nconst createWorkerHost = (name, spec) => {\n const channel = new channel_1.Channel(name);\n channel.addPipe({\n emit: (event, data) => postMessage({ event, data }),\n listen: (event, callback) => addEventListener('message', ({ data }) => {\n if (data.event === event)\n callback(data.data);\n }),\n });\n return new rpc_1.RemoteHost(channel, spec);\n};\nexports.createWorkerHost = createWorkerHost;\nclass WorkerClient extends rpc_1.RemoteClient {\n workerOpts;\n worker;\n workerListeners = [];\n url;\n constructor(name, hostName, source, workerOpts = {}) {\n const channel = new channel_1.Channel(name);\n super(hostName, channel);\n this.workerOpts = workerOpts;\n if (source instanceof Blob) {\n const blob = new Blob([source], { type: 'text/javascript' });\n this.url = URL.createObjectURL(blob);\n }\n else\n this.url = source;\n }\n async init() {\n const worker = (this.worker = new Worker(this.url, this.workerOpts));\n this.channel.addPipe({\n emit: (event, data) => worker.postMessage({ event, data }),\n listen: (event, callback) => {\n const listener = (ev) => {\n const { event: evName, data } = ev.data;\n if (evName === event)\n callback(data);\n };\n this.workerListeners.push(listener);\n worker.addEventListener('message', listener);\n },\n });\n await this.connect();\n }\n destroy() {\n if (this.worker) {\n for (const listener of this.workerListeners)\n this.worker.removeEventListener('message', listener);\n this.worker.terminate();\n }\n this.channel.destroy();\n if (this.url.startsWith('blob:'))\n URL.revokeObjectURL(this.url);\n }\n}\nexports.WorkerClient = WorkerClient;\n", "\"use strict\";\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __exportStar = (this && this.__exportStar) || function(m, exports) {\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\n__exportStar(require(\"./channel\"), exports);\n__exportStar(require(\"./rpc\"), exports);\n__exportStar(require(\"./worker\"), exports);\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { React } from \"@webpack/common\";\n\ntype Shiki = typeof import(\"../api/shiki\").shiki;\ninterface ThemeState {\n id: Shiki[\"currentThemeUrl\"],\n theme: Shiki[\"currentTheme\"],\n}\n\nconst currentTheme: ThemeState = {\n id: null,\n theme: null,\n};\n\nconst themeSetters = new Set<React.Dispatch<React.SetStateAction<ThemeState>>>();\n\nexport const useTheme = (): ThemeState => {\n const [, setTheme] = React.useState<ThemeState>(currentTheme);\n\n React.useEffect(() => {\n themeSetters.add(setTheme);\n return () => void themeSetters.delete(setTheme);\n }, []);\n\n return currentTheme;\n};\n\nexport function dispatchTheme(state: ThemeState) {\n if (currentTheme.id === state.id) return;\n Object.assign(currentTheme, state);\n themeSetters.forEach(setTheme => setTheme(state));\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { ILanguageRegistration } from \"@vap/shiki\";\n\nexport const VPC_REPO = \"Vap0r1ze/vapcord\";\nexport const VPC_REPO_COMMIT = \"88a7032a59cca40da170926651b08201ea3b965a\";\nexport const vpcRepoAssets = `https://raw.githubusercontent.com/${VPC_REPO}/${VPC_REPO_COMMIT}/assets/shiki-codeblocks`;\nexport const vpcRepoGrammar = (fileName: string) => `${vpcRepoAssets}/${fileName}`;\nexport const vpcRepoLanguages = `${vpcRepoAssets}/languages.json`;\n\nexport interface Language {\n name: string;\n id: string;\n devicon?: string;\n grammarUrl: string,\n grammar?: ILanguageRegistration[\"grammar\"];\n scopeName: string;\n aliases?: string[];\n custom?: boolean;\n}\nexport interface LanguageJson {\n name: string;\n id: string;\n fileName: string;\n devicon?: string;\n scopeName: string;\n aliases?: string[];\n}\n\nexport const languages: Record<string, Language> = {};\n\nexport const loadLanguages = async () => {\n const langsJson: LanguageJson[] = await fetch(vpcRepoLanguages).then(res => res.json());\n const loadedLanguages = Object.fromEntries(\n langsJson.map(lang => [lang.id, {\n ...lang,\n grammarUrl: vpcRepoGrammar(lang.fileName),\n }])\n );\n Object.assign(languages, loadedLanguages);\n};\n\nexport const getGrammar = (lang: Language): Promise<NonNullable<ILanguageRegistration[\"grammar\"]>> => {\n if (lang.grammar) return Promise.resolve(lang.grammar);\n return fetch(lang.grammarUrl).then(res => res.json());\n};\n\nconst aliasCache = new Map<string, Language>();\nexport function resolveLang(idOrAlias: string) {\n if (Object.prototype.hasOwnProperty.call(languages, idOrAlias)) return languages[idOrAlias];\n\n const lang = Object.values(languages).find(lang => lang.aliases?.includes(idOrAlias));\n\n if (!lang) return null;\n\n aliasCache.set(idOrAlias, lang);\n return lang;\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { IShikiTheme } from \"@vap/shiki\";\n\nexport const SHIKI_REPO = \"shikijs/shiki\";\nexport const SHIKI_REPO_COMMIT = \"0b28ad8ccfbf2615f2d9d38ea8255416b8ac3043\";\nexport const shikiRepoTheme = (name: string) => `https://raw.githubusercontent.com/${SHIKI_REPO}/${SHIKI_REPO_COMMIT}/packages/shiki/themes/${name}.json`;\n\nexport const themes = {\n // Default\n DarkPlus: shikiRepoTheme(\"dark-plus\"),\n\n // Dev Choices\n MaterialCandy: \"https://raw.githubusercontent.com/millsp/material-candy/master/material-candy.json\",\n\n // More from Shiki repo\n DraculaSoft: shikiRepoTheme(\"dracula-soft\"),\n Dracula: shikiRepoTheme(\"dracula\"),\n GithubDarkDimmed: shikiRepoTheme(\"github-dark-dimmed\"),\n GithubDark: shikiRepoTheme(\"github-dark\"),\n GithubLight: shikiRepoTheme(\"github-light\"),\n LightPlus: shikiRepoTheme(\"light-plus\"),\n MaterialDarker: shikiRepoTheme(\"material-darker\"),\n MaterialDefault: shikiRepoTheme(\"material-default\"),\n MaterialLighter: shikiRepoTheme(\"material-lighter\"),\n MaterialOcean: shikiRepoTheme(\"material-ocean\"),\n MaterialPalenight: shikiRepoTheme(\"material-palenight\"),\n MinDark: shikiRepoTheme(\"min-dark\"),\n MinLight: shikiRepoTheme(\"min-light\"),\n Monokai: shikiRepoTheme(\"monokai\"),\n Nord: shikiRepoTheme(\"nord\"),\n OneDarkPro: shikiRepoTheme(\"one-dark-pro\"),\n Poimandres: shikiRepoTheme(\"poimandres\"),\n RosePineDawn: shikiRepoTheme(\"rose-pine-dawn\"),\n RosePineMoon: shikiRepoTheme(\"rose-pine-moon\"),\n RosePine: shikiRepoTheme(\"rose-pine\"),\n SlackDark: shikiRepoTheme(\"slack-dark\"),\n SlackOchin: shikiRepoTheme(\"slack-ochin\"),\n SolarizedDark: shikiRepoTheme(\"solarized-dark\"),\n SolarizedLight: shikiRepoTheme(\"solarized-light\"),\n VitesseDark: shikiRepoTheme(\"vitesse-dark\"),\n VitesseLight: shikiRepoTheme(\"vitesse-light\"),\n CssVariables: shikiRepoTheme(\"css-variables\"),\n};\n\nexport const themeCache = new Map<string, IShikiTheme>();\n\nexport const getTheme = (url: string): Promise<IShikiTheme> => {\n if (themeCache.has(url)) return Promise.resolve(themeCache.get(url)!);\n return fetch(url).then(res => res.json());\n};\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { shikiOnigasmSrc, shikiWorkerSrc } from \"@utils/dependencies\";\nimport { WorkerClient } from \"@vap/core/ipc\";\nimport type { IShikiTheme, IThemedToken } from \"@vap/shiki\";\n\nimport { dispatchTheme } from \"../hooks/useTheme\";\nimport type { ShikiSpec } from \"../types\";\nimport { getGrammar, languages, loadLanguages, resolveLang } from \"./languages\";\nimport { themes } from \"./themes\";\n\nconst themeUrls = Object.values(themes);\n\nlet resolveClient: (client: WorkerClient<ShikiSpec>) => void;\n\nexport const shiki = {\n client: null as WorkerClient<ShikiSpec> | null,\n currentTheme: null as IShikiTheme | null,\n currentThemeUrl: null as string | null,\n timeoutMs: 10000,\n languages,\n themes,\n loadedThemes: new Set<string>(),\n loadedLangs: new Set<string>(),\n clientPromise: new Promise<WorkerClient<ShikiSpec>>(resolve => resolveClient = resolve),\n\n init: async (initThemeUrl: string | undefined) => {\n /** https://stackoverflow.com/q/58098143 */\n const workerBlob = await fetch(shikiWorkerSrc).then(res => res.blob());\n\n const client = shiki.client = new WorkerClient<ShikiSpec>(\n \"shiki-client\",\n \"shiki-host\",\n workerBlob,\n { name: \"ShikiWorker\" },\n );\n await client.init();\n\n const themeUrl = initThemeUrl || themeUrls[0];\n\n await loadLanguages();\n await client.run(\"setOnigasm\", { wasm: shikiOnigasmSrc });\n await client.run(\"setHighlighter\", { theme: themeUrl, langs: [] });\n shiki.loadedThemes.add(themeUrl);\n await shiki._setTheme(themeUrl);\n resolveClient(client);\n },\n _setTheme: async (themeUrl: string) => {\n shiki.currentThemeUrl = themeUrl;\n const { themeData } = await shiki.client!.run(\"getTheme\", { theme: themeUrl });\n shiki.currentTheme = JSON.parse(themeData);\n dispatchTheme({ id: themeUrl, theme: shiki.currentTheme });\n },\n loadTheme: async (themeUrl: string) => {\n const client = await shiki.clientPromise;\n if (shiki.loadedThemes.has(themeUrl)) return;\n\n await client.run(\"loadTheme\", { theme: themeUrl });\n\n shiki.loadedThemes.add(themeUrl);\n },\n setTheme: async (themeUrl: string) => {\n await shiki.clientPromise;\n themeUrl ||= themeUrls[0];\n if (!shiki.loadedThemes.has(themeUrl)) await shiki.loadTheme(themeUrl);\n\n await shiki._setTheme(themeUrl);\n },\n loadLang: async (langId: string) => {\n const client = await shiki.clientPromise;\n const lang = resolveLang(langId);\n\n if (!lang || shiki.loadedLangs.has(lang.id)) return;\n\n await client.run(\"loadLanguage\", {\n lang: {\n ...lang,\n grammar: lang.grammar ?? await getGrammar(lang),\n }\n });\n shiki.loadedLangs.add(lang.id);\n },\n tokenizeCode: async (code: string, langId: string): Promise<IThemedToken[][]> => {\n const client = await shiki.clientPromise;\n const lang = resolveLang(langId);\n if (!lang) return [];\n\n if (!shiki.loadedLangs.has(lang.id)) await shiki.loadLang(lang.id);\n\n return await client.run(\"codeToThemedTokens\", {\n code,\n lang: langId,\n theme: shiki.currentThemeUrl ?? themeUrls[0],\n });\n },\n destroy() {\n shiki.currentTheme = null;\n shiki.currentThemeUrl = null;\n dispatchTheme({ id: null, theme: null });\n shiki.client?.destroy();\n }\n};\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\n(window.VencordStyles ??= new Map()).set(\"src/plugins/shikiCodeblocks.desktop/devicon.css\", {\n name: \"src/plugins/shikiCodeblocks.desktop/devicon.css\",\n source: \"@import url(\\\"https://cdn.jsdelivr.net/gh/devicons/devicon@v2.10.1/devicon.min.css\\\");\\n\",\n classNames: {},\n dom: null,\n});\n\nexport default \"src/plugins/shikiCodeblocks.desktop/devicon.css\";\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport type {\n ILanguageRegistration,\n IShikiTheme,\n IThemedToken,\n IThemeRegistration,\n} from \"@vap/shiki\";\n\n/** This must be atleast a subset of the `@vap/shiki-worker` spec */\nexport type ShikiSpec = {\n setOnigasm: ({ wasm }: { wasm: string; }) => Promise<void>;\n setHighlighter: ({ theme, langs }: {\n theme: IThemeRegistration | void;\n langs: ILanguageRegistration[];\n }) => Promise<void>;\n loadTheme: ({ theme }: {\n theme: string | IShikiTheme;\n }) => Promise<void>;\n getTheme: ({ theme }: { theme: string; }) => Promise<{ themeData: string; }>;\n loadLanguage: ({ lang }: { lang: ILanguageRegistration; }) => Promise<void>;\n codeToThemedTokens: ({\n code,\n lang,\n theme,\n }: {\n code: string;\n lang?: string;\n theme?: string;\n }) => Promise<IThemedToken[][]>;\n};\n\nexport const enum StyleSheets {\n Main = \"MAIN\",\n DevIcons = \"DEVICONS\",\n}\n\nexport const enum HljsSetting {\n Never = \"NEVER\",\n Secondary = \"SECONDARY\",\n Primary = \"PRIMARY\",\n Always = \"ALWAYS\",\n}\nexport const enum DeviconSetting {\n Disabled = \"DISABLED\",\n Greyscale = \"GREYSCALE\",\n Color = \"COLOR\"\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { definePluginSettings } from \"@api/Settings\";\nimport { disableStyle, enableStyle } from \"@api/Styles\";\nimport { parseUrl } from \"@utils/misc\";\nimport { wordsFromPascal, wordsToTitle } from \"@utils/text\";\nimport { OptionType } from \"@utils/types\";\n\nimport { shiki } from \"./api/shiki\";\nimport { themes } from \"./api/themes\";\nimport deviconStyle from \"./devicon.css?managed\";\nimport { DeviconSetting, HljsSetting } from \"./types\";\n\nconst themeNames = Object.keys(themes) as (keyof typeof themes)[];\n\nexport type ShikiSettings = typeof settings.store;\nexport const settings = definePluginSettings({\n theme: {\n type: OptionType.SELECT,\n description: \"Default themes\",\n options: themeNames.map(themeName => ({\n label: wordsToTitle(wordsFromPascal(themeName)),\n value: themes[themeName],\n default: themes[themeName] === themes.DarkPlus,\n })),\n onChange: shiki.setTheme,\n },\n customTheme: {\n type: OptionType.STRING,\n description: \"A link to a custom vscode theme\",\n placeholder: themes.MaterialCandy,\n onChange: value => {\n shiki.setTheme(value || settings.store.theme);\n },\n },\n tryHljs: {\n type: OptionType.SELECT,\n description: \"Use the more lightweight default Discord highlighter and theme.\",\n options: [\n {\n label: \"Never\",\n value: HljsSetting.Never,\n },\n {\n label: \"Prefer Shiki instead of Highlight.js\",\n value: HljsSetting.Secondary,\n default: true,\n },\n {\n label: \"Prefer Highlight.js instead of Shiki\",\n value: HljsSetting.Primary,\n },\n {\n label: \"Always\",\n value: HljsSetting.Always,\n },\n ],\n },\n useDevIcon: {\n type: OptionType.SELECT,\n description: \"How to show language icons on codeblocks\",\n options: [\n {\n label: \"Disabled\",\n value: DeviconSetting.Disabled,\n },\n {\n label: \"Colorless\",\n value: DeviconSetting.Greyscale,\n default: true,\n },\n {\n label: \"Colored\",\n value: DeviconSetting.Color,\n },\n ],\n onChange: (newValue: DeviconSetting) => {\n if (newValue === DeviconSetting.Disabled) disableStyle(deviconStyle);\n else enableStyle(deviconStyle);\n },\n },\n bgOpacity: {\n type: OptionType.SLIDER,\n description: \"Background opacity\",\n markers: [0, 20, 40, 60, 80, 100],\n default: 100,\n componentProps: {\n stickToMarkers: false,\n onValueRender: null, // Defaults to percentage\n },\n },\n}, {\n theme: {\n disabled() { return !!this.store.customTheme; },\n },\n customTheme: {\n isValid(value) {\n if (!value) return true;\n const url = parseUrl(value);\n if (!url) return \"Must be a valid URL\";\n\n if (!url.pathname.endsWith(\".json\")) return \"Must be a json file\";\n\n return true;\n },\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { PartialExcept } from \"@utils/types\";\nimport { React } from \"@webpack/common\";\n\nimport { shiki } from \"../api/shiki\";\nimport { settings as pluginSettings, ShikiSettings } from \"../settings\";\n\nexport function useShikiSettings<F extends keyof ShikiSettings>(settingKeys: F[], overrides?: Partial<ShikiSettings>) {\n const settings: Partial<ShikiSettings> = pluginSettings.use(settingKeys);\n const [isLoading, setLoading] = React.useState(false);\n\n const withOverrides = { ...settings, ...overrides } as PartialExcept<ShikiSettings, F>;\n const themeUrl = withOverrides.customTheme || withOverrides.theme;\n\n if (overrides) {\n const willChangeTheme = shiki.currentThemeUrl && themeUrl && themeUrl !== shiki.currentThemeUrl;\n const noOverrides = Object.keys(overrides).length === 0;\n\n if (isLoading && (!willChangeTheme || noOverrides)) setLoading(false);\n if (!isLoading && willChangeTheme) {\n setLoading(true);\n shiki.setTheme(themeUrl);\n }\n }\n\n return {\n ...withOverrides,\n isThemeLoading: themeUrl !== shiki.currentThemeUrl,\n };\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nexport function hex2Rgb(hex: string) {\n hex = hex.slice(1);\n if (hex.length < 6)\n hex = hex\n .split(\"\")\n .map(c => c + c)\n .join(\"\");\n if (hex.length === 6) hex += \"ff\";\n if (hex.length > 6) hex = hex.slice(0, 6);\n return hex\n .split(/(..)/)\n .filter(Boolean)\n .map(c => parseInt(c, 16));\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { classNameFactory } from \"@api/Styles\";\nimport { hljs } from \"@webpack/common\";\n\nimport { resolveLang } from \"../api/languages\";\nimport { HighlighterProps } from \"../components/Highlighter\";\nimport { HljsSetting } from \"../types\";\n\nexport const cl = classNameFactory(\"shiki-\");\n\nexport const shouldUseHljs = ({\n lang,\n tryHljs,\n}: {\n lang: HighlighterProps[\"lang\"],\n tryHljs: HljsSetting,\n}) => {\n const hljsLang = lang ? hljs?.getLanguage?.(lang) : null;\n const shikiLang = lang ? resolveLang(lang) : null;\n const langName = shikiLang?.name;\n\n switch (tryHljs) {\n case HljsSetting.Always:\n return true;\n case HljsSetting.Primary:\n return !!hljsLang || lang === \"\";\n case HljsSetting.Secondary:\n return !langName && !!hljsLang;\n case HljsSetting.Never:\n return false;\n default: return false;\n }\n};\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Clipboard, React } from \"@webpack/common\";\n\nexport function useCopyCooldown(cooldown: number) {\n const [copyCooldown, setCopyCooldown] = React.useState(false);\n\n function copy(text: string) {\n Clipboard.copy(text);\n setCopyCooldown(true);\n\n setTimeout(() => {\n setCopyCooldown(false);\n }, cooldown);\n }\n\n return [copyCooldown, copy] as const;\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { useCopyCooldown } from \"../hooks/useCopyCooldown\";\n\nexport interface CopyButtonProps extends React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement> {\n content: string;\n}\n\nexport function CopyButton({ content, ...props }: CopyButtonProps) {\n const [copyCooldown, copy] = useCopyCooldown(1000);\n\n return (\n <button\n {...props}\n style={{\n ...props.style,\n cursor: copyCooldown ? \"default\" : undefined,\n }}\n onClick={() => copy(content)}\n >\n {copyCooldown ? \"Copied!\" : \"Copy\"}\n </button>\n\n );\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Clipboard } from \"@webpack/common\";\n\nimport { cl } from \"../utils/misc\";\nimport { CopyButton } from \"./CopyButton\";\n\nexport interface ButtonRowProps {\n theme: import(\"./Highlighter\").ThemeBase;\n content: string;\n}\n\nexport function ButtonRow({ content, theme }: ButtonRowProps) {\n const buttons: JSX.Element[] = [];\n\n if (Clipboard.SUPPORTS_COPY) {\n buttons.push(\n <CopyButton\n content={content}\n className={cl(\"btn\")}\n style={{\n backgroundColor: theme.accentBgColor,\n color: theme.accentFgColor,\n }}\n />\n );\n }\n\n return <div className={cl(\"btns\")}>{buttons}</div>;\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport type { IThemedToken } from \"@vap/shiki\";\nimport { hljs } from \"@webpack/common\";\n\nimport { cl } from \"../utils/misc\";\nimport { ThemeBase } from \"./Highlighter\";\n\nexport interface CodeProps {\n theme: ThemeBase;\n useHljs: boolean;\n lang?: string;\n content: string;\n tokens: IThemedToken[][] | null;\n}\n\nexport const Code = ({\n theme,\n useHljs,\n lang,\n content,\n tokens,\n}: CodeProps) => {\n let lines!: JSX.Element[];\n\n if (useHljs) {\n try {\n const { value: hljsHtml } = hljs.highlight(lang!, content, true);\n lines = hljsHtml\n .split(\"\\n\")\n .map((line, i) => <span key={i} dangerouslySetInnerHTML={{ __html: line }} />);\n } catch {\n lines = content.split(\"\\n\").map(line => <span>{line}</span>);\n }\n } else {\n const renderTokens =\n tokens ??\n content\n .split(\"\\n\")\n .map(line => [{ color: theme.plainColor, content: line } as IThemedToken]);\n\n lines = renderTokens.map(line => {\n // [Cynthia] this makes it so when you highlight the codeblock\n // empty lines are also selected and copied when you Ctrl+C.\n if (line.length === 0) {\n return <span>{\"\\n\"}</span>;\n }\n\n return (\n <>\n {line.map(({ content, color, fontStyle }, i) => (\n <span\n key={i}\n style={{\n color,\n fontStyle: (fontStyle ?? 0) & 1 ? \"italic\" : undefined,\n fontWeight: (fontStyle ?? 0) & 2 ? \"bold\" : undefined,\n textDecoration: (fontStyle ?? 0) & 4 ? \"underline\" : undefined,\n }}\n >\n {content}\n </span>\n ))}\n </>\n );\n });\n }\n\n const codeTableRows = lines.map((line, i) => (\n <tr key={i}>\n <td style={{ color: theme.plainColor }}>{i + 1}</td>\n <td>{line}</td>\n </tr>\n ));\n\n return <table className={cl(\"table\")}>{...codeTableRows}</table>;\n};\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Language } from \"../api/languages\";\nimport { DeviconSetting } from \"../types\";\nimport { cl } from \"../utils/misc\";\n\nexport interface HeaderProps {\n langName?: string;\n useDevIcon: DeviconSetting;\n shikiLang: Language | null;\n}\n\nexport function Header({ langName, useDevIcon, shikiLang }: HeaderProps) {\n if (!langName) return <></>;\n\n return (\n <div className={cl(\"lang\")}>\n {useDevIcon !== DeviconSetting.Disabled && shikiLang?.devicon && (\n <i\n className={`${cl(\"devicon\")} devicon-${shikiLang.devicon}${useDevIcon === DeviconSetting.Color ? \" colored\" : \"\"}`}\n />\n )}\n {langName}\n </div>\n );\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport ErrorBoundary from \"@components/ErrorBoundary\";\nimport { useAwaiter, useIntersection } from \"@utils/react\";\nimport { hljs, React } from \"@webpack/common\";\n\nimport { resolveLang } from \"../api/languages\";\nimport { shiki } from \"../api/shiki\";\nimport { useShikiSettings } from \"../hooks/useShikiSettings\";\nimport { useTheme } from \"../hooks/useTheme\";\nimport { hex2Rgb } from \"../utils/color\";\nimport { cl, shouldUseHljs } from \"../utils/misc\";\nimport { ButtonRow } from \"./ButtonRow\";\nimport { Code } from \"./Code\";\nimport { Header } from \"./Header\";\n\nexport interface ThemeBase {\n plainColor: string;\n accentBgColor: string;\n accentFgColor: string;\n backgroundColor: string;\n}\n\nexport interface HighlighterProps {\n lang?: string;\n content: string;\n isPreview: boolean;\n tempSettings?: Record<string, any>;\n}\n\nexport const createHighlighter = (props: HighlighterProps) => (\n <pre className={cl(\"container\")}>\n <ErrorBoundary>\n <Highlighter {...props} />\n </ErrorBoundary>\n </pre>\n);\nexport const Highlighter = ({\n lang,\n content,\n isPreview,\n tempSettings,\n}: HighlighterProps) => {\n const {\n tryHljs,\n useDevIcon,\n bgOpacity,\n } = useShikiSettings([\"tryHljs\", \"useDevIcon\", \"bgOpacity\"], tempSettings);\n const { id: currentThemeId, theme: currentTheme } = useTheme();\n\n const shikiLang = lang ? resolveLang(lang) : null;\n const useHljs = shouldUseHljs({ lang, tryHljs });\n\n const [rootRef, isIntersecting] = useIntersection(true);\n\n const [tokens] = useAwaiter(async () => {\n if (!shikiLang || useHljs || !isIntersecting) return null;\n return await shiki.tokenizeCode(content, lang!);\n }, {\n fallbackValue: null,\n deps: [lang, content, currentThemeId, isIntersecting],\n });\n\n const themeBase: ThemeBase = {\n plainColor: currentTheme?.fg || \"var(--text-normal)\",\n accentBgColor:\n currentTheme?.colors?.[\"statusBar.background\"] || (useHljs ? \"#7289da\" : \"#007BC8\"),\n accentFgColor: currentTheme?.colors?.[\"statusBar.foreground\"] || \"#FFF\",\n backgroundColor:\n currentTheme?.colors?.[\"editor.background\"] || \"var(--background-secondary)\",\n };\n\n let langName;\n if (lang) langName = useHljs ? hljs?.getLanguage?.(lang)?.name : shikiLang?.name;\n\n return (\n <div\n ref={rootRef}\n className={cl(\"root\", { plain: !langName, preview: isPreview })}\n style={{\n backgroundColor: useHljs\n ? themeBase.backgroundColor\n : `rgba(${hex2Rgb(themeBase.backgroundColor)\n .concat(bgOpacity / 100)\n .join(\", \")})`,\n color: themeBase.plainColor,\n }}\n >\n <code>\n <Header\n langName={langName}\n useDevIcon={useDevIcon}\n shikiLang={shikiLang}\n />\n <Code\n theme={themeBase}\n useHljs={useHljs}\n lang={lang}\n content={content}\n tokens={tokens}\n />\n {!isPreview && <ButtonRow\n content={content}\n theme={themeBase}\n />}\n </code>\n </div>\n );\n};\n\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nconst styles = new Map<string, HTMLStyleElement>();\n\nexport function setStyle(css: string, id: string) {\n const style = document.createElement(\"style\");\n style.innerText = css;\n document.head.appendChild(style);\n styles.set(id, style);\n}\n\nexport function removeStyle(id: string) {\n styles.get(id)?.remove();\n return styles.delete(id);\n}\n\nexport const clearStyles = () => {\n styles.forEach(style => style.remove());\n styles.clear();\n};\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport \"./shiki.css\";\n\nimport { enableStyle } from \"@api/Styles\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\n\nimport previewExampleText from \"~fileContent/previewExample.tsx\";\n\nimport { shiki } from \"./api/shiki\";\nimport { createHighlighter } from \"./components/Highlighter\";\nimport deviconStyle from \"./devicon.css?managed\";\nimport { settings } from \"./settings\";\nimport { DeviconSetting } from \"./types\";\nimport { clearStyles } from \"./utils/createStyle\";\n\nexport default definePlugin({\n name: \"ShikiCodeblocks\",\n description: \"Brings vscode-style codeblocks into Discord, powered by Shiki\",\n authors: [Devs.Vap],\n patches: [\n {\n find: \"codeBlock:{react(\",\n replacement: {\n match: /codeBlock:\\{react\\((\\i),(\\i),(\\i)\\)\\{/,\n replace: \"$&return $self.renderHighlighter($1,$2,$3);\"\n }\n },\n {\n find: \".PREVIEW_NUM_LINES\",\n replacement: {\n match: /(?<=function \\i\\((\\i)\\)\\{)(?=let\\{text:\\i,language:)/,\n replace: \"return $self.renderHighlighter({lang:$1.language,content:$1.text});\"\n }\n }\n ],\n start: async () => {\n if (settings.store.useDevIcon !== DeviconSetting.Disabled)\n enableStyle(deviconStyle);\n\n await shiki.init(settings.store.customTheme || settings.store.theme);\n },\n stop: () => {\n shiki.destroy();\n clearStyles();\n },\n settingsAboutComponent: ({ tempSettings }) => createHighlighter({\n lang: \"tsx\",\n content: previewExampleText,\n isPreview: true,\n tempSettings,\n }),\n settings,\n\n // exports\n shiki,\n createHighlighter,\n renderHighlighter: ({ lang, content }: { lang: string; content: string; }) => {\n return createHighlighter({\n lang: lang?.toLowerCase(),\n content,\n isPreview: false,\n });\n },\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\n\nexport default definePlugin({\n name: \"ShowAllMessageButtons\",\n description: \"Always show all message buttons no matter if you are holding the shift key or not.\",\n authors: [Devs.Nuckyz],\n\n patches: [\n {\n find: \".Messages.MESSAGE_UTILITIES_A11Y_LABEL\",\n replacement: {\n match: /isExpanded:\\i&&(.+?),/,\n replace: \"isExpanded:$1,\"\n }\n }\n ]\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { findComponentByCodeLazy, findLazy } from \"@webpack\";\nimport { i18n, useToken } from \"@webpack/common\";\n\nconst ColorMap = findLazy(m => m.colors?.INTERACTIVE_MUTED?.css);\nconst VerifiedIconComponent = findComponentByCodeLazy(\".CONNECTIONS_ROLE_OFFICIAL_ICON_TOOLTIP\");\n\nexport function VerifiedIcon() {\n const color = useToken(ColorMap.colors.INTERACTIVE_MUTED).hex();\n const forcedIconColor = useToken(ColorMap.colors.INTERACTIVE_ACTIVE).hex();\n\n return (\n <VerifiedIconComponent\n color={color}\n forcedIconColor={forcedIconColor}\n size={16}\n tooltipText={i18n.Messages.CONNECTION_VERIFIED}\n />\n );\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport \"./styles.css\";\n\nimport { definePluginSettings } from \"@api/Settings\";\nimport ErrorBoundary from \"@components/ErrorBoundary\";\nimport { Flex } from \"@components/Flex\";\nimport { CopyIcon, LinkIcon } from \"@components/Icons\";\nimport { Devs } from \"@utils/constants\";\nimport { copyWithToast } from \"@utils/misc\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { findByCodeLazy, findByPropsLazy, findComponentByCodeLazy, findStoreLazy } from \"@webpack\";\nimport { Text, Tooltip, UserProfileStore } from \"@webpack/common\";\nimport { User } from \"discord-types/general\";\n\nimport { VerifiedIcon } from \"./VerifiedIcon\";\n\nconst Section = findComponentByCodeLazy(\".lastSection\", \"children:\");\nconst ThemeStore = findStoreLazy(\"ThemeStore\");\nconst platformHooks: { useLegacyPlatformType(platform: string): string; } = findByPropsLazy(\"useLegacyPlatformType\");\nconst platforms: { get(type: string): ConnectionPlatform; } = findByPropsLazy(\"isSupported\", \"getByUrl\");\nconst getTheme: (user: User, displayProfile: any) => any = findByCodeLazy(',\"--profile-gradient-primary-color\"');\n\nconst enum Spacing {\n COMPACT,\n COZY,\n ROOMY\n}\nconst getSpacingPx = (spacing: Spacing | undefined) => (spacing ?? Spacing.COMPACT) * 2 + 4;\n\nconst settings = definePluginSettings({\n iconSize: {\n type: OptionType.NUMBER,\n description: \"Icon size (px)\",\n default: 32\n },\n iconSpacing: {\n type: OptionType.SELECT,\n description: \"Icon margin\",\n default: Spacing.COZY,\n options: [\n { label: \"Compact\", value: Spacing.COMPACT },\n { label: \"Cozy\", value: Spacing.COZY }, // US Spelling :/\n { label: \"Roomy\", value: Spacing.ROOMY }\n ]\n }\n});\n\ninterface Connection {\n type: string;\n id: string;\n name: string;\n verified: boolean;\n}\n\ninterface ConnectionPlatform {\n getPlatformUserUrl(connection: Connection): string;\n icon: { lightSVG: string, darkSVG: string; };\n}\n\nconst profilePopoutComponent = ErrorBoundary.wrap(({ user, displayProfile }: { user: User, displayProfile; }) =>\n <ConnectionsComponent id={user.id} theme={getTheme(user, displayProfile).profileTheme} />\n);\n\nconst profilePanelComponent = ErrorBoundary.wrap(({ id }: { id: string; }) =>\n <ConnectionsComponent id={id} theme={ThemeStore.theme} />\n);\n\nfunction ConnectionsComponent({ id, theme }: { id: string, theme: string; }) {\n const profile = UserProfileStore.getUserProfile(id);\n if (!profile)\n return null;\n\n const connections: Connection[] = profile.connectedAccounts;\n if (!connections?.length)\n return null;\n\n return (\n <Section>\n <Text\n tag=\"h2\"\n variant=\"eyebrow\"\n style={{ color: \"var(--header-primary)\" }}\n >\n Connections\n </Text>\n <Flex style={{\n marginTop: \"8px\",\n gap: getSpacingPx(settings.store.iconSpacing),\n flexWrap: \"wrap\"\n }}>\n {connections.map(connection => <CompactConnectionComponent connection={connection} theme={theme} />)}\n </Flex>\n </Section>\n );\n}\n\nfunction CompactConnectionComponent({ connection, theme }: { connection: Connection, theme: string; }) {\n const platform = platforms.get(platformHooks.useLegacyPlatformType(connection.type));\n const url = platform.getPlatformUserUrl?.(connection);\n\n const img = (\n <img\n aria-label={connection.name}\n src={theme === \"light\" ? platform.icon.lightSVG : platform.icon.darkSVG}\n style={{\n width: settings.store.iconSize,\n height: settings.store.iconSize\n }}\n />\n );\n\n const TooltipIcon = url ? LinkIcon : CopyIcon;\n\n return (\n <Tooltip\n text={\n <span className=\"vc-sc-tooltip\">\n {connection.name}\n {connection.verified && <VerifiedIcon />}\n <TooltipIcon height={16} width={16} />\n </span>\n }\n key={connection.id}\n >\n {tooltipProps =>\n url\n ? <a\n {...tooltipProps}\n className=\"vc-user-connection\"\n href={url}\n target=\"_blank\"\n onClick={e => {\n if (Vencord.Plugins.isPluginEnabled(\"OpenInApp\")) {\n const OpenInApp = Vencord.Plugins.plugins.OpenInApp as any as typeof import(\"../openInApp\").default;\n // handleLink will .preventDefault() if applicable\n OpenInApp.handleLink(e.currentTarget, e);\n }\n }}\n >\n {img}\n </a>\n : <button\n {...tooltipProps}\n className=\"vc-user-connection\"\n onClick={() => copyWithToast(connection.name)}\n >\n {img}\n </button>\n\n }\n </Tooltip>\n );\n}\n\nexport default definePlugin({\n name: \"ShowConnections\",\n description: \"Show connected accounts in user popouts\",\n authors: [Devs.TheKodeToad],\n patches: [\n {\n find: \"{isUsingGuildBio:null!==(\",\n replacement: {\n match: /,theme:\\i\\}\\)(?=,.{0,150}setNote:)/,\n replace: \"$&,$self.profilePopoutComponent({ user: arguments[0].user, displayProfile: arguments[0].displayProfile })\"\n }\n },\n {\n find: \"\\\"Profile Panel: user cannot be undefined\\\"\",\n replacement: {\n // createElement(Divider, {}), createElement(NoteComponent)\n match: /\\(0,\\i\\.jsx\\)\\(\\i\\.\\i,\\{\\}\\).{0,100}setNote:(?=.+?channelId:(\\i).id)/,\n replace: \"$self.profilePanelComponent({ id: $1.recipients[0] }),$&\"\n }\n }\n ],\n settings,\n profilePopoutComponent,\n profilePanelComponent\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Settings } from \"@api/Settings\";\nimport ErrorBoundary from \"@components/ErrorBoundary\";\nimport { formatDuration } from \"@utils/text\";\nimport { findByPropsLazy, findComponentByCodeLazy, findComponentLazy } from \"@webpack\";\nimport { EmojiStore, FluxDispatcher, GuildMemberStore, GuildStore, moment, Parser, PermissionsBits, PermissionStore, SnowflakeUtils, Text, Timestamp, Tooltip, useEffect, useState } from \"@webpack/common\";\nimport type { Channel } from \"discord-types/general\";\n\nimport openRolesAndUsersPermissionsModal, { PermissionType, RoleOrUserPermission } from \"../../permissionsViewer/components/RolesAndUsersPermissions\";\nimport { sortPermissionOverwrites } from \"../../permissionsViewer/utils\";\nimport { settings } from \"..\";\n\nconst enum SortOrderTypes {\n LATEST_ACTIVITY = 0,\n CREATION_DATE = 1\n}\n\nconst enum ForumLayoutTypes {\n DEFAULT = 0,\n LIST = 1,\n GRID = 2\n}\n\ninterface DefaultReaction {\n emojiId: string | null;\n emojiName: string | null;\n}\n\ninterface Tag {\n id: string;\n name: string;\n emojiId: string | null;\n emojiName: string | null;\n moderated: boolean;\n}\n\ninterface ExtendedChannel extends Channel {\n defaultThreadRateLimitPerUser?: number;\n defaultSortOrder?: SortOrderTypes | null;\n defaultForumLayout?: ForumLayoutTypes;\n defaultReactionEmoji?: DefaultReaction | null;\n availableTags?: Array<Tag>;\n}\n\nconst enum ChannelTypes {\n GUILD_TEXT = 0,\n GUILD_VOICE = 2,\n GUILD_ANNOUNCEMENT = 5,\n GUILD_STAGE_VOICE = 13,\n GUILD_FORUM = 15\n}\n\nconst enum VideoQualityModes {\n AUTO = 1,\n FULL = 2\n}\n\nconst enum ChannelFlags {\n PINNED = 1 << 1,\n REQUIRE_TAG = 1 << 4\n}\n\n\nconst ChatScrollClasses = findByPropsLazy(\"auto\", \"content\", \"scrollerBase\");\nconst ChatClasses = findByPropsLazy(\"chat\", \"content\", \"noChat\", \"chatContent\");\nconst ChannelBeginHeader = findComponentByCodeLazy(\".Messages.ROLE_REQUIRED_SINGLE_USER_MESSAGE\");\nconst TagComponent = findComponentLazy(m => {\n if (typeof m !== \"function\") return false;\n\n const code = Function.prototype.toString.call(m);\n // Get the component which doesn't include increasedActivity\n return code.includes(\".Messages.FORUM_TAG_A11Y_FILTER_BY_TAG\") && !code.includes(\"increasedActivityPill\");\n});\n\nconst EmojiParser = findByPropsLazy(\"convertSurrogateToName\");\nconst EmojiUtils = findByPropsLazy(\"getURL\", \"getEmojiColors\");\n\nconst ChannelTypesToChannelNames = {\n [ChannelTypes.GUILD_TEXT]: \"text\",\n [ChannelTypes.GUILD_ANNOUNCEMENT]: \"announcement\",\n [ChannelTypes.GUILD_FORUM]: \"forum\",\n [ChannelTypes.GUILD_VOICE]: \"voice\",\n [ChannelTypes.GUILD_STAGE_VOICE]: \"stage\"\n};\n\nconst SortOrderTypesToNames = {\n [SortOrderTypes.LATEST_ACTIVITY]: \"Latest activity\",\n [SortOrderTypes.CREATION_DATE]: \"Creation date\"\n};\n\nconst ForumLayoutTypesToNames = {\n [ForumLayoutTypes.DEFAULT]: \"Not set\",\n [ForumLayoutTypes.LIST]: \"List view\",\n [ForumLayoutTypes.GRID]: \"Gallery view\"\n};\n\nconst VideoQualityModesToNames = {\n [VideoQualityModes.AUTO]: \"Automatic\",\n [VideoQualityModes.FULL]: \"720p\"\n};\n\n// Icon from the modal when clicking a message link you don't have access to view\nconst HiddenChannelLogo = \"/assets/433e3ec4319a9d11b0cbe39342614982.svg\";\n\nfunction HiddenChannelLockScreen({ channel }: { channel: ExtendedChannel; }) {\n const [viewAllowedUsersAndRoles, setViewAllowedUsersAndRoles] = useState(settings.store.defaultAllowedUsersAndRolesDropdownState);\n const [permissions, setPermissions] = useState<RoleOrUserPermission[]>([]);\n\n const {\n type,\n topic,\n lastMessageId,\n defaultForumLayout,\n lastPinTimestamp,\n defaultAutoArchiveDuration,\n availableTags,\n id: channelId,\n rateLimitPerUser,\n defaultThreadRateLimitPerUser,\n defaultSortOrder,\n defaultReactionEmoji,\n bitrate,\n rtcRegion,\n videoQualityMode,\n permissionOverwrites,\n guild_id\n } = channel;\n\n useEffect(() => {\n const membersToFetch: Array<string> = [];\n\n const guildOwnerId = GuildStore.getGuild(guild_id).ownerId;\n if (!GuildMemberStore.getMember(guild_id, guildOwnerId)) membersToFetch.push(guildOwnerId);\n\n Object.values(permissionOverwrites).forEach(({ type, id: userId }) => {\n if (type === 1 && !GuildMemberStore.getMember(guild_id, userId)) {\n membersToFetch.push(userId);\n }\n });\n\n if (membersToFetch.length > 0) {\n FluxDispatcher.dispatch({\n type: \"GUILD_MEMBERS_REQUEST\",\n guildIds: [guild_id],\n userIds: membersToFetch\n });\n }\n\n if (Settings.plugins.PermissionsViewer.enabled) {\n setPermissions(sortPermissionOverwrites(Object.values(permissionOverwrites).map(overwrite => ({\n type: overwrite.type as PermissionType,\n id: overwrite.id,\n overwriteAllow: overwrite.allow,\n overwriteDeny: overwrite.deny\n })), guild_id));\n }\n }, [channelId]);\n\n return (\n <div className={ChatScrollClasses.auto + \" \" + ChatScrollClasses.customTheme + \" \" + ChatClasses.chatContent + \" \" + \"shc-lock-screen-outer-container\"}>\n <div className=\"shc-lock-screen-container\">\n <img className=\"shc-lock-screen-logo\" src={HiddenChannelLogo} />\n\n <div className=\"shc-lock-screen-heading-container\">\n <Text variant=\"heading-xxl/bold\">This is a {!PermissionStore.can(PermissionsBits.VIEW_CHANNEL, channel) ? \"hidden\" : \"locked\"} {ChannelTypesToChannelNames[type]} channel.</Text>\n {channel.isNSFW() &&\n <Tooltip text=\"NSFW\">\n {({ onMouseLeave, onMouseEnter }) => (\n <svg\n onMouseLeave={onMouseLeave}\n onMouseEnter={onMouseEnter}\n className=\"shc-lock-screen-heading-nsfw-icon\"\n width=\"32\"\n height=\"32\"\n viewBox=\"0 0 48 48\"\n aria-hidden={true}\n role=\"img\"\n >\n <path fill=\"currentColor\" d=\"M.7 43.05 24 2.85l23.3 40.2Zm23.55-6.25q.75 0 1.275-.525.525-.525.525-1.275 0-.75-.525-1.3t-1.275-.55q-.8 0-1.325.55-.525.55-.525 1.3t.55 1.275q.55.525 1.3.525Zm-1.85-6.1h3.65V19.4H22.4Z\" />\n </svg>\n )}\n </Tooltip>\n }\n </div>\n\n {(!channel.isGuildVoice() && !channel.isGuildStageVoice()) && (\n <Text variant=\"text-lg/normal\">\n You can not see the {channel.isForumChannel() ? \"posts\" : \"messages\"} of this channel.\n {channel.isForumChannel() && topic && topic.length > 0 && \" However you may see its guidelines:\"}\n </Text >\n )}\n\n {channel.isForumChannel() && topic && topic.length > 0 && (\n <div className=\"shc-lock-screen-topic-container\">\n {Parser.parseTopic(topic, false, { channelId })}\n </div>\n )}\n\n {lastMessageId &&\n <Text variant=\"text-md/normal\">\n Last {channel.isForumChannel() ? \"post\" : \"message\"} created:\n <Timestamp timestamp={moment(SnowflakeUtils.extractTimestamp(lastMessageId))} />\n </Text>\n }\n\n {lastPinTimestamp &&\n <Text variant=\"text-md/normal\">Last message pin: <Timestamp timestamp={moment(lastPinTimestamp)} /></Text>\n }\n {(rateLimitPerUser ?? 0) > 0 &&\n <Text variant=\"text-md/normal\">Slowmode: {formatDuration(rateLimitPerUser!, \"seconds\")}</Text>\n }\n {(defaultThreadRateLimitPerUser ?? 0) > 0 &&\n <Text variant=\"text-md/normal\">\n Default thread slowmode: {formatDuration(defaultThreadRateLimitPerUser!, \"seconds\")}\n </Text>\n }\n {((channel.isGuildVoice() || channel.isGuildStageVoice()) && bitrate != null) &&\n <Text variant=\"text-md/normal\">Bitrate: {bitrate} bits</Text>\n }\n {rtcRegion !== undefined &&\n <Text variant=\"text-md/normal\">Region: {rtcRegion ?? \"Automatic\"}</Text>\n }\n {(channel.isGuildVoice() || channel.isGuildStageVoice()) &&\n <Text variant=\"text-md/normal\">Video quality mode: {VideoQualityModesToNames[videoQualityMode ?? VideoQualityModes.AUTO]}</Text>\n }\n {(defaultAutoArchiveDuration ?? 0) > 0 &&\n <Text variant=\"text-md/normal\">\n Default inactivity duration before archiving {channel.isForumChannel() ? \"posts\" : \"threads\"}:\n {\" \" + formatDuration(defaultAutoArchiveDuration!, \"minutes\")}\n </Text>\n }\n {defaultForumLayout != null &&\n <Text variant=\"text-md/normal\">Default layout: {ForumLayoutTypesToNames[defaultForumLayout]}</Text>\n }\n {defaultSortOrder != null &&\n <Text variant=\"text-md/normal\">Default sort order: {SortOrderTypesToNames[defaultSortOrder]}</Text>\n }\n {defaultReactionEmoji != null &&\n <div className=\"shc-lock-screen-default-emoji-container\">\n <Text variant=\"text-md/normal\">Default reaction emoji:</Text>\n {Parser.defaultRules[defaultReactionEmoji.emojiName ? \"emoji\" : \"customEmoji\"].react({\n name: defaultReactionEmoji.emojiName\n ? EmojiParser.convertSurrogateToName(defaultReactionEmoji.emojiName)\n : EmojiStore.getCustomEmojiById(defaultReactionEmoji.emojiId)?.name ?? \"\",\n emojiId: defaultReactionEmoji.emojiId ?? void 0,\n surrogate: defaultReactionEmoji.emojiName ?? void 0,\n src: defaultReactionEmoji.emojiName\n ? EmojiUtils.getURL(defaultReactionEmoji.emojiName)\n : void 0\n }, void 0, { key: \"0\" })}\n </div>\n }\n {channel.hasFlag(ChannelFlags.REQUIRE_TAG) &&\n <Text variant=\"text-md/normal\">Posts on this forum require a tag to be set.</Text>\n }\n {availableTags && availableTags.length > 0 &&\n <div className=\"shc-lock-screen-tags-container\">\n <Text variant=\"text-lg/bold\">Available tags:</Text>\n <div className=\"shc-lock-screen-tags\">\n {availableTags.map(tag => <TagComponent tag={tag} />)}\n </div>\n </div>\n }\n <div className=\"shc-lock-screen-allowed-users-and-roles-container\">\n <div className=\"shc-lock-screen-allowed-users-and-roles-container-title\">\n {Settings.plugins.PermissionsViewer.enabled && (\n <Tooltip text=\"Permission Details\">\n {({ onMouseLeave, onMouseEnter }) => (\n <button\n onMouseLeave={onMouseLeave}\n onMouseEnter={onMouseEnter}\n className=\"shc-lock-screen-allowed-users-and-roles-container-permdetails-btn\"\n onClick={() => openRolesAndUsersPermissionsModal(permissions, GuildStore.getGuild(channel.guild_id), channel.name)}\n >\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n >\n <path fill=\"currentColor\" d=\"M7 12.001C7 10.8964 6.10457 10.001 5 10.001C3.89543 10.001 3 10.8964 3 12.001C3 13.1055 3.89543 14.001 5 14.001C6.10457 14.001 7 13.1055 7 12.001ZM14 12.001C14 10.8964 13.1046 10.001 12 10.001C10.8954 10.001 10 10.8964 10 12.001C10 13.1055 10.8954 14.001 12 14.001C13.1046 14.001 14 13.1055 14 12.001ZM19 10.001C20.1046 10.001 21 10.8964 21 12.001C21 13.1055 20.1046 14.001 19 14.001C17.8954 14.001 17 13.1055 17 12.001C17 10.8964 17.8954 10.001 19 10.001Z\" />\n </svg>\n </button>\n )}\n </Tooltip>\n )}\n <Text variant=\"text-lg/bold\">Allowed users and roles:</Text>\n <Tooltip text={viewAllowedUsersAndRoles ? \"Hide Allowed Users and Roles\" : \"View Allowed Users and Roles\"}>\n {({ onMouseLeave, onMouseEnter }) => (\n <button\n onMouseLeave={onMouseLeave}\n onMouseEnter={onMouseEnter}\n className=\"shc-lock-screen-allowed-users-and-roles-container-toggle-btn\"\n onClick={() => setViewAllowedUsersAndRoles(v => !v)}\n >\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n transform={viewAllowedUsersAndRoles ? \"scale(1 -1)\" : \"scale(1 1)\"}\n >\n <path fill=\"currentColor\" d=\"M16.59 8.59003L12 13.17L7.41 8.59003L6 10L12 16L18 10L16.59 8.59003Z\" />\n </svg>\n </button>\n )}\n </Tooltip>\n </div>\n {viewAllowedUsersAndRoles && <ChannelBeginHeader channel={channel} />}\n </div>\n </div>\n </div>\n );\n}\n\nexport default ErrorBoundary.wrap(HiddenChannelLockScreen);\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport \"./style.css\";\n\nimport { definePluginSettings } from \"@api/Settings\";\nimport ErrorBoundary from \"@components/ErrorBoundary\";\nimport { Devs } from \"@utils/constants\";\nimport { canonicalizeMatch } from \"@utils/patches\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { findByPropsLazy } from \"@webpack\";\nimport { ChannelStore, PermissionsBits, PermissionStore, Tooltip } from \"@webpack/common\";\nimport type { Channel, Role } from \"discord-types/general\";\n\nimport HiddenChannelLockScreen from \"./components/HiddenChannelLockScreen\";\n\nconst ChannelListClasses = findByPropsLazy(\"channelEmoji\", \"unread\", \"icon\");\n\nconst enum ShowMode {\n LockIcon,\n HiddenIconWithMutedStyle\n}\n\nexport const settings = definePluginSettings({\n hideUnreads: {\n description: \"Hide Unreads\",\n type: OptionType.BOOLEAN,\n default: true,\n restartNeeded: true\n },\n showMode: {\n description: \"The mode used to display hidden channels.\",\n type: OptionType.SELECT,\n options: [\n { label: \"Plain style with Lock Icon instead\", value: ShowMode.LockIcon, default: true },\n { label: \"Muted style with hidden eye icon on the right\", value: ShowMode.HiddenIconWithMutedStyle },\n ],\n restartNeeded: true\n },\n defaultAllowedUsersAndRolesDropdownState: {\n description: \"Whether the allowed users and roles dropdown on hidden channels should be open by default\",\n type: OptionType.BOOLEAN,\n default: true\n }\n});\n\nexport default definePlugin({\n name: \"ShowHiddenChannels\",\n description: \"Show channels that you do not have access to view.\",\n authors: [Devs.BigDuck, Devs.AverageReactEnjoyer, Devs.D3SOX, Devs.Ven, Devs.Nuckyz, Devs.Nickyux, Devs.dzshn],\n settings,\n\n patches: [\n {\n // RenderLevel defines if a channel is hidden, collapsed in category, visible, etc\n find: '\"placeholder-channel-id\"',\n replacement: [\n // Remove the special logic for channels we don't have access to\n {\n match: /if\\(!\\i\\.\\i\\.can\\(\\i\\.\\i\\.VIEW_CHANNEL.+?{if\\(this\\.id===\\i\\).+?threadIds:\\i}}/,\n replace: \"\"\n },\n // Do not check for unreads when selecting the render level if the channel is hidden\n {\n match: /(?<=&&)(?=!\\i\\.\\i\\.hasUnread\\(this\\.record\\.id\\))/,\n replace: \"$self.isHiddenChannel(this.record)||\"\n },\n // Make channels we dont have access to be the same level as normal ones\n {\n match: /(activeJoinedRelevantThreads:.{0,50}VIEW_CHANNEL.+?renderLevel:(.+?),threadIds.+?renderLevel:).+?(?=,threadIds)/g,\n replace: (_, rest, defaultRenderLevel) => `${rest}${defaultRenderLevel}`\n },\n // Remove permission checking for getRenderLevel function\n {\n match: /(?<=getRenderLevel\\(\\i\\){.+?return)!\\i\\.\\i\\.can\\(\\i\\.\\i\\.VIEW_CHANNEL,this\\.record\\)\\|\\|/,\n replace: \" \"\n }\n ]\n },\n {\n find: \"VoiceChannel, transitionTo: Channel does not have a guildId\",\n replacement: [\n {\n // Do not show confirmation to join a voice channel when already connected to another if clicking on a hidden voice channel\n match: /(?<=getCurrentClientVoiceChannelId\\((\\i)\\.guild_id\\);return)/,\n replace: (_, channel) => `!$self.isHiddenChannel(${channel})&&`\n },\n {\n // Prevent Discord from trying to connect to hidden voice channels\n match: /(?=&&\\i\\.\\i\\.selectVoiceChannel\\((\\i)\\.id\\))/,\n replace: (_, channel) => `&&!$self.isHiddenChannel(${channel})`\n },\n {\n // Make Discord show inside the channel if clicking on a hidden or locked channel\n match: /!__OVERLAY__&&\\((?<=selectVoiceChannel\\((\\i)\\.id\\).+?)/,\n replace: (m, channel) => `${m}$self.isHiddenChannel(${channel},true)||`\n }\n ]\n },\n // Prevent Discord from trying to connect to hidden stage channels\n {\n find: \".MAX_STAGE_VOICE_USER_LIMIT})\",\n replacement: {\n match: /!(\\i)\\.isRoleSubscriptionTemplatePreviewChannel\\(\\)/,\n replace: (m, channel) => `${m}&&!$self.isHiddenChannel(${channel})`\n }\n },\n {\n find: \"ChannelItemEditButton:function(){\",\n replacement: [\n // Render null instead of the buttons if the channel is hidden\n ...[\n \"renderEditButton\",\n \"renderInviteButton\",\n ].map(func => ({\n match: new RegExp(`(?<=${func}\\\\(\\\\){)`, \"g\"), // Global because Discord has multiple declarations of the same functions\n replace: \"if($self.isHiddenChannel(this.props.channel))return null;\"\n }))\n ]\n },\n {\n find: \"VoiceChannel.renderPopout: There must always be something to render\",\n all: true,\n // Render null instead of the buttons if the channel is hidden\n replacement: {\n match: /(?<=renderOpenChatButton=\\(\\)=>{)/,\n replace: \"if($self.isHiddenChannel(this.props.channel))return null;\"\n }\n },\n {\n find: \".Messages.CHANNEL_TOOLTIP_DIRECTORY\",\n predicate: () => settings.store.showMode === ShowMode.LockIcon,\n replacement: {\n // Lock Icon\n match: /(?=switch\\((\\i)\\.type\\).{0,30}\\.GUILD_ANNOUNCEMENT.{0,70}\\(0,\\i\\.\\i\\))/,\n replace: (_, channel) => `if($self.isHiddenChannel(${channel}))return $self.LockIcon;`\n }\n },\n {\n find: \"UNREAD_IMPORTANT:\",\n predicate: () => settings.store.showMode === ShowMode.HiddenIconWithMutedStyle,\n replacement: [\n // Make the channel appear as muted if it's hidden\n {\n match: /(?<={channel:(\\i),name:\\i,muted:(\\i).+?;)/,\n replace: (_, channel, muted) => `${muted}=$self.isHiddenChannel(${channel})?true:${muted};`\n },\n // Add the hidden eye icon if the channel is hidden\n {\n match: /\\i\\.children.+?:null(?<=,channel:(\\i).+?)/,\n replace: (m, channel) => `${m},$self.isHiddenChannel(${channel})?$self.HiddenChannelIcon():null`\n },\n // Make voice channels also appear as muted if they are muted\n {\n match: /(?<=\\.wrapper:\\i\\.notInteractive,)(.+?)if\\((\\i)\\)return (\\i\\.MUTED);/,\n replace: (_, otherClasses, isMuted, mutedClassExpression) => `${isMuted}?${mutedClassExpression}:\"\",${otherClasses}if(${isMuted})return \"\";`\n }\n ]\n },\n {\n find: \"UNREAD_IMPORTANT:\",\n replacement: [\n {\n // Make muted channels also appear as unread if hide unreads is false, using the HiddenIconWithMutedStyle and the channel is hidden\n predicate: () => settings.store.hideUnreads === false && settings.store.showMode === ShowMode.HiddenIconWithMutedStyle,\n match: /\\.LOCKED;if\\((?<={channel:(\\i).+?)/,\n replace: (m, channel) => `${m}!$self.isHiddenChannel(${channel})&&`\n },\n {\n // Hide unreads\n predicate: () => settings.store.hideUnreads === true,\n match: /(?<={channel:(\\i),name:\\i,.+?unread:(\\i).+?;)/,\n replace: (_, channel, unread) => `${unread}=$self.isHiddenChannel(${channel})?false:${unread};`\n }\n ]\n },\n {\n // Hide the new version of unreads box for hidden channels\n find: '.displayName=\"ChannelListUnreadsStore\"',\n replacement: {\n match: /(?<=if\\(null==(\\i))(?=.{0,160}?getHasImportantUnread\\)\\(\\i\\))/g, // Global because Discord has multiple methods like that in the same module\n replace: (_, channel) => `||$self.isHiddenChannel(${channel})`\n }\n },\n {\n // Make the old version of unreads box not visible for hidden channels\n find: \"renderBottomUnread(){\",\n replacement: {\n match: /(?=&&\\(0,\\i\\.getHasImportantUnread\\)\\((\\i\\.record)\\))/,\n replace: \"&&!$self.isHiddenChannel($1)\"\n }\n },\n {\n // Make the state of the old version of unreads box not include hidden channels\n find: \".useFlattenedChannelIdListWithThreads)\",\n replacement: {\n match: /(?=&&\\(0,\\i\\.getHasImportantUnread\\)\\((\\i)\\))/,\n replace: \"&&!$self.isHiddenChannel($1)\"\n }\n },\n // Only render the channel header and buttons that work when transitioning to a hidden channel\n {\n find: \"Missing channel in Channel.renderHeaderToolbar\",\n replacement: [\n {\n match: /(?<=renderHeaderToolbar=\\(\\)=>{.+?case \\i\\.\\i\\.GUILD_TEXT:)(?=.+?(\\i\\.push.{0,50}channel:(\\i)},\"notifications\"\\)\\)))(?<=isLurking:(\\i).+?)/,\n replace: (_, pushNotificationButtonExpression, channel, isLurking) => `if(!${isLurking}&&$self.isHiddenChannel(${channel})){${pushNotificationButtonExpression};break;}`\n },\n {\n match: /(?<=renderHeaderToolbar=\\(\\)=>{.+?case \\i\\.\\i\\.GUILD_MEDIA:)(?=.+?(\\i\\.push.{0,40}channel:(\\i)},\"notifications\"\\)\\)))(?<=isLurking:(\\i).+?)/,\n replace: (_, pushNotificationButtonExpression, channel, isLurking) => `if(!${isLurking}&&$self.isHiddenChannel(${channel})){${pushNotificationButtonExpression};break;}`\n },\n {\n match: /renderMobileToolbar=\\(\\)=>{.+?case \\i\\.\\i\\.GUILD_DIRECTORY:(?<=let{channel:(\\i).+?)/,\n replace: (m, channel) => `${m}if($self.isHiddenChannel(${channel}))break;`\n },\n {\n match: /(?<=renderHeaderBar=\\(\\)=>{.+?hideSearch:(\\i)\\.isDirectory\\(\\))/,\n replace: (_, channel) => `||$self.isHiddenChannel(${channel})`\n },\n {\n match: /(?<=renderSidebar\\(\\){)/,\n replace: \"if($self.isHiddenChannel(this.props.channel))return null;\"\n },\n {\n match: /(?<=renderChat\\(\\){)/,\n replace: \"if($self.isHiddenChannel(this.props.channel))return $self.HiddenChannelLockScreen(this.props.channel);\"\n }\n ]\n },\n // Avoid trying to fetch messages from hidden channels\n {\n find: '\"MessageManager\"',\n replacement: {\n match: /\"Skipping fetch because channelId is a static route\"\\);return}(?=.+?getChannel\\((\\i)\\))/,\n replace: (m, channelId) => `${m}if($self.isHiddenChannel({channelId:${channelId}}))return;`\n }\n },\n // Patch keybind handlers so you can't accidentally jump to hidden channels\n {\n find: '\"alt+shift+down\"',\n replacement: {\n match: /(?<=getChannel\\(\\i\\);return null!=(\\i))(?=.{0,150}?getHasImportantUnread\\)\\(\\i\\))/,\n replace: (_, channel) => `&&!$self.isHiddenChannel(${channel})`\n }\n },\n // Patch keybind handlers so you can't accidentally jump to hidden channels\n {\n find: \".APPLICATION_STORE&&null!=\",\n replacement: {\n match: /(?<=getState\\(\\)\\.channelId.{0,30}?\\(0,\\i\\.\\i\\)\\(\\i\\))(?=\\.map\\()/,\n replace: \".filter(e=>!$self.isHiddenChannel(e))\"\n }\n },\n {\n find: \".Messages.ROLE_REQUIRED_SINGLE_USER_MESSAGE\",\n replacement: [\n {\n // Change the role permission check to CONNECT if the channel is locked\n match: /ADMINISTRATOR\\)\\|\\|(?<=context:(\\i)}.+?)(?=(.+?)VIEW_CHANNEL)/,\n replace: (m, channel, permCheck) => `${m}!Vencord.Webpack.Common.PermissionStore.can(${PermissionsBits.CONNECT}n,${channel})?${permCheck}CONNECT):`\n },\n {\n // Change the permissionOverwrite check to CONNECT if the channel is locked\n match: /permissionOverwrites\\[.+?\\i=(?<=context:(\\i)}.+?)(?=(.+?)VIEW_CHANNEL)/,\n replace: (m, channel, permCheck) => `${m}!Vencord.Webpack.Common.PermissionStore.can(${PermissionsBits.CONNECT}n,${channel})?${permCheck}CONNECT):`\n },\n {\n // Include the @everyone role in the allowed roles list for Hidden Channels\n match: /sortBy.{0,30}?\\.filter\\(\\i=>(?<=channel:(\\i).+?)/,\n replace: (m, channel) => `${m}$self.isHiddenChannel(${channel})?true:`\n },\n {\n // If the @everyone role has the required permissions, make the array only contain it\n match: /computePermissionsForRoles.+?.value\\(\\)(?<=channel:(\\i).+?)/,\n replace: (m, channel) => `${m}.reduce(...$self.makeAllowedRolesReduce(${channel}.guild_id))`\n },\n {\n // Patch the header to only return allowed users and roles if it's a hidden channel or locked channel (Like when it's used on the HiddenChannelLockScreen)\n match: /MANAGE_ROLES.{0,90}?return(?=\\(.+?(\\(0,\\i\\.jsxs\\)\\(\"div\",{className:\\i\\.members.+?guildId:(\\i)\\.guild_id.+?roleColor.+?\\]}\\)))/,\n replace: (m, component, channel) => {\n // Export the channel for the users allowed component patch\n component = component.replace(canonicalizeMatch(/(?<=users:\\i)/), `,shcChannel:${channel}`);\n // Always render the component for multiple allowed users\n component = component.replace(canonicalizeMatch(/1!==\\i\\.length/), \"true\");\n\n return `${m} $self.isHiddenChannel(${channel},true)?${component}:`;\n }\n }\n ]\n },\n {\n find: \".avatars),children\",\n replacement: [\n {\n // Create a variable for the channel prop\n match: /maxUsers:\\i,users:\\i.+?=(\\i).+?;/,\n replace: (m, props) => `${m}let{shcChannel}=${props};`\n },\n {\n // Make Discord always render the plus button if the component is used inside the HiddenChannelLockScreen\n match: /\\i>0(?=&&.{0,60}renderPopout)/,\n replace: m => `($self.isHiddenChannel(shcChannel,true)?true:${m})`\n },\n {\n // Prevent Discord from overwriting the last children with the plus button if the overflow amount is <= 0 and the component is used inside the HiddenChannelLockScreen\n match: /(?<=\\.value\\(\\),(\\i)=.+?length-)1(?=\\]=.{0,60}renderPopout)/,\n replace: (_, amount) => `($self.isHiddenChannel(shcChannel,true)&&${amount}<=0?0:1)`\n },\n {\n // Show only the plus text without overflowed children amount if the overflow amount is <= 0 and the component is used inside the HiddenChannelLockScreen\n match: /(?<=\"\\+\",)(\\i)\\+1/,\n replace: (m, amount) => `$self.isHiddenChannel(shcChannel,true)&&${amount}<=0?\"\":${m}`\n }\n ]\n },\n {\n find: \".Messages.CHANNEL_CALL_CURRENT_SPEAKER.format\",\n replacement: [\n {\n // Remove the divider and the open chat button for the HiddenChannelLockScreen\n match: /\"more-options-popout\"\\)\\),(?<=channel:(\\i).+?inCall:(\\i).+?)/,\n replace: (m, channel, inCall) => `${m}${inCall}||!$self.isHiddenChannel(${channel},true)&&`\n },\n {\n // Remove invite users button for the HiddenChannelLockScreen\n match: /\"popup\".{0,100}?if\\((?<=channel:(\\i).+?inCall:(\\i).+?)/,\n replace: (m, channel, inCall) => `${m}(${inCall}||!$self.isHiddenChannel(${channel},true))&&`\n },\n ]\n },\n {\n find: \".Messages.EMBEDDED_ACTIVITIES_DEVELOPER_ACTIVITY_SHELF_FETCH_ERROR\",\n replacement: [\n {\n // Render our HiddenChannelLockScreen component instead of the main voice channel component\n match: /renderContent\\(\\i\\){.+?this\\.renderVoiceChannelEffects.+?children:/,\n replace: \"$&!this.props.inCall&&$self.isHiddenChannel(this.props.channel,true)?$self.HiddenChannelLockScreen(this.props.channel):\"\n },\n {\n // Disable gradients for the HiddenChannelLockScreen of voice channels\n match: /renderContent\\(\\i\\){.+?disableGradients:/,\n replace: \"$&!this.props.inCall&&$self.isHiddenChannel(this.props.channel,true)||\"\n },\n {\n // Disable useless components for the HiddenChannelLockScreen of voice channels\n match: /(?:{|,)render(?!Header|ExternalHeader).{0,30}?:/g,\n replace: \"$&!this.props.inCall&&$self.isHiddenChannel(this.props.channel,true)?()=>null:\"\n },\n {\n // Disable bad CSS class which mess up hidden voice channels styling\n match: /callContainer,(?<=\\i\\.callContainer,)/,\n replace: '$&!this.props.inCall&&$self.isHiddenChannel(this.props.channel,true)?\"\":'\n }\n ]\n },\n {\n find: '\"HasBeenInStageChannel\"',\n replacement: [\n {\n // Render our HiddenChannelLockScreen component instead of the main stage channel component\n match: /\"124px\".+?children:(?<=let \\i,{channel:(\\i).+?)(?=.{0,20}?}\\)}function)/,\n replace: (m, channel) => `${m}$self.isHiddenChannel(${channel})?$self.HiddenChannelLockScreen(${channel}):`\n },\n {\n // Disable useless components for the HiddenChannelLockScreen of stage channels\n match: /render(?:BottomLeft|BottomCenter|BottomRight|ChatToasts):\\(\\)=>(?<=let \\i,{channel:(\\i).+?)/g,\n replace: (m, channel) => `${m}$self.isHiddenChannel(${channel})?null:`\n },\n {\n // Disable gradients for the HiddenChannelLockScreen of stage channels\n match: /\"124px\".+?disableGradients:(?<=let \\i,{channel:(\\i).+?)/,\n replace: (m, channel) => `${m}$self.isHiddenChannel(${channel})||`\n },\n {\n // Disable strange styles applied to the header for the HiddenChannelLockScreen of stage channels\n match: /\"124px\".+?style:(?<=let \\i,{channel:(\\i).+?)/,\n replace: (m, channel) => `${m}$self.isHiddenChannel(${channel})?void 0:`\n }\n ]\n },\n {\n find: \".Messages.STAGE_FULL_MODERATOR_TITLE\",\n replacement: [\n {\n // Remove the divider and amount of users in stage channel components for the HiddenChannelLockScreen\n match: /\\(0,\\i\\.jsx\\)\\(\\i\\.\\i\\.Divider.+?}\\)]}\\)(?=.+?:(\\i)\\.guild_id)/,\n replace: (m, channel) => `$self.isHiddenChannel(${channel})?null:(${m})`\n },\n {\n // Remove the open chat button for the HiddenChannelLockScreen\n match: /\"recents\".+?&&(?=\\(.+?channelId:(\\i)\\.id,showRequestToSpeakSidebar)/,\n replace: (m, channel) => `${m}!$self.isHiddenChannel(${channel})&&`\n }\n ]\n },\n {\n // Make the chat input bar channel list contain hidden channels\n find: \",queryStaticRouteChannels(\",\n replacement: [\n {\n // Make the getChannels call to GuildChannelStore return hidden channels\n match: /(?<=queryChannels\\(\\i\\){.+?getChannels\\(\\i)(?=\\))/,\n replace: \",true\"\n },\n {\n // Avoid filtering out hidden channels from the channel list\n match: /(?<=queryChannels\\(\\i\\){.+?isGuildChannelType\\)\\((\\i)\\.type\\))(?=&&!\\i\\.\\i\\.can\\()/,\n replace: \"&&!$self.isHiddenChannel($1)\"\n }\n ]\n },\n {\n find: \"\\\"^/guild-stages/(\\\\\\\\d+)(?:/)?(\\\\\\\\d+)?\\\"\",\n replacement: {\n // Make mentions of hidden channels work\n match: /\\i\\.\\i\\.can\\(\\i\\.\\i\\.VIEW_CHANNEL,\\i\\)/,\n replace: \"true\"\n },\n },\n {\n find: \".shouldCloseDefaultModals\",\n replacement: {\n // Show inside voice channel instead of trying to join them when clicking on a channel mention\n match: /(?<=getChannel\\(\\i\\);if\\(null!=(\\i))(?=.{0,100}?selectVoiceChannel)/,\n replace: (_, channel) => `&&!$self.isHiddenChannel(${channel})`\n }\n },\n {\n find: '.displayName=\"GuildChannelStore\"',\n replacement: [\n {\n // Make GuildChannelStore contain hidden channels\n match: /isChannelGated\\(.+?\\)(?=&&)/,\n replace: m => `${m}&&false`\n },\n {\n // Filter hidden channels from GuildChannelStore.getChannels unless told otherwise\n match: /(?<=getChannels\\(\\i)(\\){.+?)return (.+?)}/,\n replace: (_, rest, channels) => `,shouldIncludeHidden${rest}return $self.resolveGuildChannels(${channels},shouldIncludeHidden??false);}`\n }\n ]\n },\n {\n find: \".Messages.FORM_LABEL_MUTED\",\n replacement: {\n // Make GuildChannelStore.getChannels return hidden channels\n match: /(?<=getChannels\\(\\i)(?=\\))/,\n replace: \",true\"\n }\n },\n {\n find: '.displayName=\"NowPlayingViewStore\"',\n replacement: {\n // Make active now voice states on hidden channels\n match: /(getVoiceStateForUser.{0,150}?)&&\\i\\.\\i\\.canWithPartialContext.{0,20}VIEW_CHANNEL.+?}\\)(?=\\?)/,\n replace: \"$1\"\n }\n }\n ],\n\n isHiddenChannel(channel: Channel & { channelId?: string; }, checkConnect = false) {\n if (!channel) return false;\n\n if (channel.channelId) channel = ChannelStore.getChannel(channel.channelId);\n if (!channel || channel.isDM() || channel.isGroupDM() || channel.isMultiUserDM()) return false;\n\n return !PermissionStore.can(PermissionsBits.VIEW_CHANNEL, channel) || checkConnect && !PermissionStore.can(PermissionsBits.CONNECT, channel);\n },\n\n resolveGuildChannels(channels: Record<string | number, Array<{ channel: Channel; comparator: number; }> | string | number>, shouldIncludeHidden: boolean) {\n if (shouldIncludeHidden) return channels;\n\n const res = {};\n for (const [key, maybeObjChannels] of Object.entries(channels)) {\n if (!Array.isArray(maybeObjChannels)) {\n res[key] = maybeObjChannels;\n continue;\n }\n\n res[key] ??= [];\n\n for (const objChannel of maybeObjChannels) {\n if (objChannel.channel.id === null || !this.isHiddenChannel(objChannel.channel)) res[key].push(objChannel);\n }\n }\n\n return res;\n },\n\n makeAllowedRolesReduce(guildId: string) {\n return [\n (prev: Array<Role>, _: Role, index: number, originalArray: Array<Role>) => {\n if (index !== 0) return prev;\n\n const everyoneRole = originalArray.find(role => role.id === guildId);\n\n if (everyoneRole) return [everyoneRole];\n return originalArray;\n },\n [] as Array<Role>\n ];\n },\n\n HiddenChannelLockScreen: (channel: any) => <HiddenChannelLockScreen channel={channel} />,\n\n LockIcon: ErrorBoundary.wrap(() => (\n <svg\n className={ChannelListClasses.icon}\n height=\"18\"\n width=\"20\"\n viewBox=\"0 0 24 24\"\n aria-hidden={true}\n role=\"img\"\n >\n <path className=\"shc-evenodd-fill-current-color\" d=\"M17 11V7C17 4.243 14.756 2 12 2C9.242 2 7 4.243 7 7V11C5.897 11 5 11.896 5 13V20C5 21.103 5.897 22 7 22H17C18.103 22 19 21.103 19 20V13C19 11.896 18.103 11 17 11ZM12 18C11.172 18 10.5 17.328 10.5 16.5C10.5 15.672 11.172 15 12 15C12.828 15 13.5 15.672 13.5 16.5C13.5 17.328 12.828 18 12 18ZM15 11H9V7C9 5.346 10.346 4 12 4C13.654 4 15 5.346 15 7V11Z\" />\n </svg>\n ), { noop: true }),\n\n HiddenChannelIcon: ErrorBoundary.wrap(() => (\n <Tooltip text=\"Hidden Channel\">\n {({ onMouseLeave, onMouseEnter }) => (\n <svg\n onMouseLeave={onMouseLeave}\n onMouseEnter={onMouseEnter}\n className={ChannelListClasses.icon + \" \" + \"shc-hidden-channel-icon\"}\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n aria-hidden={true}\n role=\"img\"\n >\n <path className=\"shc-evenodd-fill-current-color\" d=\"m19.8 22.6-4.2-4.15q-.875.275-1.762.413Q12.95 19 12 19q-3.775 0-6.725-2.087Q2.325 14.825 1 11.5q.525-1.325 1.325-2.463Q3.125 7.9 4.15 7L1.4 4.2l1.4-1.4 18.4 18.4ZM12 16q.275 0 .512-.025.238-.025.513-.1l-5.4-5.4q-.075.275-.1.513-.025.237-.025.512 0 1.875 1.312 3.188Q10.125 16 12 16Zm7.3.45-3.175-3.15q.175-.425.275-.862.1-.438.1-.938 0-1.875-1.312-3.188Q13.875 7 12 7q-.5 0-.938.1-.437.1-.862.3L7.65 4.85q1.025-.425 2.1-.638Q10.825 4 12 4q3.775 0 6.725 2.087Q21.675 8.175 23 11.5q-.575 1.475-1.512 2.738Q20.55 15.5 19.3 16.45Zm-4.625-4.6-3-3q.7-.125 1.288.112.587.238 1.012.688.425.45.613 1.038.187.587.087 1.162Z\" />\n </svg>\n )}\n </Tooltip>\n ), { noop: true })\n});\n", "/*\n * Vencord, a Discord client mod\n * Copyright (c) 2023 rini\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport \"./styles.css\";\n\nimport { definePluginSettings } from \"@api/Settings\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { Message, User } from \"discord-types/general\";\n\ninterface UsernameProps {\n author: { nick: string; };\n message: Message;\n withMentionPrefix?: boolean;\n isRepliedMessage: boolean;\n userOverride?: User;\n}\n\nconst settings = definePluginSettings({\n mode: {\n type: OptionType.SELECT,\n description: \"How to display usernames and nicks\",\n options: [\n { label: \"Username then nickname\", value: \"user-nick\", default: true },\n { label: \"Nickname then username\", value: \"nick-user\" },\n { label: \"Username only\", value: \"user\" },\n ],\n },\n displayNames: {\n type: OptionType.BOOLEAN,\n description: \"Use display names in place of usernames\",\n default: false\n },\n inReplies: {\n type: OptionType.BOOLEAN,\n default: false,\n description: \"Also apply functionality to reply previews\",\n },\n});\n\nexport default definePlugin({\n name: \"ShowMeYourName\",\n description: \"Display usernames next to nicks, or no nicks at all\",\n authors: [Devs.Rini, Devs.TheKodeToad],\n patches: [\n {\n find: \".useCanSeeRemixBadge)\",\n replacement: {\n match: /(?<=onContextMenu:\\i,children:).*?\\}/,\n replace: \"$self.renderUsername(arguments[0])}\"\n }\n },\n ],\n settings,\n\n renderUsername: ({ author, message, isRepliedMessage, withMentionPrefix, userOverride }: UsernameProps) => {\n try {\n const user = userOverride ?? message.author;\n let { username } = user;\n if (settings.store.displayNames)\n username = (user as any).globalName || username;\n\n const { nick } = author;\n const prefix = withMentionPrefix ? \"@\" : \"\";\n if (username === nick || isRepliedMessage && !settings.store.inReplies)\n return prefix + nick;\n if (settings.store.mode === \"user-nick\")\n return <>{prefix}{username} <span className=\"vc-smyn-suffix\">{nick}</span></>;\n if (settings.store.mode === \"nick-user\")\n return <>{prefix}{nick} <span className=\"vc-smyn-suffix\">{username}</span></>;\n return prefix + username;\n } catch {\n return author?.nick;\n }\n },\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\n\nexport default definePlugin({\n name: \"ShowTimeouts\",\n description: \"Display member timeout icons in chat regardless of permissions.\",\n authors: [Devs.Dolfies],\n patches: [\n {\n find: \"showCommunicationDisabledStyles\",\n replacement: {\n match: /&&\\i\\.\\i\\.canManageUser\\(\\i\\.\\i\\.MODERATE_MEMBERS,\\i\\.author,\\i\\)/,\n replace: \"\",\n },\n },\n ],\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { addPreSendListener, removePreSendListener, SendListener } from \"@api/MessageEvents\";\nimport { definePluginSettings } from \"@api/Settings\";\nimport ErrorBoundary from \"@components/ErrorBoundary\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { Button, ButtonLooks, ButtonWrapperClasses, React, Tooltip } from \"@webpack/common\";\n\nlet lastState = false;\n\nconst settings = definePluginSettings({\n persistState: {\n type: OptionType.BOOLEAN,\n description: \"Whether to persist the state of the silent message toggle when changing channels\",\n default: false,\n onChange(newValue: boolean) {\n if (newValue === false) lastState = false;\n }\n },\n autoDisable: {\n type: OptionType.BOOLEAN,\n description: \"Automatically disable the silent message toggle again after sending one\",\n default: true\n }\n});\n\nfunction SilentMessageToggle(chatBoxProps: {\n type: {\n analyticsName: string;\n };\n}) {\n const [enabled, setEnabled] = React.useState(lastState);\n\n function setEnabledValue(value: boolean) {\n if (settings.store.persistState) lastState = value;\n setEnabled(value);\n }\n\n React.useEffect(() => {\n const listener: SendListener = (_, message) => {\n if (enabled) {\n if (settings.store.autoDisable) setEnabledValue(false);\n if (!message.content.startsWith(\"@silent \")) message.content = \"@silent \" + message.content;\n }\n };\n\n addPreSendListener(listener);\n return () => void removePreSendListener(listener);\n }, [enabled]);\n\n if (chatBoxProps.type.analyticsName !== \"normal\") return null;\n\n return (\n <Tooltip text={enabled ? \"Disable Silent Message\" : \"Enable Silent Message\"}>\n {tooltipProps => (\n <div style={{ display: \"flex\" }}>\n <Button\n {...tooltipProps}\n onClick={() => setEnabledValue(!enabled)}\n size=\"\"\n look={ButtonLooks.BLANK}\n innerClassName={ButtonWrapperClasses.button}\n style={{ padding: \"0 6px\" }}\n >\n <div className={ButtonWrapperClasses.buttonWrapper}>\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\">\n <path fill=\"currentColor\" mask=\"url(#_)\" d=\"M18 10.7101C15.1085 9.84957 13 7.17102 13 4c0-.30736.0198-.6101.0582-.907C12.7147 3.03189 12.3611 3 12 3 8.686 3 6 5.686 6 9v5c0 1.657-1.344 3-3 3v1h18v-1c-1.656 0-3-1.343-3-3v-3.2899ZM8.55493 19c.693 1.19 1.96897 2 3.44497 2s2.752-.81 3.445-2H8.55493ZM18.2624 5.50209 21 2.5V1h-4.9651v1.49791h2.4411L16 5.61088V7h5V5.50209h-2.7376Z\" />\n {!enabled && <>\n <mask id=\"_\">\n <path fill=\"#fff\" d=\"M0 0h24v24H0Z\" />\n <path stroke=\"#000\" stroke-width=\"5.99068\" d=\"M0 24 24 0\" />\n </mask>\n <path fill=\"var(--status-danger)\" d=\"m21.178 1.70703 1.414 1.414L4.12103 21.593l-1.414-1.415L21.178 1.70703Z\" />\n </>}\n </svg>\n </div>\n </Button>\n </div>\n )}\n </Tooltip>\n );\n}\n\nexport default definePlugin({\n name: \"SilentMessageToggle\",\n authors: [Devs.Nuckyz, Devs.CatNoir],\n description: \"Adds a button to the chat bar to toggle sending a silent message.\",\n dependencies: [\"MessageEventsAPI\"],\n\n settings,\n patches: [\n {\n find: \"ChannelTextAreaButtons\",\n replacement: {\n match: /(\\i)\\.push.{1,30}disabled:(\\i),.{1,20}\\},\"gift\"\\)\\)/,\n replace: \"$&,(()=>{try{$2||$1.push($self.chatBarIcon(arguments[0]))}catch{}})()\",\n }\n },\n ],\n\n chatBarIcon: ErrorBoundary.wrap(SilentMessageToggle, { noop: true }),\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { ApplicationCommandInputType, ApplicationCommandOptionType, findOption, sendBotMessage } from \"@api/Commands\";\nimport { definePluginSettings } from \"@api/Settings\";\nimport ErrorBoundary from \"@components/ErrorBoundary\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { Button, ButtonLooks, ButtonWrapperClasses, FluxDispatcher, React, Tooltip } from \"@webpack/common\";\n\nconst settings = definePluginSettings({\n showIcon: {\n type: OptionType.BOOLEAN,\n default: false,\n description: \"Show an icon for toggling the plugin\",\n restartNeeded: true,\n },\n isEnabled: {\n type: OptionType.BOOLEAN,\n description: \"Toggle functionality\",\n default: true,\n }\n});\n\nfunction SilentTypingToggle(chatBoxProps: {\n type: {\n analyticsName: string;\n };\n}) {\n const { isEnabled } = settings.use([\"isEnabled\"]);\n const toggle = () => settings.store.isEnabled = !settings.store.isEnabled;\n\n if (chatBoxProps.type.analyticsName !== \"normal\") return null;\n\n return (\n <Tooltip text={isEnabled ? \"Disable Silent Typing\" : \"Enable Silent Typing\"}>\n {(tooltipProps: any) => (\n <div style={{ display: \"flex\" }}>\n <Button\n {...tooltipProps}\n onClick={toggle}\n size=\"\"\n look={ButtonLooks.BLANK}\n innerClassName={ButtonWrapperClasses.button}\n style={{ padding: \"0 6px\" }}\n >\n <div className={ButtonWrapperClasses.buttonWrapper}>\n <svg width=\"24\" height=\"24\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 576 512\">\n <path fill=\"currentColor\" d=\"M528 448H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h480c26.51 0 48 21.49 48 48v288c0 26.51-21.49 48-48 48zM128 180v-40c0-6.627-5.373-12-12-12H76c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm-336 96v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm-336 96v-40c0-6.627-5.373-12-12-12H76c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm288 0v-40c0-6.627-5.373-12-12-12H172c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h232c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12z\" />\n {isEnabled && <path d=\"M13 432L590 48\" stroke=\"var(--red-500)\" stroke-width=\"72\" stroke-linecap=\"round\" />}\n </svg>\n </div>\n </Button>\n </div>\n )}\n </Tooltip>\n );\n}\n\nexport default definePlugin({\n name: \"SilentTyping\",\n authors: [Devs.Ven, Devs.Rini],\n description: \"Hide that you are typing\",\n patches: [\n {\n find: '.dispatch({type:\"TYPING_START_LOCAL\"',\n replacement: {\n match: /startTyping\\(\\i\\){.+?},stop/,\n replace: \"startTyping:$self.startTyping,stop\"\n }\n },\n {\n find: \"ChannelTextAreaButtons\",\n predicate: () => settings.store.showIcon,\n replacement: {\n match: /(\\i)\\.push.{1,30}disabled:(\\i),.{1,20}\\},\"gift\"\\)\\)/,\n replace: \"$&,(()=>{try{$2||$1.push($self.chatBarIcon(arguments[0]))}catch{}})()\",\n }\n },\n ],\n dependencies: [\"CommandsAPI\"],\n settings,\n commands: [{\n name: \"silenttype\",\n description: \"Toggle whether you're hiding that you're typing or not.\",\n inputType: ApplicationCommandInputType.BUILT_IN,\n options: [\n {\n name: \"value\",\n description: \"whether to hide or not that you're typing (default is toggle)\",\n required: false,\n type: ApplicationCommandOptionType.BOOLEAN,\n },\n ],\n execute: async (args, ctx) => {\n settings.store.isEnabled = !!findOption(args, \"value\", !settings.store.isEnabled);\n sendBotMessage(ctx.channel.id, {\n content: settings.store.isEnabled ? \"Silent typing enabled!\" : \"Silent typing disabled!\",\n });\n },\n }],\n\n async startTyping(channelId: string) {\n if (settings.store.isEnabled) return;\n FluxDispatcher.dispatch({ type: \"TYPING_START_LOCAL\", channelId });\n },\n\n chatBarIcon: ErrorBoundary.wrap(SilentTypingToggle, { noop: true }),\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { definePluginSettings } from \"@api/Settings\";\nimport { Flex } from \"@components/Flex\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { RelationshipStore } from \"@webpack/common\";\nimport { User } from \"discord-types/general\";\n\nconst settings = definePluginSettings({\n showDates: {\n type: OptionType.BOOLEAN,\n description: \"Show dates on friend requests\",\n default: false,\n restartNeeded: true\n }\n});\n\nexport default definePlugin({\n name: \"SortFriendRequests\",\n authors: [Devs.Megu],\n description: \"Sorts friend requests by date of receipt\",\n settings,\n\n patches: [{\n find: \"getRelationshipCounts(){\",\n replacement: {\n match: /\\.sortBy\\(\\i=>\\i\\.comparator\\)/,\n replace: \".sortBy((row) => $self.sortList(row))\"\n }\n }, {\n find: \".Messages.FRIEND_REQUEST_CANCEL\",\n replacement: {\n predicate: () => settings.store.showDates,\n match: /subText:(\\i)(?=,className:\\i\\.userInfo}\\))(?<=user:(\\i).+?)/,\n replace: (_, subtext, user) => `subText:$self.makeSubtext(${subtext},${user})`\n }\n }],\n\n sortList(row: any) {\n return row.type === 3 || row.type === 4\n ? -this.getSince(row.user)\n : row.comparator;\n },\n\n getSince(user: User) {\n return new Date(RelationshipStore.getSince(user.id));\n },\n\n makeSubtext(text: string, user: User) {\n const since = this.getSince(user);\n return (\n <Flex flexDirection=\"row\" style={{ gap: 0, flexWrap: \"wrap\", lineHeight: \"0.9rem\" }}>\n <span>{text}</span>\n {!isNaN(since.getTime()) && <span>Received &mdash; {since.toDateString()}</span>}\n </Flex>\n );\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\n(window.VencordStyles ??= new Map()).set(\"src/plugins/spotifyControls/hoverOnly.css\", {\n name: \"src/plugins/spotifyControls/hoverOnly.css\",\n source: \".vc-spotify-button-row {\\n height: 0;\\n opacity: 0;\\n pointer-events: none;\\n transition: 0.2s;\\n transition-property: height;\\n}\\n\\n#vc-spotify-player:hover .vc-spotify-button-row {\\n opacity: 1;\\n height: 32px;\\n pointer-events: auto;\\n\\n /* only transition opacity on show to prevent clipping */\\n transition-property: height, opacity;\\n}\\n\",\n classNames: {},\n dom: null,\n});\n\nexport default \"src/plugins/spotifyControls/hoverOnly.css\";\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Settings } from \"@api/Settings\";\nimport { findByProps, proxyLazyWebpack } from \"@webpack\";\nimport { Flux, FluxDispatcher } from \"@webpack/common\";\n\nexport interface Track {\n id: string;\n name: string;\n duration: number;\n isLocal: boolean;\n album: {\n id: string;\n name: string;\n image: {\n height: number;\n width: number;\n url: string;\n };\n };\n artists: {\n id: string;\n href: string;\n name: string;\n type: string;\n uri: string;\n }[];\n}\n\ninterface PlayerState {\n accountId: string;\n track: Track | null;\n volumePercent: number,\n isPlaying: boolean,\n repeat: boolean,\n position: number,\n context?: any;\n device?: Device;\n\n // added by patch\n actual_repeat: Repeat;\n}\n\ninterface Device {\n id: string;\n is_active: boolean;\n}\n\ntype Repeat = \"off\" | \"track\" | \"context\";\n\n// Don't wanna run before Flux and Dispatcher are ready!\nexport const SpotifyStore = proxyLazyWebpack(() => {\n // For some reason ts hates extends Flux.Store\n const { Store } = Flux;\n\n const SpotifySocket = findByProps(\"getActiveSocketAndDevice\");\n const SpotifyUtils = findByProps(\"SpotifyAPI\");\n\n const API_BASE = \"https://api.spotify.com/v1/me/player\";\n\n class SpotifyStore extends Store {\n public mPosition = 0;\n private start = 0;\n\n public track: Track | null = null;\n public device: Device | null = null;\n public isPlaying = false;\n public repeat: Repeat = \"off\";\n public shuffle = false;\n public volume = 0;\n\n public isSettingPosition = false;\n\n public openExternal(path: string) {\n const url = Settings.plugins.SpotifyControls.useSpotifyUris || Vencord.Plugins.isPluginEnabled(\"OpenInApp\")\n ? \"spotify:\" + path.replaceAll(\"/\", (_, idx) => idx === 0 ? \"\" : \":\")\n : \"https://open.spotify.com\" + path;\n\n VencordNative.native.openExternal(url);\n }\n\n // Need to keep track of this manually\n public get position(): number {\n let pos = this.mPosition;\n if (this.isPlaying) {\n pos += Date.now() - this.start;\n }\n return pos;\n }\n\n public set position(p: number) {\n this.mPosition = p;\n this.start = Date.now();\n }\n\n prev() {\n this.req(\"post\", \"/previous\");\n }\n\n next() {\n this.req(\"post\", \"/next\");\n }\n\n setVolume(percent: number) {\n this.req(\"put\", \"/volume\", {\n query: {\n volume_percent: Math.round(percent)\n }\n\n }).then(() => {\n this.volume = percent;\n this.emitChange();\n });\n }\n\n setPlaying(playing: boolean) {\n this.req(\"put\", playing ? \"/play\" : \"/pause\");\n }\n\n setRepeat(state: Repeat) {\n this.req(\"put\", \"/repeat\", {\n query: { state }\n });\n }\n\n setShuffle(state: boolean) {\n this.req(\"put\", \"/shuffle\", {\n query: { state }\n }).then(() => {\n this.shuffle = state;\n this.emitChange();\n });\n }\n\n seek(ms: number) {\n if (this.isSettingPosition) return Promise.resolve();\n\n this.isSettingPosition = true;\n\n return this.req(\"put\", \"/seek\", {\n query: {\n position_ms: Math.round(ms)\n }\n }).catch((e: any) => {\n console.error(\"[VencordSpotifyControls] Failed to seek\", e);\n this.isSettingPosition = false;\n });\n }\n\n private req(method: \"post\" | \"get\" | \"put\", route: string, data: any = {}) {\n if (this.device?.is_active)\n (data.query ??= {}).device_id = this.device.id;\n\n const { socket } = SpotifySocket.getActiveSocketAndDevice();\n return SpotifyUtils.SpotifyAPI[method](socket.accountId, socket.accessToken, {\n url: API_BASE + route,\n ...data\n });\n }\n }\n\n const store = new SpotifyStore(FluxDispatcher, {\n SPOTIFY_PLAYER_STATE(e: PlayerState) {\n store.track = e.track;\n store.device = e.device ?? null;\n store.isPlaying = e.isPlaying ?? false;\n store.volume = e.volumePercent ?? 0;\n store.repeat = e.actual_repeat || \"off\";\n store.position = e.position ?? 0;\n store.isSettingPosition = false;\n store.emitChange();\n },\n SPOTIFY_SET_DEVICES({ devices }: { devices: Device[]; }) {\n store.device = devices.find(d => d.is_active) ?? devices[0] ?? null;\n store.emitChange();\n }\n });\n\n return store;\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport \"./spotifyStyles.css\";\n\nimport ErrorBoundary from \"@components/ErrorBoundary\";\nimport { Flex } from \"@components/Flex\";\nimport { ImageIcon, LinkIcon, OpenExternalIcon } from \"@components/Icons\";\nimport { debounce } from \"@utils/debounce\";\nimport { openImageModal } from \"@utils/discord\";\nimport { classes, copyWithToast } from \"@utils/misc\";\nimport { ContextMenuApi, FluxDispatcher, Forms, Menu, React, useEffect, useState, useStateFromStores } from \"@webpack/common\";\n\nimport { SpotifyStore, Track } from \"./SpotifyStore\";\n\nconst cl = (className: string) => `vc-spotify-${className}`;\n\nfunction msToHuman(ms: number) {\n const minutes = ms / 1000 / 60;\n const m = Math.floor(minutes);\n const s = Math.floor((minutes - m) * 60);\n return `${m.toString().padStart(2, \"0\")}:${s.toString().padStart(2, \"0\")}`;\n}\n\nfunction Svg(path: string, label: string) {\n return () => (\n <svg\n className={classes(cl(\"button-icon\"), cl(label))}\n height=\"24\"\n width=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n aria-label={label}\n focusable={false}\n >\n <path d={path} />\n </svg>\n );\n}\n\n// KraXen's icons :yesyes:\n// from https://fonts.google.com/icons?icon.style=Rounded&icon.set=Material+Icons\n// older material icon style, but still really good\nconst PlayButton = Svg(\"M8 6.82v10.36c0 .79.87 1.27 1.54.84l8.14-5.18c.62-.39.62-1.29 0-1.69L9.54 5.98C8.87 5.55 8 6.03 8 6.82z\", \"play\");\nconst PauseButton = Svg(\"M8 19c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2s-2 .9-2 2v10c0 1.1.9 2 2 2zm6-12v10c0 1.1.9 2 2 2s2-.9 2-2V7c0-1.1-.9-2-2-2s-2 .9-2 2z\", \"pause\");\nconst SkipPrev = Svg(\"M7 6c.55 0 1 .45 1 1v10c0 .55-.45 1-1 1s-1-.45-1-1V7c0-.55.45-1 1-1zm3.66 6.82l5.77 4.07c.66.47 1.58-.01 1.58-.82V7.93c0-.81-.91-1.28-1.58-.82l-5.77 4.07c-.57.4-.57 1.24 0 1.64z\", \"previous\");\nconst SkipNext = Svg(\"M7.58 16.89l5.77-4.07c.56-.4.56-1.24 0-1.63L7.58 7.11C6.91 6.65 6 7.12 6 7.93v8.14c0 .81.91 1.28 1.58.82zM16 7v10c0 .55.45 1 1 1s1-.45 1-1V7c0-.55-.45-1-1-1s-1 .45-1 1z\", \"next\");\nconst Repeat = Svg(\"M7 7h10v1.79c0 .45.54.67.85.35l2.79-2.79c.2-.2.2-.51 0-.71l-2.79-2.79c-.31-.31-.85-.09-.85.36V5H6c-.55 0-1 .45-1 1v4c0 .55.45 1 1 1s1-.45 1-1V7zm10 10H7v-1.79c0-.45-.54-.67-.85-.35l-2.79 2.79c-.2.2-.2.51 0 .71l2.79 2.79c.31.31.85.09.85-.36V19h11c.55 0 1-.45 1-1v-4c0-.55-.45-1-1-1s-1 .45-1 1v3z\", \"repeat\");\nconst Shuffle = Svg(\"M10.59 9.17L6.12 4.7c-.39-.39-1.02-.39-1.41 0-.39.39-.39 1.02 0 1.41l4.46 4.46 1.42-1.4zm4.76-4.32l1.19 1.19L4.7 17.88c-.39.39-.39 1.02 0 1.41.39.39 1.02.39 1.41 0L17.96 7.46l1.19 1.19c.31.31.85.09.85-.36V4.5c0-.28-.22-.5-.5-.5h-3.79c-.45 0-.67.54-.36.85zm-.52 8.56l-1.41 1.41 3.13 3.13-1.2 1.2c-.31.31-.09.85.36.85h3.79c.28 0 .5-.22.5-.5v-3.79c0-.45-.54-.67-.85-.35l-1.19 1.19-3.13-3.14z\", \"shuffle\");\n\nfunction Button(props: React.ButtonHTMLAttributes<HTMLButtonElement>) {\n return (\n <button\n className={cl(\"button\")}\n {...props}\n >\n {props.children}\n </button>\n );\n}\n\nfunction CopyContextMenu({ name, path }: { name: string; path: string; }) {\n const copyId = `spotify-copy-${name}`;\n const openId = `spotify-open-${name}`;\n\n return (\n <Menu.Menu\n navId={`spotify-${name}-menu`}\n onClose={() => FluxDispatcher.dispatch({ type: \"CONTEXT_MENU_CLOSE\" })}\n aria-label={`Spotify ${name} Menu`}\n >\n <Menu.MenuItem\n key={copyId}\n id={copyId}\n label={`Copy ${name} Link`}\n action={() => copyWithToast(\"https://open.spotify.com\" + path)}\n icon={LinkIcon}\n />\n <Menu.MenuItem\n key={openId}\n id={openId}\n label={`Open ${name} in Spotify`}\n action={() => SpotifyStore.openExternal(path)}\n icon={OpenExternalIcon}\n />\n </Menu.Menu>\n );\n}\n\nfunction makeContextMenu(name: string, path: string) {\n return (e: React.MouseEvent<HTMLElement, MouseEvent>) =>\n ContextMenuApi.openContextMenu(e, () => <CopyContextMenu name={name} path={path} />);\n}\n\nfunction Controls() {\n const [isPlaying, shuffle, repeat] = useStateFromStores(\n [SpotifyStore],\n () => [SpotifyStore.isPlaying, SpotifyStore.shuffle, SpotifyStore.repeat]\n );\n\n const [nextRepeat, repeatClassName] = (() => {\n switch (repeat) {\n case \"off\": return [\"context\", \"repeat-off\"] as const;\n case \"context\": return [\"track\", \"repeat-context\"] as const;\n case \"track\": return [\"off\", \"repeat-track\"] as const;\n default: throw new Error(`Invalid repeat state ${repeat}`);\n }\n })();\n\n // the 1 is using position absolute so it does not make the button jump around\n return (\n <Flex className={cl(\"button-row\")} style={{ gap: 0 }}>\n <Button\n className={classes(cl(\"button\"), cl(shuffle ? \"shuffle-on\" : \"shuffle-off\"))}\n onClick={() => SpotifyStore.setShuffle(!shuffle)}\n >\n <Shuffle />\n </Button>\n <Button onClick={() => SpotifyStore.prev()}>\n <SkipPrev />\n </Button>\n <Button onClick={() => SpotifyStore.setPlaying(!isPlaying)}>\n {isPlaying ? <PauseButton /> : <PlayButton />}\n </Button>\n <Button onClick={() => SpotifyStore.next()}>\n <SkipNext />\n </Button>\n <Button\n className={classes(cl(\"button\"), cl(repeatClassName))}\n onClick={() => SpotifyStore.setRepeat(nextRepeat)}\n style={{ position: \"relative\" }}\n >\n {repeat === \"track\" && <span className={cl(\"repeat-1\")}>1</span>}\n <Repeat />\n </Button>\n </Flex>\n );\n}\n\nconst seek = debounce((v: number) => {\n SpotifyStore.seek(v);\n});\n\nfunction SeekBar() {\n const { duration } = SpotifyStore.track!;\n\n const [storePosition, isSettingPosition, isPlaying] = useStateFromStores(\n [SpotifyStore],\n () => [SpotifyStore.mPosition, SpotifyStore.isSettingPosition, SpotifyStore.isPlaying]\n );\n\n const [position, setPosition] = useState(storePosition);\n\n // eslint-disable-next-line consistent-return\n useEffect(() => {\n if (isPlaying && !isSettingPosition) {\n setPosition(SpotifyStore.position);\n const interval = setInterval(() => {\n setPosition(p => p + 1000);\n }, 1000);\n\n return () => clearInterval(interval);\n }\n }, [storePosition, isSettingPosition, isPlaying]);\n\n return (\n <div id={cl(\"progress-bar\")}>\n <Forms.FormText\n variant=\"text-xs/medium\"\n className={cl(\"progress-time\") + \" \" + cl(\"time-left\")}\n aria-label=\"Progress\"\n >\n {msToHuman(position)}\n </Forms.FormText>\n <Menu.MenuSliderControl\n minValue={0}\n maxValue={duration}\n value={position}\n onChange={(v: number) => {\n if (isSettingPosition) return;\n setPosition(v);\n seek(v);\n }}\n renderValue={msToHuman}\n />\n <Forms.FormText\n variant=\"text-xs/medium\"\n className={cl(\"progress-time\") + \" \" + cl(\"time-right\")}\n aria-label=\"Total Duration\"\n >\n {msToHuman(duration)}\n </Forms.FormText>\n </div>\n );\n}\n\n\nfunction AlbumContextMenu({ track }: { track: Track; }) {\n const volume = useStateFromStores([SpotifyStore], () => SpotifyStore.volume);\n\n return (\n <Menu.Menu\n navId=\"spotify-album-menu\"\n onClose={() => FluxDispatcher.dispatch({ type: \"CONTEXT_MENU_CLOSE\" })}\n aria-label=\"Spotify Album Menu\"\n >\n <Menu.MenuItem\n key=\"open-album\"\n id=\"open-album\"\n label=\"Open Album\"\n action={() => SpotifyStore.openExternal(`/album/${track.album.id}`)}\n icon={OpenExternalIcon}\n />\n <Menu.MenuItem\n key=\"view-cover\"\n id=\"view-cover\"\n label=\"View Album Cover\"\n // trolley\n action={() => openImageModal(track.album.image.url)}\n icon={ImageIcon}\n />\n <Menu.MenuControlItem\n id=\"spotify-volume\"\n key=\"spotify-volume\"\n label=\"Volume\"\n control={(props, ref) => (\n <Menu.MenuSliderControl\n {...props}\n ref={ref}\n value={volume}\n minValue={0}\n maxValue={100}\n onChange={debounce((v: number) => SpotifyStore.setVolume(v))}\n />\n )}\n />\n </Menu.Menu>\n );\n}\n\nfunction makeLinkProps(name: string, condition: unknown, path: string) {\n if (!condition) return {};\n\n return {\n role: \"link\",\n onClick: () => SpotifyStore.openExternal(path),\n onContextMenu: makeContextMenu(name, path)\n } satisfies React.HTMLAttributes<HTMLElement>;\n}\n\nfunction Info({ track }: { track: Track; }) {\n const img = track?.album?.image;\n\n const [coverExpanded, setCoverExpanded] = useState(false);\n\n const i = (\n <>\n {img && (\n <img\n id={cl(\"album-image\")}\n src={img.url}\n alt=\"Album Image\"\n onClick={() => setCoverExpanded(!coverExpanded)}\n onContextMenu={e => {\n ContextMenuApi.openContextMenu(e, () => <AlbumContextMenu track={track} />);\n }}\n />\n )}\n </>\n );\n\n if (coverExpanded && img) return (\n <div id={cl(\"album-expanded-wrapper\")}>\n {i}\n </div>\n );\n\n return (\n <div id={cl(\"info-wrapper\")}>\n {i}\n <div id={cl(\"titles\")}>\n <Forms.FormText\n variant=\"text-sm/semibold\"\n id={cl(\"song-title\")}\n className={cl(\"ellipoverflow\")}\n title={track.name}\n {...makeLinkProps(\"Song\", track.id, `/track/${track.id}`)}\n >\n {track.name}\n </Forms.FormText>\n {track.artists.some(a => a.name) && (\n <Forms.FormText variant=\"text-sm/normal\" className={cl(\"ellipoverflow\")}>\n by&nbsp;\n {track.artists.map((a, i) => (\n <React.Fragment key={a.name}>\n <span\n className={cl(\"artist\")}\n style={{ fontSize: \"inherit\" }}\n title={a.name}\n {...makeLinkProps(\"Artist\", a.id, `/artist/${a.id}`)}\n >\n {a.name}\n </span>\n {i !== track.artists.length - 1 && <span className={cl(\"comma\")}>{\", \"}</span>}\n </React.Fragment>\n ))}\n </Forms.FormText>\n )}\n {track.album.name && (\n <Forms.FormText variant=\"text-sm/normal\" className={cl(\"ellipoverflow\")}>\n on&nbsp;\n <span\n id={cl(\"album-title\")}\n className={cl(\"album\")}\n style={{ fontSize: \"inherit\" }}\n title={track.album.name}\n {...makeLinkProps(\"Album\", track.album.id, `/album/${track.album.id}`)}\n >\n {track.album.name}\n </span>\n </Forms.FormText>\n )}\n </div>\n </div>\n );\n}\n\nexport function Player() {\n const track = useStateFromStores(\n [SpotifyStore],\n () => SpotifyStore.track,\n null,\n (prev, next) => prev?.id ? (prev.id === next?.id) : prev?.name === next?.name\n );\n\n const device = useStateFromStores(\n [SpotifyStore],\n () => SpotifyStore.device,\n null,\n (prev, next) => prev?.id === next?.id\n );\n\n const isPlaying = useStateFromStores([SpotifyStore], () => SpotifyStore.isPlaying);\n const [shouldHide, setShouldHide] = useState(false);\n\n // Hide player after 5 minutes of inactivity\n // eslint-disable-next-line consistent-return\n React.useEffect(() => {\n setShouldHide(false);\n if (!isPlaying) {\n const timeout = setTimeout(() => setShouldHide(true), 1000 * 60 * 5);\n return () => clearTimeout(timeout);\n }\n }, [isPlaying]);\n\n if (!track || !device?.is_active || shouldHide)\n return null;\n\n return (\n <ErrorBoundary fallback={() => (\n <div className=\"vc-spotify-fallback\">\n <p>Failed to render Spotify Modal :(</p>\n <p >Check the console for errors</p>\n </div>\n )}>\n <div id={cl(\"player\")}>\n <Info track={track} />\n <SeekBar />\n <Controls />\n </div>\n </ErrorBoundary>\n );\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Settings } from \"@api/Settings\";\nimport { disableStyle, enableStyle } from \"@api/Styles\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin, { OptionType } from \"@utils/types\";\n\nimport hoverOnlyStyle from \"./hoverOnly.css?managed\";\nimport { Player } from \"./PlayerComponent\";\n\nfunction toggleHoverControls(value: boolean) {\n (value ? enableStyle : disableStyle)(hoverOnlyStyle);\n}\n\nexport default definePlugin({\n name: \"SpotifyControls\",\n description: \"Adds a Spotify player above the account panel\",\n authors: [Devs.Ven, Devs.afn, Devs.KraXen72],\n options: {\n hoverControls: {\n description: \"Show controls on hover\",\n type: OptionType.BOOLEAN,\n default: false,\n onChange: v => toggleHoverControls(v)\n },\n useSpotifyUris: {\n type: OptionType.BOOLEAN,\n description: \"Open Spotify URIs instead of Spotify URLs. Will only work if you have Spotify installed and might not work on all platforms\",\n default: false\n }\n },\n patches: [\n {\n find: \"showTaglessAccountPanel:\",\n replacement: {\n // return React.createElement(AccountPanel, { ..., showTaglessAccountPanel: blah })\n match: /return ?(.{0,30}\\(.{1,3},\\{[^}]+?,showTaglessAccountPanel:.+?\\}\\))/,\n // return [Player, Panel]\n replace: \"return [$self.renderPlayer(),$1]\"\n }\n },\n {\n find: \".PLAYER_DEVICES\",\n replacement: [{\n // Adds POST and a Marker to the SpotifyAPI (so we can easily find it)\n match: /get:(\\i)\\.bind\\(null,(\\i\\.\\i)\\.get\\)/,\n replace: \"post:$1.bind(null,$2.post),$&\"\n },\n {\n // Spotify Connect API returns status 202 instead of 204 when skipping tracks.\n // Discord rejects 202 which causes the request to send twice. This patch prevents this.\n match: /202===\\i\\.status/,\n replace: \"false\",\n }]\n },\n // Discord doesn't give you the repeat kind, only a boolean\n {\n find: 'repeat:\"off\"!==',\n replacement: {\n match: /repeat:\"off\"!==(.{1,3}),/,\n replace: \"actual_repeat:$1,$&\"\n }\n }\n ],\n start: () => toggleHoverControls(Settings.plugins.SpotifyControls.hoverControls),\n renderPlayer: () => <Player />\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { definePluginSettings } from \"@api/Settings\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin, { OptionType } from \"@utils/types\";\n\nconst settings = definePluginSettings({\n noSpotifyAutoPause: {\n description: \"Disable Spotify auto-pause\",\n type: OptionType.BOOLEAN,\n default: true,\n restartNeeded: true\n },\n keepSpotifyActivityOnIdle: {\n description: \"Keep Spotify activity playing when idling\",\n type: OptionType.BOOLEAN,\n default: false,\n restartNeeded: true\n }\n});\n\nexport default definePlugin({\n name: \"SpotifyCrack\",\n description: \"Free listen along, no auto-pausing in voice chat, and allows activity to continue playing when idling\",\n authors: [Devs.Cyn, Devs.Nuckyz],\n settings,\n\n patches: [\n {\n\n find: 'dispatch({type:\"SPOTIFY_PROFILE_UPDATE\"',\n replacement: {\n match: /SPOTIFY_PROFILE_UPDATE.+?isPremium:(?=\"premium\"===(\\i)\\.body\\.product)/,\n replace: (m, req) => `${m}(${req}.body.product=\"premium\")&&`\n },\n },\n {\n find: '.displayName=\"SpotifyStore\"',\n replacement: [\n {\n predicate: () => settings.store.noSpotifyAutoPause,\n match: /(?<=function \\i\\(\\){)(?=.{0,200}SPOTIFY_AUTO_PAUSED\\))/,\n replace: \"return;\"\n },\n {\n predicate: () => settings.store.keepSpotifyActivityOnIdle,\n match: /(?<=shouldShowActivity\\(\\){.{0,50})&&!\\i\\.\\i\\.isIdle\\(\\)/,\n replace: \"\"\n }\n ]\n }\n ]\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { ApplicationCommandInputType, sendBotMessage } from \"@api/Commands\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\nimport { findByPropsLazy } from \"@webpack\";\nimport { FluxDispatcher, MessageActions } from \"@webpack/common\";\n\ninterface Album {\n id: string;\n image: {\n height: number;\n width: number;\n url: string;\n };\n name: string;\n}\n\ninterface Artist {\n external_urls: {\n spotify: string;\n };\n href: string;\n id: string;\n name: string;\n type: \"artist\" | string;\n uri: string;\n}\n\ninterface Track {\n id: string;\n album: Album;\n artists: Artist[];\n duration: number;\n isLocal: boolean;\n name: string;\n}\n\nconst Spotify = findByPropsLazy(\"getPlayerState\");\nconst PendingReplyStore = findByPropsLazy(\"getPendingReply\");\n\nfunction sendMessage(channelId, message) {\n message = {\n // The following are required to prevent Discord from throwing an error\n invalidEmojis: [],\n tts: false,\n validNonShortcutEmojis: [],\n ...message\n };\n const reply = PendingReplyStore.getPendingReply(channelId);\n MessageActions.sendMessage(channelId, message, void 0, MessageActions.getSendMessageOptionsForReply(reply))\n .then(() => {\n if (reply) {\n FluxDispatcher.dispatch({ type: \"DELETE_PENDING_REPLY\", channelId });\n }\n });\n}\n\nexport default definePlugin({\n name: \"SpotifyShareCommands\",\n description: \"Share your current Spotify track, album or artist via slash command (/track, /album, /artist)\",\n authors: [Devs.katlyn],\n dependencies: [\"CommandsAPI\"],\n commands: [\n {\n name: \"track\",\n description: \"Send your current Spotify track to chat\",\n inputType: ApplicationCommandInputType.BUILT_IN,\n options: [],\n execute: (_, ctx) => {\n const track: Track | null = Spotify.getTrack();\n if (track === null) {\n sendBotMessage(ctx.channel.id, {\n content: \"You're not listening to any music.\"\n });\n return;\n }\n // Note: Due to how Discord handles commands, we need to manually create and send the message\n sendMessage(ctx.channel.id, {\n content: `https://open.spotify.com/track/${track.id}`\n });\n }\n },\n {\n name: \"album\",\n description: \"Send your current Spotify album to chat\",\n inputType: ApplicationCommandInputType.BUILT_IN,\n options: [],\n execute: (_, ctx) => {\n const track: Track | null = Spotify.getTrack();\n if (track === null) {\n sendBotMessage(ctx.channel.id, {\n content: \"You're not listening to any music.\"\n });\n return;\n }\n sendMessage(ctx.channel.id, {\n content: `https://open.spotify.com/album/${track.album.id}`\n });\n }\n },\n {\n name: \"artist\",\n description: \"Send your current Spotify artist to chat\",\n inputType: ApplicationCommandInputType.BUILT_IN,\n options: [],\n execute: (_, ctx) => {\n const track: Track | null = Spotify.getTrack();\n if (track === null) {\n sendBotMessage(ctx.channel.id, {\n content: \"You're not listening to any music.\"\n });\n return;\n }\n sendMessage(ctx.channel.id, {\n content: track.artists[0].external_urls.spotify\n });\n }\n }\n ]\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport ErrorBoundary from \"@components/ErrorBoundary\";\nimport { Flex } from \"@components/Flex\";\nimport { findByPropsLazy } from \"@webpack\";\nimport { Forms, React } from \"@webpack/common\";\n\ninterface AppStartPerformance {\n prefix: string;\n logs: Log[];\n logGroups: LogGroup[];\n endTime_: number;\n isTracing_: boolean;\n}\n\ninterface LogGroup {\n index: number;\n timestamp: number;\n logs: Log[];\n nativeLogs: any[];\n serverTrace: string;\n}\n\ninterface Log {\n emoji: string;\n prefix: string;\n log: string;\n timestamp?: number;\n delta?: number;\n}\n\nconst AppStartPerformance = findByPropsLazy(\"markWithDelta\", \"markAndLog\", \"markAt\") as AppStartPerformance;\n\ninterface TimerItemProps extends Log {\n instance: {\n sinceStart: number;\n sinceLast: number;\n };\n}\n\nfunction TimerItem({ emoji, prefix, log, delta, instance }: TimerItemProps) {\n return (\n <React.Fragment>\n <span>{instance.sinceStart.toFixed(3)}s</span>\n <span>{instance.sinceLast.toFixed(3)}s</span>\n <span>{delta?.toFixed(0) ?? \"\"}</span>\n <span><pre>{emoji} {prefix ?? \" \"}{log}</pre></span>\n </React.Fragment>\n );\n}\n\ninterface TimingSectionProps {\n title: string;\n logs: Log[];\n traceEnd?: number;\n}\n\nfunction TimingSection({ title, logs, traceEnd }: TimingSectionProps) {\n const startTime = logs.find(l => l.timestamp)?.timestamp ?? 0;\n\n let lastTimestamp = startTime;\n const timings = logs.map(log => {\n // Get last log entry with valid timestamp\n const timestamp = log.timestamp ?? lastTimestamp;\n\n const sinceStart = (timestamp - startTime) / 1000;\n const sinceLast = (timestamp - lastTimestamp) / 1000;\n\n lastTimestamp = timestamp;\n\n return { sinceStart, sinceLast };\n });\n\n return (\n <Forms.FormSection title={title} tag=\"h1\">\n <code>\n {traceEnd && (\n <div style={{ color: \"var(--header-primary)\", marginBottom: 5, userSelect: \"text\" }}>\n Trace ended at: {(new Date(traceEnd)).toTimeString()}\n </div>\n )}\n <div style={{ color: \"var(--header-primary)\", display: \"grid\", gridTemplateColumns: \"repeat(3, auto) 1fr\", gap: \"2px 10px\", userSelect: \"text\" }}>\n <span>Start</span>\n <span>Interval</span>\n <span>Delta</span>\n <span style={{ marginBottom: 5 }}>Event</span>\n {AppStartPerformance.logs.map((log, i) => (\n <TimerItem key={i} {...log} instance={timings[i]} />\n ))}\n </div>\n </code>\n </Forms.FormSection>\n );\n}\n\ninterface ServerTraceProps {\n trace: string;\n}\n\nfunction ServerTrace({ trace }: ServerTraceProps) {\n const lines = trace.split(\"\\n\");\n\n return (\n <Forms.FormSection title=\"Server Trace\" tag=\"h2\">\n <code>\n <Flex flexDirection=\"column\" style={{ color: \"var(--header-primary)\", gap: 5, userSelect: \"text\" }}>\n {lines.map(line => (\n <span>{line}</span>\n ))}\n </Flex>\n </code>\n </Forms.FormSection>\n );\n}\n\nfunction StartupTimingPage() {\n if (!AppStartPerformance?.logs) return <div>Loading...</div>;\n\n const serverTrace = AppStartPerformance.logGroups.find(g => g.serverTrace)?.serverTrace;\n\n return (\n <React.Fragment>\n <TimingSection\n title=\"Startup Timings\"\n logs={AppStartPerformance.logs}\n traceEnd={AppStartPerformance.endTime_}\n />\n {/* Lazy Divider */}\n <div style={{ marginTop: 5 }}>&nbsp;</div>\n {serverTrace && <ServerTrace trace={serverTrace} />}\n </React.Fragment>\n );\n}\n\nexport default ErrorBoundary.wrap(StartupTimingPage);\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Devs } from \"@utils/constants\";\nimport { LazyComponent } from \"@utils/react\";\nimport definePlugin from \"@utils/types\";\n\nexport default definePlugin({\n name: \"StartupTimings\",\n description: \"Adds Startup Timings to the Settings menu\",\n authors: [Devs.Megu],\n patches: [{\n find: \"UserSettingsSections.PAYMENT_FLOW_MODAL_TEST_PAGE,\",\n replacement: {\n match: /{section:\\i\\.UserSettingsSections\\.PAYMENT_FLOW_MODAL_TEST_PAGE/,\n replace: '{section:\"StartupTimings\",label:\"Startup Timings\",element:$self.StartupTimingPage},$&'\n }\n }],\n StartupTimingPage: LazyComponent(() => require(\"./StartupTimingPage\").default)\n});\n", "/*\n * Vencord, a Discord client mod\n * Copyright (c) 2023 Vendicated, ant0n, FieryFlames and contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport { definePluginSettings } from \"@api/Settings\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin, { OptionType } from \"@utils/types\";\n\nexport const settings = definePluginSettings({\n superReactByDefault: {\n type: OptionType.BOOLEAN,\n description: \"Reaction picker will default to Super Reactions\",\n default: true,\n },\n unlimitedSuperReactionPlaying: {\n type: OptionType.BOOLEAN,\n description: \"Remove the limit on Super Reactions playing at once\",\n default: false,\n },\n\n superReactionPlayingLimit: {\n description: \"Max Super Reactions to play at once\",\n type: OptionType.SLIDER,\n default: 20,\n markers: [5, 10, 20, 40, 60, 80, 100],\n stickToMarkers: true,\n },\n}, {\n superReactionPlayingLimit: {\n disabled() { return this.store.unlimitedSuperReactionPlaying; },\n }\n});\n\nexport default definePlugin({\n name: \"SuperReactionTweaks\",\n description: \"Customize the limit of Super Reactions playing at once, and super react by default\",\n authors: [Devs.FieryFlames, Devs.ant0n],\n patches: [\n {\n find: \",BURST_REACTION_EFFECT_PLAY\",\n replacement: {\n match: /(?<=BURST_REACTION_EFFECT_PLAY:\\i=>{.{50,100})(\\i\\(\\i,\\i\\))>=\\d+/,\n replace: \"!$self.shouldPlayBurstReaction($1)\"\n }\n },\n {\n find: \".trackEmojiSearchEmpty,200\",\n replacement: {\n match: /(\\.trackEmojiSearchEmpty,200(?=.+?isBurstReaction:(\\i).+?(\\i===\\i\\.EmojiIntention.REACTION)).+?\\[\\2,\\i\\]=\\i\\.useState\\().+?\\)/,\n replace: (_, rest, isBurstReactionVariable, isReactionIntention) => `${rest}$self.settings.store.superReactByDefault&&${isReactionIntention})`\n }\n }\n ],\n settings,\n\n shouldPlayBurstReaction(playingCount: number) {\n if (settings.store.unlimitedSuperReactionPlaying) return true;\n if (playingCount <= settings.store.superReactionPlayingLimit) return true;\n return false;\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { DataStore } from \"@api/index\";\nimport { addPreSendListener, removePreSendListener } from \"@api/MessageEvents\";\nimport { definePluginSettings } from \"@api/Settings\";\nimport { Flex } from \"@components/Flex\";\nimport { DeleteIcon } from \"@components/Icons\";\nimport { Devs } from \"@utils/constants\";\nimport { Logger } from \"@utils/Logger\";\nimport { useForceUpdater } from \"@utils/react\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { Button, Forms, React, TextInput, useState } from \"@webpack/common\";\n\nconst STRING_RULES_KEY = \"TextReplace_rulesString\";\nconst REGEX_RULES_KEY = \"TextReplace_rulesRegex\";\n\ntype Rule = Record<\"find\" | \"replace\" | \"onlyIfIncludes\", string>;\n\ninterface TextReplaceProps {\n title: string;\n rulesArray: Rule[];\n rulesKey: string;\n update: () => void;\n}\n\nconst makeEmptyRule: () => Rule = () => ({\n find: \"\",\n replace: \"\",\n onlyIfIncludes: \"\"\n});\nconst makeEmptyRuleArray = () => [makeEmptyRule()];\n\nlet stringRules = makeEmptyRuleArray();\nlet regexRules = makeEmptyRuleArray();\n\nconst settings = definePluginSettings({\n replace: {\n type: OptionType.COMPONENT,\n description: \"\",\n component: () => {\n const update = useForceUpdater();\n return (\n <>\n <TextReplace\n title=\"Using String\"\n rulesArray={stringRules}\n rulesKey={STRING_RULES_KEY}\n update={update}\n />\n <TextReplace\n title=\"Using Regex\"\n rulesArray={regexRules}\n rulesKey={REGEX_RULES_KEY}\n update={update}\n />\n <TextReplaceTesting />\n </>\n );\n }\n },\n});\n\nfunction stringToRegex(str: string) {\n const match = str.match(/^(\\/)?(.+?)(?:\\/([gimsuy]*))?$/); // Regex to match regex\n return match\n ? new RegExp(\n match[2], // Pattern\n match[3]\n ?.split(\"\") // Remove duplicate flags\n .filter((char, pos, flagArr) => flagArr.indexOf(char) === pos)\n .join(\"\")\n ?? \"g\"\n )\n : new RegExp(str); // Not a regex, return string\n}\n\nfunction renderFindError(find: string) {\n try {\n stringToRegex(find);\n return null;\n } catch (e) {\n return (\n <span style={{ color: \"var(--text-danger)\" }}>\n {String(e)}\n </span>\n );\n }\n}\n\nfunction Input({ initialValue, onChange, placeholder }: {\n placeholder: string;\n initialValue: string;\n onChange(value: string): void;\n}) {\n const [value, setValue] = useState(initialValue);\n return (\n <TextInput\n placeholder={placeholder}\n value={value}\n onChange={setValue}\n spellCheck={false}\n onBlur={() => value !== initialValue && onChange(value)}\n />\n );\n}\n\nfunction TextReplace({ title, rulesArray, rulesKey, update }: TextReplaceProps) {\n const isRegexRules = title === \"Using Regex\";\n\n async function onClickRemove(index: number) {\n if (index === rulesArray.length - 1) return;\n rulesArray.splice(index, 1);\n\n await DataStore.set(rulesKey, rulesArray);\n update();\n }\n\n async function onChange(e: string, index: number, key: string) {\n if (index === rulesArray.length - 1)\n rulesArray.push(makeEmptyRule());\n\n rulesArray[index][key] = e;\n\n if (rulesArray[index].find === \"\" && rulesArray[index].replace === \"\" && rulesArray[index].onlyIfIncludes === \"\" && index !== rulesArray.length - 1)\n rulesArray.splice(index, 1);\n\n await DataStore.set(rulesKey, rulesArray);\n update();\n }\n\n return (\n <>\n <Forms.FormTitle tag=\"h4\">{title}</Forms.FormTitle>\n <Flex flexDirection=\"column\" style={{ gap: \"0.5em\" }}>\n {\n rulesArray.map((rule, index) =>\n <React.Fragment key={`${rule.find}-${index}`}>\n <Flex flexDirection=\"row\" style={{ gap: 0 }}>\n <Flex flexDirection=\"row\" style={{ flexGrow: 1, gap: \"0.5em\" }}>\n <Input\n placeholder=\"Find\"\n initialValue={rule.find}\n onChange={e => onChange(e, index, \"find\")}\n />\n <Input\n placeholder=\"Replace\"\n initialValue={rule.replace}\n onChange={e => onChange(e, index, \"replace\")}\n />\n <Input\n placeholder=\"Only if includes\"\n initialValue={rule.onlyIfIncludes}\n onChange={e => onChange(e, index, \"onlyIfIncludes\")}\n />\n </Flex>\n <Button\n size={Button.Sizes.MIN}\n onClick={() => onClickRemove(index)}\n style={{\n background: \"none\",\n color: \"var(--status-danger)\",\n ...(index === rulesArray.length - 1\n ? {\n visibility: \"hidden\",\n pointerEvents: \"none\"\n }\n : {}\n )\n }}\n >\n <DeleteIcon />\n </Button>\n </Flex>\n {isRegexRules && renderFindError(rule.find)}\n </React.Fragment>\n )\n }\n </Flex>\n </>\n );\n}\n\nfunction TextReplaceTesting() {\n const [value, setValue] = useState(\"\");\n return (\n <>\n <Forms.FormTitle tag=\"h4\">Test Rules</Forms.FormTitle>\n <TextInput placeholder=\"Type a message\" onChange={setValue} />\n <TextInput placeholder=\"Message with rules applied\" editable={false} value={applyRules(value)} />\n </>\n );\n}\n\nfunction applyRules(content: string): string {\n if (content.length === 0)\n return content;\n\n if (stringRules) {\n for (const rule of stringRules) {\n if (!rule.find) continue;\n if (rule.onlyIfIncludes && !content.includes(rule.onlyIfIncludes)) continue;\n\n content = ` ${content} `.replaceAll(rule.find, rule.replace.replaceAll(\"\\\\n\", \"\\n\")).replace(/^\\s|\\s$/g, \"\");\n }\n }\n\n if (regexRules) {\n for (const rule of regexRules) {\n if (!rule.find) continue;\n if (rule.onlyIfIncludes && !content.includes(rule.onlyIfIncludes)) continue;\n\n try {\n const regex = stringToRegex(rule.find);\n content = content.replace(regex, rule.replace.replaceAll(\"\\\\n\", \"\\n\"));\n } catch (e) {\n new Logger(\"TextReplace\").error(`Invalid regex: ${rule.find}`);\n }\n }\n }\n\n content = content.trim();\n return content;\n}\n\nconst TEXT_REPLACE_RULES_CHANNEL_ID = \"1102784112584040479\";\n\nexport default definePlugin({\n name: \"TextReplace\",\n description: \"Replace text in your messages. You can find pre-made rules in the #textreplace-rules channel in Vencord's Server\",\n authors: [Devs.AutumnVN, Devs.TheKodeToad],\n dependencies: [\"MessageEventsAPI\"],\n\n settings,\n\n async start() {\n stringRules = await DataStore.get(STRING_RULES_KEY) ?? makeEmptyRuleArray();\n regexRules = await DataStore.get(REGEX_RULES_KEY) ?? makeEmptyRuleArray();\n\n this.preSend = addPreSendListener((channelId, msg) => {\n // Channel used for sharing rules, applying rules here would be messy\n if (channelId === TEXT_REPLACE_RULES_CHANNEL_ID) return;\n msg.content = applyRules(msg.content);\n });\n },\n\n stop() {\n removePreSendListener(this.preSend);\n }\n});\n", "/*\n * Vencord, a Discord client mod\n * Copyright (c) 2023 Vendicated and contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\nimport { UserStore } from \"@webpack/common\";\nimport { Message } from \"discord-types/general\";\n\nexport default definePlugin({\n name: \"ThemeAttributes\",\n description: \"Adds data attributes to various elements for theming purposes\",\n authors: [Devs.Ven],\n\n patches: [\n // Add data-tab-id to all tab bar items\n // This for examples applies to the User and Server settings sidebars\n {\n find: \".tabBarRef\",\n replacement: {\n match: /style:this\\.getStyle\\(\\),role:\"tab\"/,\n replace: \"$&,'data-tab-id':this.props.id\"\n }\n },\n\n // Add data-author-id and data-is-self to all messages\n {\n find: \".messageListItem\",\n replacement: {\n match: /\\.messageListItem(?=,\"aria)/,\n replace: \"$&,...$self.getMessageProps(arguments[0])\"\n }\n }\n ],\n\n getMessageProps(props: { message: Message; }) {\n const authorId = props.message?.author?.id;\n return {\n \"data-author-id\": authorId,\n \"data-is-self\": authorId && authorId === UserStore.getCurrentUser()?.id\n };\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\n\nexport default definePlugin({\n name: \"TimeBarAllActivities\",\n description: \"Adds the Spotify time bar to all activities if they have start and end timestamps\",\n authors: [Devs.obscurity],\n patches: [\n {\n find: \"}renderTimeBar(\",\n replacement: {\n match: /renderTimeBar\\((.{1,3})\\){.{0,50}?let/,\n replace: \"renderTimeBar($1){let\"\n }\n }\n ],\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { definePluginSettings } from \"@api/Settings\";\nimport { OptionType } from \"@utils/types\";\n\nexport const settings = definePluginSettings({\n receivedInput: {\n type: OptionType.STRING,\n description: \"Input language for received messages\",\n default: \"auto\",\n hidden: true\n },\n receivedOutput: {\n type: OptionType.STRING,\n description: \"Output language for received messages\",\n default: \"en\",\n hidden: true\n },\n sentInput: {\n type: OptionType.STRING,\n description: \"Input language for sent messages\",\n default: \"auto\",\n hidden: true\n },\n sentOutput: {\n type: OptionType.STRING,\n description: \"Output language for sent messages\",\n default: \"en\",\n hidden: true\n },\n autoTranslate: {\n type: OptionType.BOOLEAN,\n description: \"Automatically translate your messages before sending. You can also shift/right click the translate button to toggle this\",\n default: false\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\n/*\nTo generate:\n- Visit https://translate.google.com/?sl=auto&tl=en&op=translate\n- Open Language dropdown\n- Open Devtools and use the element picker to pick the root of the language picker\n- Right click on the element in devtools and click \"Store as global variable\"\n\ncopy(Object.fromEntries(\n Array.from(\n temp1.querySelectorAll(\"[data-language-code]\"),\n e => [e.dataset.languageCode, e.children[1].textContent]\n ).sort((a, b) => a[1] === \"Detect language\" ? -1 : b[1] === \"Detect language\" ? 1 : a[1].localeCompare(b[1]))\n))\n*/\n\nexport type Language = keyof typeof Languages;\n\nexport const Languages = {\n \"auto\": \"Detect language\",\n \"af\": \"Afrikaans\",\n \"sq\": \"Albanian\",\n \"am\": \"Amharic\",\n \"ar\": \"Arabic\",\n \"hy\": \"Armenian\",\n \"as\": \"Assamese\",\n \"ay\": \"Aymara\",\n \"az\": \"Azerbaijani\",\n \"bm\": \"Bambara\",\n \"eu\": \"Basque\",\n \"be\": \"Belarusian\",\n \"bn\": \"Bengali\",\n \"bho\": \"Bhojpuri\",\n \"bs\": \"Bosnian\",\n \"bg\": \"Bulgarian\",\n \"ca\": \"Catalan\",\n \"ceb\": \"Cebuano\",\n \"ny\": \"Chichewa\",\n \"zh-CN\": \"Chinese (Simplified)\",\n \"zh-TW\": \"Chinese (Traditional)\",\n \"co\": \"Corsican\",\n \"hr\": \"Croatian\",\n \"cs\": \"Czech\",\n \"da\": \"Danish\",\n \"dv\": \"Dhivehi\",\n \"doi\": \"Dogri\",\n \"nl\": \"Dutch\",\n \"en\": \"English\",\n \"eo\": \"Esperanto\",\n \"et\": \"Estonian\",\n \"ee\": \"Ewe\",\n \"tl\": \"Filipino\",\n \"fi\": \"Finnish\",\n \"fr\": \"French\",\n \"fy\": \"Frisian\",\n \"gl\": \"Galician\",\n \"ka\": \"Georgian\",\n \"de\": \"German\",\n \"el\": \"Greek\",\n \"gn\": \"Guarani\",\n \"gu\": \"Gujarati\",\n \"ht\": \"Haitian Creole\",\n \"ha\": \"Hausa\",\n \"haw\": \"Hawaiian\",\n \"iw\": \"Hebrew\",\n \"hi\": \"Hindi\",\n \"hmn\": \"Hmong\",\n \"hu\": \"Hungarian\",\n \"is\": \"Icelandic\",\n \"ig\": \"Igbo\",\n \"ilo\": \"Ilocano\",\n \"id\": \"Indonesian\",\n \"ga\": \"Irish\",\n \"it\": \"Italian\",\n \"ja\": \"Japanese\",\n \"jw\": \"Javanese\",\n \"kn\": \"Kannada\",\n \"kk\": \"Kazakh\",\n \"km\": \"Khmer\",\n \"rw\": \"Kinyarwanda\",\n \"gom\": \"Konkani\",\n \"ko\": \"Korean\",\n \"kri\": \"Krio\",\n \"ku\": \"Kurdish (Kurmanji)\",\n \"ckb\": \"Kurdish (Sorani)\",\n \"ky\": \"Kyrgyz\",\n \"lo\": \"Lao\",\n \"la\": \"Latin\",\n \"lv\": \"Latvian\",\n \"ln\": \"Lingala\",\n \"lt\": \"Lithuanian\",\n \"lg\": \"Luganda\",\n \"lb\": \"Luxembourgish\",\n \"mk\": \"Macedonian\",\n \"mai\": \"Maithili\",\n \"mg\": \"Malagasy\",\n \"ms\": \"Malay\",\n \"ml\": \"Malayalam\",\n \"mt\": \"Maltese\",\n \"mi\": \"Maori\",\n \"mr\": \"Marathi\",\n \"mni-Mtei\": \"Meiteilon (Manipuri)\",\n \"lus\": \"Mizo\",\n \"mn\": \"Mongolian\",\n \"my\": \"Myanmar (Burmese)\",\n \"ne\": \"Nepali\",\n \"no\": \"Norwegian\",\n \"or\": \"Odia (Oriya)\",\n \"om\": \"Oromo\",\n \"ps\": \"Pashto\",\n \"fa\": \"Persian\",\n \"pl\": \"Polish\",\n \"pt\": \"Portuguese\",\n \"pa\": \"Punjabi\",\n \"qu\": \"Quechua\",\n \"ro\": \"Romanian\",\n \"ru\": \"Russian\",\n \"sm\": \"Samoan\",\n \"sa\": \"Sanskrit\",\n \"gd\": \"Scots Gaelic\",\n \"nso\": \"Sepedi\",\n \"sr\": \"Serbian\",\n \"st\": \"Sesotho\",\n \"sn\": \"Shona\",\n \"sd\": \"Sindhi\",\n \"si\": \"Sinhala\",\n \"sk\": \"Slovak\",\n \"sl\": \"Slovenian\",\n \"so\": \"Somali\",\n \"es\": \"Spanish\",\n \"su\": \"Sundanese\",\n \"sw\": \"Swahili\",\n \"sv\": \"Swedish\",\n \"tg\": \"Tajik\",\n \"ta\": \"Tamil\",\n \"tt\": \"Tatar\",\n \"te\": \"Telugu\",\n \"th\": \"Thai\",\n \"ti\": \"Tigrinya\",\n \"ts\": \"Tsonga\",\n \"tr\": \"Turkish\",\n \"tk\": \"Turkmen\",\n \"ak\": \"Twi\",\n \"uk\": \"Ukrainian\",\n \"ur\": \"Urdu\",\n \"ug\": \"Uyghur\",\n \"uz\": \"Uzbek\",\n \"vi\": \"Vietnamese\",\n \"cy\": \"Welsh\",\n \"xh\": \"Xhosa\",\n \"yi\": \"Yiddish\",\n \"yo\": \"Yoruba\",\n \"zu\": \"Zulu\"\n} as const;\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { classNameFactory } from \"@api/Styles\";\n\nimport { settings } from \"./settings\";\n\nexport const cl = classNameFactory(\"vc-trans-\");\n\ninterface TranslationData {\n src: string;\n sentences: {\n // \uD83C\uDFF3\uFE0F\u200D\u26A7\uFE0F\n trans: string;\n }[];\n}\n\nexport interface TranslationValue {\n src: string;\n text: string;\n}\n\nexport async function translate(kind: \"received\" | \"sent\", text: string): Promise<TranslationValue> {\n const sourceLang = settings.store[kind + \"Input\"];\n const targetLang = settings.store[kind + \"Output\"];\n\n const url = \"https://translate.googleapis.com/translate_a/single?\" + new URLSearchParams({\n // see https://stackoverflow.com/a/29537590 for more params\n // holy shidd nvidia\n client: \"gtx\",\n // source language\n sl: sourceLang,\n // target language\n tl: targetLang,\n // what to return, t = translation probably\n dt: \"t\",\n // Send json object response instead of weird array\n dj: \"1\",\n source: \"input\",\n // query, duh\n q: text\n });\n\n const res = await fetch(url);\n if (!res.ok)\n throw new Error(\n `Failed to translate \"${text}\" (${sourceLang} -> ${targetLang})`\n + `\\n${res.status} ${res.statusText}`\n );\n\n const { src, sentences }: TranslationData = await res.json();\n\n return {\n src,\n text: sentences.\n map(s => s?.trans).\n filter(Boolean).\n join(\"\")\n };\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Margins } from \"@utils/margins\";\nimport { ModalCloseButton, ModalContent, ModalHeader, ModalProps, ModalRoot } from \"@utils/modal\";\nimport { Forms, SearchableSelect, Switch, useMemo } from \"@webpack/common\";\n\nimport { Languages } from \"./languages\";\nimport { settings } from \"./settings\";\nimport { cl } from \"./utils\";\n\nconst LanguageSettingKeys = [\"receivedInput\", \"receivedOutput\", \"sentInput\", \"sentOutput\"] as const;\n\nfunction LanguageSelect({ settingsKey, includeAuto }: { settingsKey: typeof LanguageSettingKeys[number]; includeAuto: boolean; }) {\n const currentValue = settings.use([settingsKey])[settingsKey];\n\n const options = useMemo(\n () => {\n const options = Object.entries(Languages).map(([value, label]) => ({ value, label }));\n if (!includeAuto)\n options.shift();\n\n return options;\n }, []\n );\n\n return (\n <section className={Margins.bottom16}>\n <Forms.FormTitle tag=\"h3\">\n {settings.def[settingsKey].description}\n </Forms.FormTitle>\n\n <SearchableSelect\n options={options}\n value={options.find(o => o.value === currentValue)}\n placeholder={\"Select a language\"}\n maxVisibleItems={5}\n closeOnSelect={true}\n onChange={v => settings.store[settingsKey] = v}\n />\n </section>\n );\n}\n\nfunction AutoTranslateToggle() {\n const value = settings.use([\"autoTranslate\"]).autoTranslate;\n\n return (\n <Switch\n value={value}\n onChange={v => settings.store.autoTranslate = v}\n note={settings.def.autoTranslate.description}\n hideBorder\n >\n Auto Translate\n </Switch>\n );\n}\n\n\nexport function TranslateModal({ rootProps }: { rootProps: ModalProps; }) {\n return (\n <ModalRoot {...rootProps}>\n <ModalHeader className={cl(\"modal-header\")}>\n <Forms.FormTitle tag=\"h2\">\n Translate\n </Forms.FormTitle>\n <ModalCloseButton onClick={rootProps.onClose} />\n </ModalHeader>\n\n <ModalContent className={cl(\"modal-content\")}>\n {LanguageSettingKeys.map(s => (\n <LanguageSelect\n key={s}\n settingsKey={s}\n includeAuto={s.endsWith(\"Input\")}\n />\n ))}\n\n <Forms.FormDivider className={Margins.bottom16} />\n\n <AutoTranslateToggle />\n </ModalContent>\n </ModalRoot>\n );\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { classes } from \"@utils/misc\";\nimport { openModal } from \"@utils/modal\";\nimport { Button, ButtonLooks, ButtonWrapperClasses, Tooltip } from \"@webpack/common\";\n\nimport { settings } from \"./settings\";\nimport { TranslateModal } from \"./TranslateModal\";\nimport { cl } from \"./utils\";\n\nexport function TranslateIcon({ height = 24, width = 24, className }: { height?: number; width?: number; className?: string; }) {\n return (\n <svg\n viewBox=\"0 96 960 960\"\n height={height}\n width={width}\n className={classes(cl(\"icon\"), className)}\n >\n <path fill=\"currentColor\" d=\"m475 976 181-480h82l186 480h-87l-41-126H604l-47 126h-82Zm151-196h142l-70-194h-2l-70 194Zm-466 76-55-55 204-204q-38-44-67.5-88.5T190 416h87q17 33 37.5 62.5T361 539q45-47 75-97.5T487 336H40v-80h280v-80h80v80h280v80H567q-22 69-58.5 135.5T419 598l98 99-30 81-127-122-200 200Z\" />\n </svg>\n );\n}\n\nexport function TranslateChatBarIcon({ slateProps }: { slateProps: { type: { analyticsName: string; }; }; }) {\n const { autoTranslate } = settings.use([\"autoTranslate\"]);\n\n if (slateProps.type.analyticsName !== \"normal\")\n return null;\n\n const toggle = () => settings.store.autoTranslate = !autoTranslate;\n\n return (\n <Tooltip text=\"Open Translate Modal\">\n {({ onMouseEnter, onMouseLeave }) => (\n <div style={{ display: \"flex\" }}>\n <Button\n aria-haspopup=\"dialog\"\n aria-label=\"Open Translate Modal\"\n size=\"\"\n look={ButtonLooks.BLANK}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n innerClassName={ButtonWrapperClasses.button}\n onClick={e => {\n if (e.shiftKey) return toggle();\n\n openModal(props => (\n <TranslateModal rootProps={props} />\n ));\n }}\n onContextMenu={() => toggle()}\n style={{ padding: \"0 4px\" }}\n >\n <div className={ButtonWrapperClasses.buttonWrapper}>\n <TranslateIcon className={cl({ \"auto-translate\": autoTranslate })} />\n </div>\n </Button>\n </div>\n )}\n </Tooltip>\n );\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Parser, useEffect, useState } from \"@webpack/common\";\nimport { Message } from \"discord-types/general\";\n\nimport { Languages } from \"./languages\";\nimport { TranslateIcon } from \"./TranslateIcon\";\nimport { cl, TranslationValue } from \"./utils\";\n\nconst TranslationSetters = new Map<string, (v: TranslationValue) => void>();\n\nexport function handleTranslate(messageId: string, data: TranslationValue) {\n TranslationSetters.get(messageId)!(data);\n}\n\nfunction Dismiss({ onDismiss }: { onDismiss: () => void; }) {\n return (\n <button\n onClick={onDismiss}\n className={cl(\"dismiss\")}\n >\n Dismiss\n </button>\n );\n}\n\nexport function TranslationAccessory({ message }: { message: Message; }) {\n const [translation, setTranslation] = useState<TranslationValue>();\n\n useEffect(() => {\n // Ignore MessageLinkEmbeds messages\n if ((message as any).vencordEmbeddedBy) return;\n\n TranslationSetters.set(message.id, setTranslation);\n\n return () => void TranslationSetters.delete(message.id);\n }, []);\n\n if (!translation) return null;\n\n return (\n <span className={cl(\"accessory\")}>\n <TranslateIcon width={16} height={16} />\n {Parser.parse(translation.text)}\n {\" \"}\n (translated from {Languages[translation.src] ?? translation.src} - <Dismiss onDismiss={() => setTranslation(undefined)} />)\n </span>\n );\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport \"./styles.css\";\n\nimport { addContextMenuPatch, findGroupChildrenByChildId, NavContextMenuPatchCallback, removeContextMenuPatch } from \"@api/ContextMenu\";\nimport { addAccessory, removeAccessory } from \"@api/MessageAccessories\";\nimport { addPreSendListener, removePreSendListener } from \"@api/MessageEvents\";\nimport { addButton, removeButton } from \"@api/MessagePopover\";\nimport ErrorBoundary from \"@components/ErrorBoundary\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\nimport { ChannelStore, Menu } from \"@webpack/common\";\n\nimport { settings } from \"./settings\";\nimport { TranslateChatBarIcon, TranslateIcon } from \"./TranslateIcon\";\nimport { handleTranslate, TranslationAccessory } from \"./TranslationAccessory\";\nimport { translate } from \"./utils\";\n\nconst messageCtxPatch: NavContextMenuPatchCallback = (children, { message }) => () => {\n if (!message.content) return;\n\n const group = findGroupChildrenByChildId(\"copy-text\", children);\n if (!group) return;\n\n group.splice(group.findIndex(c => c?.props?.id === \"copy-text\") + 1, 0, (\n <Menu.MenuItem\n id=\"vc-trans\"\n label=\"Translate\"\n icon={TranslateIcon}\n action={async () => {\n const trans = await translate(\"received\", message.content);\n handleTranslate(message.id, trans);\n }}\n />\n ));\n};\n\nexport default definePlugin({\n name: \"Translate\",\n description: \"Translate messages with Google Translate\",\n authors: [Devs.Ven],\n dependencies: [\"MessageAccessoriesAPI\", \"MessagePopoverAPI\", \"MessageEventsAPI\"],\n settings,\n // not used, just here in case some other plugin wants it or w/e\n translate,\n\n patches: [\n {\n find: \"ChannelTextAreaButtons\",\n replacement: {\n match: /(\\i)\\.push.{1,30}disabled:(\\i),.{1,20}\\},\"gift\"\\)\\)/,\n replace: \"$&,(()=>{try{$2||$1.push($self.chatBarIcon(arguments[0]))}catch{}})()\",\n }\n },\n ],\n\n start() {\n addAccessory(\"vc-translation\", props => <TranslationAccessory message={props.message} />);\n\n addContextMenuPatch(\"message\", messageCtxPatch);\n\n addButton(\"vc-translate\", message => {\n if (!message.content) return null;\n\n return {\n label: \"Translate\",\n icon: TranslateIcon,\n message,\n channel: ChannelStore.getChannel(message.channel_id),\n onClick: async () => {\n const trans = await translate(\"received\", message.content);\n handleTranslate(message.id, trans);\n }\n };\n });\n\n this.preSend = addPreSendListener(async (_, message) => {\n if (!settings.store.autoTranslate) return;\n if (!message.content) return;\n\n message.content = (await translate(\"sent\", message.content)).text;\n });\n },\n\n stop() {\n removePreSendListener(this.preSend);\n removeContextMenuPatch(\"message\", messageCtxPatch);\n removeButton(\"vc-translate\");\n removeAccessory(\"vc-translation\");\n },\n\n chatBarIcon: (slateProps: any) => (\n <ErrorBoundary noop>\n <TranslateChatBarIcon slateProps={slateProps} />\n </ErrorBoundary>\n )\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { definePluginSettings } from \"@api/Settings\";\nimport ErrorBoundary from \"@components/ErrorBoundary\";\nimport { Devs } from \"@utils/constants\";\nimport { openUserProfile } from \"@utils/discord\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { Avatar, GuildMemberStore, React, RelationshipStore } from \"@webpack/common\";\nimport { User } from \"discord-types/general\";\n\nconst settings = definePluginSettings({\n showAvatars: {\n type: OptionType.BOOLEAN,\n default: true,\n description: \"Show avatars in the typing indicator\"\n },\n showRoleColors: {\n type: OptionType.BOOLEAN,\n default: true,\n description: \"Show role colors in the typing indicator\"\n },\n alternativeFormatting: {\n type: OptionType.BOOLEAN,\n default: true,\n description: \"Show a more useful message when several users are typing\"\n }\n});\n\nexport function buildSeveralUsers({ a, b, count }: { a: string, b: string, count: number; }) {\n return [\n <strong key=\"0\">{a}</strong>,\n \", \",\n <strong key=\"1\">{b}</strong>,\n `, and ${count} others are typing...`\n ];\n}\n\ninterface Props {\n user: User;\n guildId: string;\n}\n\nconst TypingUser = ErrorBoundary.wrap(function ({ user, guildId }: Props) {\n return (\n <strong\n role=\"button\"\n onClick={() => {\n openUserProfile(user.id);\n }}\n style={{\n display: \"grid\",\n gridAutoFlow: \"column\",\n gap: \"4px\",\n color: settings.store.showRoleColors ? GuildMemberStore.getMember(guildId, user.id)?.colorString : undefined,\n cursor: \"pointer\"\n }}\n >\n {settings.store.showAvatars && (\n <div style={{ marginTop: \"4px\" }}>\n <Avatar\n size=\"SIZE_16\"\n src={user.getAvatarURL(guildId, 128)} />\n </div>\n )}\n {GuildMemberStore.getNick(guildId!, user.id)\n || (!guildId && RelationshipStore.getNickname(user.id))\n || (user as any).globalName\n || user.username\n }\n </strong>\n );\n}, { noop: true });\n\nexport default definePlugin({\n name: \"TypingTweaks\",\n description: \"Show avatars and role colours in the typing indicator\",\n authors: [Devs.zt],\n patches: [\n // Style the indicator and add function call to modify the children before rendering\n {\n find: \"getCooldownTextStyle\",\n replacement: {\n match: /(?<=children:\\[(\\i)\\.length>0.{0,200}?\"aria-atomic\":!0,children:)\\i/,\n replace: \"$self.mutateChildren(this.props, $1, $&), style: $self.TYPING_TEXT_STYLE\"\n }\n },\n // Changes the indicator to keep the user object when creating the list of typing users\n {\n find: \"getCooldownTextStyle\",\n replacement: {\n match: /(?<=map\\(\\i=>)\\i\\.\\i\\.getName\\(\\i,this\\.props\\.channel\\.id,(\\i)\\)/,\n replace: \"$1\"\n }\n },\n // Adds the alternative formatting for several users typing\n {\n find: \"getCooldownTextStyle\",\n replacement: {\n match: /(?<=(\\i)\\.length\\?\\i.\\i\\.Messages.THREE_USERS_TYPING\\.format\\({\\i:(\\i),(?:\\i:)?(\\i),\\i:\\i}\\):)\\i\\.\\i\\.Messages\\.SEVERAL_USERS_TYPING/,\n replace: (_, users, a, b) => `$self.buildSeveralUsers({ a: ${a}, b: ${b}, count: ${users}.length - 2 })`\n },\n predicate: () => settings.store.alternativeFormatting\n }\n ],\n settings,\n\n TYPING_TEXT_STYLE: {\n display: \"grid\",\n gridAutoFlow: \"column\",\n gridGap: \"0.25em\"\n },\n\n buildSeveralUsers,\n\n mutateChildren(props: any, users: User[], children: any) {\n if (!Array.isArray(children)) return children;\n\n let element = 0;\n\n return children.map(c =>\n c.type === \"strong\"\n ? <TypingUser {...props} user={users[element++]} />\n : c\n );\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { definePluginSettings, Settings } from \"@api/Settings\";\nimport ErrorBoundary from \"@components/ErrorBoundary\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { findExportedComponentLazy, findStoreLazy } from \"@webpack\";\nimport { ChannelStore, GuildMemberStore, i18n, RelationshipStore, SelectedChannelStore, Tooltip, UserStore, useStateFromStores } from \"@webpack/common\";\n\nimport { buildSeveralUsers } from \"../typingTweaks\";\n\nconst ThreeDots = findExportedComponentLazy(\"Dots\", \"AnimatedDots\");\n\nconst TypingStore = findStoreLazy(\"TypingStore\");\nconst UserGuildSettingsStore = findStoreLazy(\"UserGuildSettingsStore\");\n\nfunction getDisplayName(guildId: string, userId: string) {\n const user = UserStore.getUser(userId);\n return GuildMemberStore.getNick(guildId, userId) ?? (user as any).globalName ?? user.username;\n}\n\nfunction TypingIndicator({ channelId }: { channelId: string; }) {\n const typingUsers: Record<string, number> = useStateFromStores(\n [TypingStore],\n () => ({ ...TypingStore.getTypingUsers(channelId) as Record<string, number> }),\n null,\n (old, current) => {\n const oldKeys = Object.keys(old);\n const currentKeys = Object.keys(current);\n\n return oldKeys.length === currentKeys.length && currentKeys.every(key => old[key] != null);\n }\n );\n const currentChannelId: string = useStateFromStores([SelectedChannelStore], () => SelectedChannelStore.getChannelId());\n const guildId = ChannelStore.getChannel(channelId).guild_id;\n\n if (!settings.store.includeMutedChannels) {\n const isChannelMuted = UserGuildSettingsStore.isChannelMuted(guildId, channelId);\n if (isChannelMuted) return null;\n }\n\n if (!settings.store.includeCurrentChannel) {\n if (currentChannelId === channelId) return null;\n }\n\n const myId = UserStore.getCurrentUser()?.id;\n\n const typingUsersArray = Object.keys(typingUsers).filter(id => id !== myId && !(RelationshipStore.isBlocked(id) && !settings.store.includeBlockedUsers));\n let tooltipText: string;\n\n switch (typingUsersArray.length) {\n case 0: break;\n case 1: {\n tooltipText = i18n.Messages.ONE_USER_TYPING.format({ a: getDisplayName(guildId, typingUsersArray[0]) });\n break;\n }\n case 2: {\n tooltipText = i18n.Messages.TWO_USERS_TYPING.format({ a: getDisplayName(guildId, typingUsersArray[0]), b: getDisplayName(guildId, typingUsersArray[1]) });\n break;\n }\n case 3: {\n tooltipText = i18n.Messages.THREE_USERS_TYPING.format({ a: getDisplayName(guildId, typingUsersArray[0]), b: getDisplayName(guildId, typingUsersArray[1]), c: getDisplayName(guildId, typingUsersArray[2]) });\n break;\n }\n default: {\n tooltipText = Settings.plugins.TypingTweaks.enabled\n ? buildSeveralUsers({ a: getDisplayName(guildId, typingUsersArray[0]), b: getDisplayName(guildId, typingUsersArray[1]), count: typingUsersArray.length - 2 })\n : i18n.Messages.SEVERAL_USERS_TYPING;\n break;\n }\n }\n\n if (typingUsersArray.length > 0) {\n return (\n <Tooltip text={tooltipText!}>\n {props => (\n <div\n {...props}\n style={{ marginLeft: 6, height: 16, display: \"flex\", alignItems: \"center\", zIndex: 0, cursor: \"pointer\" }}\n >\n <ThreeDots dotRadius={3} themed={true} />\n </div>\n )}\n </Tooltip>\n );\n }\n\n return null;\n}\n\nconst settings = definePluginSettings({\n includeCurrentChannel: {\n type: OptionType.BOOLEAN,\n description: \"Whether to show the typing indicator for the currently selected channel\",\n default: true\n },\n includeMutedChannels: {\n type: OptionType.BOOLEAN,\n description: \"Whether to show the typing indicator for muted channels.\",\n default: false\n },\n includeBlockedUsers: {\n type: OptionType.BOOLEAN,\n description: \"Whether to show the typing indicator for blocked users.\",\n default: false\n }\n});\n\nexport default definePlugin({\n name: \"TypingIndicator\",\n description: \"Adds an indicator if someone is typing on a channel.\",\n authors: [Devs.Nuckyz, Devs.obscurity],\n settings,\n\n patches: [\n // Normal channel\n {\n find: \"UNREAD_IMPORTANT:\",\n replacement: {\n match: /channel:(\\i).{0,100}?channelEmoji,.{0,250}?\\.children.{0,50}?:null/,\n replace: \"$&,$self.TypingIndicator($1.id)\"\n }\n },\n // Theads\n {\n // This is the thread \"spine\" that shows in the left\n find: \"M11 9H4C2.89543 9 2 8.10457 2 7V1C2 0.447715 1.55228 0 1 0C0.447715 0 0 0.447715 0 1V7C0 9.20914 1.79086 11 4 11H11C11.5523 11 12 10.5523 12 10C12 9.44771 11.5523 9 11 9Z\",\n replacement: {\n match: /mentionsCount:\\i.+?null(?<=channel:(\\i).+?)/,\n replace: \"$&,$self.TypingIndicator($1.id)\"\n }\n }\n ],\n\n TypingIndicator: (channelId: string) => (\n <ErrorBoundary noop>\n <TypingIndicator channelId={channelId} />\n </ErrorBoundary>\n ),\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { addPreEditListener, addPreSendListener, MessageObject, removePreEditListener, removePreSendListener } from \"@api/MessageEvents\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\n\nexport default definePlugin({\n name: \"Unindent\",\n description: \"Trims leading indentation from codeblocks\",\n authors: [Devs.Ven],\n dependencies: [\"MessageEventsAPI\"],\n patches: [\n {\n find: \"inQuote:\",\n replacement: {\n match: /,content:([^,]+),inQuote/,\n replace: (_, content) => `,content:Vencord.Plugins.plugins.Unindent.unindent(${content}),inQuote`\n }\n }\n ],\n\n unindent(str: string) {\n // Users cannot send tabs, they get converted to spaces. However, a bot may send tabs, so convert them to 4 spaces first\n str = str.replace(/\\t/g, \" \");\n const minIndent = str.match(/^ *(?=\\S)/gm)\n ?.reduce((prev, curr) => Math.min(prev, curr.length), Infinity) ?? 0;\n\n if (!minIndent) return str;\n return str.replace(new RegExp(`^ {${minIndent}}`, \"gm\"), \"\");\n },\n\n unindentMsg(msg: MessageObject) {\n msg.content = msg.content.replace(/```(.|\\n)*?```/g, m => {\n const lines = m.split(\"\\n\");\n if (lines.length < 2) return m; // Do not affect inline codeblocks\n let suffix = \"\";\n if (lines[lines.length - 1] === \"```\") suffix = lines.pop()!;\n return `${lines[0]}\\n${this.unindent(lines.slice(1).join(\"\\n\"))}\\n${suffix}`;\n });\n },\n\n start() {\n this.preSend = addPreSendListener((_, msg) => this.unindentMsg(msg));\n this.preEdit = addPreEditListener((_cid, _mid, msg) => this.unindentMsg(msg));\n },\n\n stop() {\n removePreSendListener(this.preSend);\n removePreEditListener(this.preEdit);\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { addContextMenuPatch, findGroupChildrenByChildId, NavContextMenuPatchCallback, removeContextMenuPatch } from \"@api/ContextMenu\";\nimport { ImageInvisible, ImageVisible } from \"@components/Icons\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\nimport { Menu, PermissionsBits, PermissionStore, RestAPI, UserStore } from \"@webpack/common\";\n\nconst EMBED_SUPPRESSED = 1 << 2;\n\nconst messageContextMenuPatch: NavContextMenuPatchCallback = (children, { channel, message: { author, embeds, flags, id: messageId } }) => () => {\n const isEmbedSuppressed = (flags & EMBED_SUPPRESSED) !== 0;\n if (!isEmbedSuppressed && !embeds.length) return;\n\n const hasEmbedPerms = channel.isPrivate() || !!(PermissionStore.getChannelPermissions({ id: channel.id }) & PermissionsBits.EMBED_LINKS);\n if (author.id === UserStore.getCurrentUser().id && !hasEmbedPerms) return;\n\n const menuGroup = findGroupChildrenByChildId(\"delete\", children);\n const deleteIndex = menuGroup?.findIndex(i => i?.props?.id === \"delete\");\n if (!deleteIndex || !menuGroup) return;\n\n menuGroup.splice(deleteIndex - 1, 0, (\n <Menu.MenuItem\n id=\"unsuppress-embeds\"\n key=\"unsuppress-embeds\"\n label={isEmbedSuppressed ? \"Unsuppress Embeds\" : \"Suppress Embeds\"}\n color={isEmbedSuppressed ? undefined : \"danger\"}\n icon={isEmbedSuppressed ? ImageVisible : ImageInvisible}\n action={() =>\n RestAPI.patch({\n url: `/channels/${channel.id}/messages/${messageId}`,\n body: { flags: isEmbedSuppressed ? flags & ~EMBED_SUPPRESSED : flags | EMBED_SUPPRESSED }\n })\n }\n />\n ));\n};\n\nexport default definePlugin({\n name: \"UnsuppressEmbeds\",\n authors: [Devs.rad, Devs.HypedDomi],\n description: \"Allows you to unsuppress embeds in messages\",\n\n start() {\n addContextMenuPatch(\"message\", messageContextMenuPatch);\n },\n\n stop() {\n removeContextMenuPatch(\"message\", messageContextMenuPatch);\n },\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { ApplicationCommandOptionType, sendBotMessage } from \"@api/Commands\";\nimport { ApplicationCommandInputType } from \"@api/Commands/types\";\nimport { definePluginSettings } from \"@api/Settings\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin, { OptionType } from \"@utils/types\";\n\nconst settings = definePluginSettings({\n resultsAmount: {\n type: OptionType.NUMBER,\n description: \"The amount of results you want to get (more gives better results, but is slower)\",\n default: 10\n }\n});\n\nexport default definePlugin({\n name: \"UrbanDictionary\",\n description: \"Search for a word on Urban Dictionary via /urban slash command\",\n authors: [Devs.jewdev],\n dependencies: [\"CommandsAPI\"],\n settings,\n commands: [\n {\n name: \"urban\",\n description: \"Returns the definition of a word from Urban Dictionary\",\n inputType: ApplicationCommandInputType.BUILT_IN,\n options: [\n {\n type: ApplicationCommandOptionType.STRING,\n name: \"word\",\n description: \"The word to search for on Urban Dictionary\",\n required: true\n }\n ],\n execute: async (args, ctx) => {\n try {\n const query: string = encodeURIComponent(args[0].value);\n const { list } = await fetch(`https://api.urbandictionary.com/v0/define?term=${query}&per_page=${settings.store.resultsAmount}`).then(response => response.json());\n\n if (!list.length)\n return void sendBotMessage(ctx.channel.id, { content: \"No results found.\" });\n\n const definition = list.reduce((prev, curr) => {\n return prev.thumbs_up > curr.thumbs_up ? prev : curr;\n });\n\n const linkify = (text: string) => text\n .replaceAll(\"\\r\\n\", \"\\n\")\n .replace(/([*>_`~\\\\])/gsi, \"\\\\$1\")\n .replace(/\\[(.+?)\\]/g, (_, word) => `[${word}](https://www.urbandictionary.com/define.php?term=${encodeURIComponent(word)} \"Define '${word}' on Urban Dictionary\")`)\n .trim();\n\n return void sendBotMessage(ctx.channel.id, {\n embeds: [\n {\n type: \"rich\",\n author: {\n name: `Uploaded by \"${definition.author}\"`,\n url: `https://www.urbandictionary.com/author.php?author=${encodeURIComponent(definition.author)}`,\n },\n title: definition.word,\n url: `https://www.urbandictionary.com/define.php?term=${encodeURIComponent(definition.word)}`,\n description: linkify(definition.definition),\n fields: [\n {\n name: \"Example\",\n value: linkify(definition.example),\n },\n {\n name: \"Want more definitions?\",\n value: `Check out [more definitions](https://www.urbandictionary.com/define.php?term=${query} \"Define \"${args[0].value}\" on Urban Dictionary\") on Urban Dictionary.`,\n },\n ],\n color: 0xFF9900,\n footer: { text: `\uD83D\uDC4D ${definition.thumbs_up.toString()} | \uD83D\uDC4E ${definition.thumbs_down.toString()}`, icon_url: \"https://www.urbandictionary.com/favicon.ico\" },\n timestamp: new Date(definition.written_on).toISOString(),\n },\n ] as any,\n });\n } catch (error) {\n sendBotMessage(ctx.channel.id, {\n content: `Something went wrong: \\`${error}\\``,\n });\n }\n }\n }\n ]\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport \"./VoiceChannelSection.css\";\n\nimport { findByCodeLazy, findByPropsLazy } from \"@webpack\";\nimport { Button, Forms, PermissionStore, Toasts } from \"@webpack/common\";\nimport { Channel } from \"discord-types/general\";\n\nconst ChannelActions = findByPropsLazy(\"selectChannel\", \"selectVoiceChannel\");\nconst UserPopoutSection = findByCodeLazy(\".lastSection\", \"children:\");\n\nconst CONNECT = 1n << 20n;\n\ninterface VoiceChannelFieldProps {\n channel: Channel;\n label: string;\n showHeader: boolean;\n}\n\nexport const VoiceChannelSection = ({ channel, label, showHeader }: VoiceChannelFieldProps) => (\n <UserPopoutSection>\n {showHeader && <Forms.FormTitle className=\"vc-uvs-header\">In a voice channel</Forms.FormTitle>}\n <Button\n className=\"vc-uvs-button\"\n color={Button.Colors.TRANSPARENT}\n size={Button.Sizes.SMALL}\n\n onClick={() => {\n if (PermissionStore.can(CONNECT, channel))\n ChannelActions.selectVoiceChannel(channel.id);\n else\n Toasts.show({\n message: \"Insufficient permissions to enter the channel.\",\n id: \"user-voice-show-insufficient-permissions\",\n type: Toasts.Type.FAILURE,\n options: {\n position: Toasts.Position.BOTTOM,\n }\n });\n }}\n >\n {label}\n </Button>\n </UserPopoutSection>\n);\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { definePluginSettings } from \"@api/Settings\";\nimport ErrorBoundary from \"@components/ErrorBoundary\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { findStoreLazy } from \"@webpack\";\nimport { ChannelStore, GuildStore, UserStore } from \"@webpack/common\";\nimport { User } from \"discord-types/general\";\n\nimport { VoiceChannelSection } from \"./components/VoiceChannelSection\";\n\nconst VoiceStateStore = findStoreLazy(\"VoiceStateStore\");\n\nconst settings = definePluginSettings({\n showInUserProfileModal: {\n type: OptionType.BOOLEAN,\n description: \"Show a user's voice channel in their profile modal\",\n default: true,\n },\n showVoiceChannelSectionHeader: {\n type: OptionType.BOOLEAN,\n description: 'Whether to show \"IN A VOICE CHANNEL\" above the join button',\n default: true,\n }\n});\n\ninterface UserProps {\n user: User;\n}\n\nconst VoiceChannelField = ErrorBoundary.wrap(({ user }: UserProps) => {\n const { channelId } = VoiceStateStore.getVoiceStateForUser(user.id) ?? {};\n if (!channelId) return null;\n\n const channel = ChannelStore.getChannel(channelId);\n if (!channel) return null;\n\n const guild = GuildStore.getGuild(channel.guild_id);\n\n if (!guild) return null; // When in DM call\n\n const result = `${guild.name} | ${channel.name}`;\n\n return (\n <VoiceChannelSection\n channel={channel}\n label={result}\n showHeader={settings.store.showVoiceChannelSectionHeader}\n />\n );\n});\n\nexport default definePlugin({\n name: \"UserVoiceShow\",\n description: \"Shows whether a User is currently in a voice channel somewhere in their profile\",\n authors: [Devs.LordElias],\n settings,\n\n patchModal({ user }: UserProps) {\n if (!settings.store.showInUserProfileModal)\n return null;\n\n return (\n <div className=\"vc-uvs-modal-margin\">\n <VoiceChannelField user={user} />\n </div>\n );\n },\n\n patchPopout: ({ user }: UserProps) => {\n const isSelfUser = user.id === UserStore.getCurrentUser().id;\n return (\n <div className={isSelfUser ? \"vc-uvs-popout-margin-self\" : \"\"}>\n <VoiceChannelField user={user} />\n </div>\n );\n },\n\n patches: [\n // above message box\n {\n find: \".lastEditedByContainer\",\n replacement: {\n match: /\\(0,\\i\\.jsx\\)\\(\\i\\.\\i,{user:\\i,setNote/,\n replace: \"$self.patchPopout(arguments[0]),$&\",\n }\n },\n // below username\n {\n find: \".USER_PROFILE_MODAL\",\n replacement: {\n match: /\\.body.+?displayProfile:\\i}\\),/,\n replace: \"$&$self.patchModal(arguments[0]),\",\n }\n }\n ],\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\n(window.VencordStyles ??= new Map()).set(\"src/plugins/usrbg/index.css\", {\n name: \"src/plugins/usrbg/index.css\",\n source: \":is([class*=\\\"userProfile\\\"], [class*=\\\"userPopout\\\"]) [class*=\\\"bannerPremium\\\"] {\\n background: center / cover no-repeat;\\n}\\n\\n[class*=\\\"NonPremium\\\"]:has([class*=\\\"bannerPremium\\\"]) [class*=\\\"avatarPositionNormal\\\"],\\n[class*=\\\"PremiumWithoutBanner\\\"]:has([class*=\\\"bannerPremium\\\"]) [class*=\\\"avatarPositionPremiumNoBanner\\\"] {\\n top: 76px;\\n}\\n\\n[style*=\\\"background-image\\\"] [class*=\\\"background_\\\"] {\\n background-color: transparent !important;\\n}\\n\",\n classNames: {},\n dom: null,\n});\n\nexport default \"src/plugins/usrbg/index.css\";\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { definePluginSettings } from \"@api/Settings\";\nimport { enableStyle } from \"@api/Styles\";\nimport { Link } from \"@components/Link\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin, { OptionType } from \"@utils/types\";\n\nimport style from \"./index.css?managed\";\n\nconst BASE_URL = \"https://raw.githubusercontent.com/AutumnVN/usrbg/main/usrbg.json\";\n\nlet data = {} as Record<string, string>;\n\nconst settings = definePluginSettings({\n nitroFirst: {\n description: \"Banner to use if both Nitro and USRBG banners are present\",\n type: OptionType.SELECT,\n options: [\n { label: \"Nitro banner\", value: true, default: true },\n { label: \"USRBG banner\", value: false },\n ]\n },\n voiceBackground: {\n description: \"Use USRBG banners as voice chat backgrounds\",\n type: OptionType.BOOLEAN,\n default: true,\n restartNeeded: true\n }\n});\n\nexport default definePlugin({\n name: \"USRBG\",\n description: \"Displays user banners from USRBG, allowing anyone to get a banner without Nitro\",\n authors: [Devs.AutumnVN, Devs.pylix, Devs.TheKodeToad],\n settings,\n patches: [\n {\n find: \".NITRO_BANNER,\",\n replacement: [\n {\n match: /(\\i)\\.premiumType/,\n replace: \"$self.premiumHook($1)||$&\"\n },\n {\n match: /(?<=function \\i\\((\\i)\\)\\{)(?=var.{30,50},bannerSrc:)/,\n replace: \"$1.bannerSrc=$self.useBannerHook($1);\"\n },\n {\n match: /\\?\\(0,\\i\\.jsx\\)\\(\\i,{type:\\i,shown/,\n replace: \"&&$self.shouldShowBadge(arguments[0])$&\"\n }\n ]\n },\n {\n find: \"\\\"data-selenium-video-tile\\\":\",\n predicate: () => settings.store.voiceBackground,\n replacement: [\n {\n match: /(?<=function\\((\\i),\\i\\)\\{)(?=let.{20,40},style:)/,\n replace: \"$1.style=$self.voiceBackgroundHook($1);\"\n }\n ]\n }\n ],\n\n\n data,\n\n settingsAboutComponent: () => {\n return (\n <Link href=\"https://github.com/AutumnVN/usrbg#how-to-request-your-own-usrbg-banner\">CLICK HERE TO GET YOUR OWN BANNER</Link>\n );\n },\n\n voiceBackgroundHook({ className, participantUserId }: any) {\n if (className.includes(\"tile_\")) {\n if (data[participantUserId]) {\n return {\n backgroundImage: `url(${data[participantUserId]})`,\n backgroundSize: \"cover\",\n backgroundPosition: \"center\",\n backgroundRepeat: \"no-repeat\"\n };\n }\n }\n },\n\n useBannerHook({ displayProfile, user }: any) {\n if (displayProfile?.banner && settings.store.nitroFirst) return;\n if (data[user.id]) return data[user.id];\n },\n\n premiumHook({ userId }: any) {\n if (data[userId]) return 2;\n },\n\n shouldShowBadge({ displayProfile, user }: any) {\n return displayProfile?.banner && (!data[user.id] || settings.store.nitroFirst);\n },\n\n async start() {\n enableStyle(style);\n\n const res = await fetch(BASE_URL);\n if (res.ok) {\n data = await res.json();\n this.data = data;\n }\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport ErrorBoundary from \"@components/ErrorBoundary\";\nimport { Devs } from \"@utils/constants\";\nimport { sleep } from \"@utils/misc\";\nimport { Queue } from \"@utils/Queue\";\nimport definePlugin from \"@utils/types\";\nimport { UserStore, UserUtils, useState } from \"@webpack/common\";\nimport type { ComponentType, ReactNode } from \"react\";\n\nconst fetching = new Set<string>();\nconst queue = new Queue(5);\n\ninterface MentionProps {\n data: {\n userId?: string;\n channelId?: string;\n content: any;\n };\n parse: (content: any, props: MentionProps[\"props\"]) => ReactNode;\n props: {\n key: string;\n formatInline: boolean;\n noStyleAndInteraction: boolean;\n };\n RoleMention: ComponentType<any>;\n UserMention: ComponentType<any>;\n}\n\nfunction MentionWrapper({ data, UserMention, RoleMention, parse, props }: MentionProps) {\n const [userId, setUserId] = useState(data.userId);\n\n // if userId is set it means the user is cached. Uncached users have userId set to undefined\n if (userId)\n return (\n <UserMention\n className=\"mention\"\n userId={userId}\n channelId={data.channelId}\n inlinePreview={props.noStyleAndInteraction}\n key={props.key}\n />\n );\n\n // Parses the raw text node array data.content into a ReactNode[]: [\"<@userid>\"]\n const children = parse(data.content, props);\n\n return (\n // Discord is deranged and renders unknown user mentions as role mentions\n <RoleMention\n {...data}\n inlinePreview={props.formatInline}\n >\n <span\n onMouseEnter={() => {\n const mention = children?.[0]?.props?.children;\n if (typeof mention !== \"string\") return;\n\n const id = mention.match(/<@!?(\\d+)>/)?.[1];\n if (!id) return;\n\n if (fetching.has(id))\n return;\n\n if (UserStore.getUser(id))\n return setUserId(id);\n\n const fetch = () => {\n fetching.add(id);\n\n queue.unshift(() =>\n UserUtils.getUser(id)\n .then(() => {\n setUserId(id);\n fetching.delete(id);\n })\n .catch(e => {\n if (e?.status === 429) {\n queue.unshift(() => sleep(1000).then(fetch));\n fetching.delete(id);\n }\n })\n .finally(() => sleep(300))\n );\n };\n\n fetch();\n }}\n >\n {children}\n </span>\n </RoleMention>\n );\n}\n\nexport default definePlugin({\n name: \"ValidUser\",\n description: \"Fix mentions for unknown users showing up as '<@343383572805058560>' (hover over a mention to fix it)\",\n authors: [Devs.Ven],\n tags: [\"MentionCacheFix\"],\n\n patches: [{\n find: 'className:\"mention\"',\n replacement: {\n // mention = { react: function (data, parse, props) { if (data.userId == null) return RoleMention() else return UserMention()\n match: /react(?=\\(\\i,\\i,\\i\\).{0,50}return null==\\i\\?\\(0,\\i\\.jsx\\)\\((\\i\\.\\i),.+?jsx\\)\\((\\i\\.\\i),\\{className:\"mention\")/,\n // react: (...args) => OurWrapper(RoleMention, UserMention, ...args), originalReact: theirFunc\n replace: \"react:(...args)=>$self.renderMention($1,$2,...args),originalReact\"\n }\n }],\n\n renderMention(RoleMention, UserMention, data, parse, props) {\n return (\n <ErrorBoundary noop>\n <MentionWrapper\n RoleMention={RoleMention}\n UserMention={UserMention}\n data={data}\n parse={parse}\n props={props}\n />\n </ErrorBoundary>\n );\n },\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\nimport { ChannelStore, SelectedChannelStore } from \"@webpack/common\";\n\nconst timers = {} as Record<string, {\n timeout?: NodeJS.Timeout;\n i: number;\n}>;\n\nexport default definePlugin({\n name: \"VoiceChatDoubleClick\",\n description: \"Join voice chats via double click instead of single click\",\n authors: [Devs.Ven, Devs.D3SOX],\n patches: [\n ...[\n \".handleVoiceStatusClick\", // voice channels\n \".handleClickChat\" // stage channels\n ].map(find => ({\n find,\n // hack: these are not React onClick, it is a custom prop handled by Discord\n // thus, replacing this with onDoubleClick won't work, and you also cannot check\n // e.detail since instead of the event they pass the channel.\n // do this timer workaround instead\n replacement: [\n {\n match: /onClick:\\(\\)=>\\{this.handleClick\\(\\)/g,\n replace: \"onClick:()=>{$self.schedule(()=>{this.handleClick()},this)\",\n },\n ]\n })),\n {\n // channel mentions\n find: \".shouldCloseDefaultModals\",\n replacement: {\n match: /onClick:(\\i)(?=,.{0,30}className:\"channelMention\".+?(\\i)\\.inContent)/,\n replace: (_, onClick, props) => \"\"\n + `onClick:(vcDoubleClickEvt)=>$self.shouldRunOnClick(vcDoubleClickEvt,${props})&&${onClick}()`,\n }\n }\n ],\n\n shouldRunOnClick(e: MouseEvent, { channelId }) {\n const channel = ChannelStore.getChannel(channelId);\n if (!channel || ![2, 13].includes(channel.type)) return true;\n return e.detail >= 2;\n },\n\n schedule(cb: () => void, e: any) {\n const id = e.props.channel.id as string;\n if (SelectedChannelStore.getVoiceChannelId() === id) {\n cb();\n return;\n }\n // use a different counter for each channel\n const data = (timers[id] ??= { timeout: void 0, i: 0 });\n // clear any existing timer\n clearTimeout(data.timeout);\n\n // if we already have 2 or more clicks, run the callback immediately\n if (++data.i >= 2) {\n cb();\n delete timers[id];\n } else {\n // else reset the counter in 500ms\n data.timeout = setTimeout(() => {\n delete timers[id];\n }, 500);\n }\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Settings } from \"@api/Settings\";\nimport { ErrorCard } from \"@components/ErrorCard\";\nimport { Devs } from \"@utils/constants\";\nimport { Logger } from \"@utils/Logger\";\nimport { Margins } from \"@utils/margins\";\nimport { wordsToTitle } from \"@utils/text\";\nimport definePlugin, { OptionType, PluginOptionsItem } from \"@utils/types\";\nimport { findByPropsLazy } from \"@webpack\";\nimport { Button, ChannelStore, Forms, GuildMemberStore, SelectedChannelStore, SelectedGuildStore, useMemo, UserStore } from \"@webpack/common\";\n\ninterface VoiceState {\n userId: string;\n channelId?: string;\n oldChannelId?: string;\n deaf: boolean;\n mute: boolean;\n selfDeaf: boolean;\n selfMute: boolean;\n}\n\nconst VoiceStateStore = findByPropsLazy(\"getVoiceStatesForChannel\", \"getCurrentClientVoiceChannelId\");\n\n// Mute/Deaf for other people than you is commented out, because otherwise someone can spam it and it will be annoying\n// Filtering out events is not as simple as just dropping duplicates, as otherwise mute, unmute, mute would\n// not say the second mute, which would lead you to believe they're unmuted\n\nfunction speak(text: string, settings: any = Settings.plugins.VcNarrator) {\n if (!text) return;\n\n const speech = new SpeechSynthesisUtterance(text);\n let voice = speechSynthesis.getVoices().find(v => v.voiceURI === settings.voice);\n if (!voice) {\n new Logger(\"VcNarrator\").error(`Voice \"${settings.voice}\" not found. Resetting to default.`);\n voice = speechSynthesis.getVoices().find(v => v.default);\n settings.voice = voice?.voiceURI;\n if (!voice) return; // This should never happen\n }\n speech.voice = voice!;\n speech.volume = settings.volume;\n speech.rate = settings.rate;\n speechSynthesis.speak(speech);\n}\n\nfunction clean(str: string) {\n const replacer = Settings.plugins.VcNarrator.latinOnly\n ? /[^\\p{Script=Latin}\\p{Number}\\p{Punctuation}\\s]/gu\n : /[^\\p{Letter}\\p{Number}\\p{Punctuation}\\s]/gu;\n\n return str.normalize(\"NFKC\")\n .replace(replacer, \"\")\n .replace(/_{2,}/g, \"_\")\n .trim();\n}\n\nfunction formatText(str: string, user: string, channel: string, displayName: string, nickname: string) {\n return str\n .replaceAll(\"{{USER}}\", clean(user) || (user ? \"Someone\" : \"\"))\n .replaceAll(\"{{CHANNEL}}\", clean(channel) || \"channel\")\n .replaceAll(\"{{DISPLAY_NAME}}\", clean(displayName) || (displayName ? \"Someone\" : \"\"))\n .replaceAll(\"{{NICKNAME}}\", clean(nickname) || (nickname ? \"Someone\" : \"\"));\n}\n\n/*\nlet StatusMap = {} as Record<string, {\n mute: boolean;\n deaf: boolean;\n}>;\n*/\n\n// For every user, channelId and oldChannelId will differ when moving channel.\n// Only for the local user, channelId and oldChannelId will be the same when moving channel,\n// for some ungodly reason\nlet myLastChannelId: string | undefined;\n\nfunction getTypeAndChannelId({ channelId, oldChannelId }: VoiceState, isMe: boolean) {\n if (isMe && channelId !== myLastChannelId) {\n oldChannelId = myLastChannelId;\n myLastChannelId = channelId;\n }\n\n if (channelId !== oldChannelId) {\n if (channelId) return [oldChannelId ? \"move\" : \"join\", channelId];\n if (oldChannelId) return [\"leave\", oldChannelId];\n }\n /*\n if (channelId) {\n if (deaf || selfDeaf) return [\"deafen\", channelId];\n if (mute || selfMute) return [\"mute\", channelId];\n const oldStatus = StatusMap[userId];\n if (oldStatus.deaf) return [\"undeafen\", channelId];\n if (oldStatus.mute) return [\"unmute\", channelId];\n }\n */\n return [\"\", \"\"];\n}\n\n/*\nfunction updateStatuses(type: string, { deaf, mute, selfDeaf, selfMute, userId, channelId }: VoiceState, isMe: boolean) {\n if (isMe && (type === \"join\" || type === \"move\")) {\n StatusMap = {};\n const states = VoiceStateStore.getVoiceStatesForChannel(channelId!) as Record<string, VoiceState>;\n for (const userId in states) {\n const s = states[userId];\n StatusMap[userId] = {\n mute: s.mute || s.selfMute,\n deaf: s.deaf || s.selfDeaf\n };\n }\n return;\n }\n\n if (type === \"leave\" || (type === \"move\" && channelId !== SelectedChannelStore.getVoiceChannelId())) {\n if (isMe)\n StatusMap = {};\n else\n delete StatusMap[userId];\n\n return;\n }\n\n StatusMap[userId] = {\n deaf: deaf || selfDeaf,\n mute: mute || selfMute\n };\n}\n*/\n\nfunction playSample(tempSettings: any, type: string) {\n const settings = Object.assign({}, Settings.plugins.VcNarrator, tempSettings);\n const currentUser = UserStore.getCurrentUser();\n const myGuildId = SelectedGuildStore.getGuildId();\n\n speak(formatText(settings[type + \"Message\"], currentUser.username, \"general\", (currentUser as any).globalName ?? currentUser.username, GuildMemberStore.getNick(myGuildId, currentUser.id) ?? currentUser.username), settings);\n}\n\nexport default definePlugin({\n name: \"VcNarrator\",\n description: \"Announces when users join, leave, or move voice channels via narrator\",\n authors: [Devs.Ven],\n\n flux: {\n VOICE_STATE_UPDATES({ voiceStates }: { voiceStates: VoiceState[]; }) {\n const myGuildId = SelectedGuildStore.getGuildId();\n const myChanId = SelectedChannelStore.getVoiceChannelId();\n const myId = UserStore.getCurrentUser().id;\n\n if (ChannelStore.getChannel(myChanId!)?.type === 13 /* Stage Channel */) return;\n\n for (const state of voiceStates) {\n const { userId, channelId, oldChannelId } = state;\n const isMe = userId === myId;\n if (!isMe) {\n if (!myChanId) continue;\n if (channelId !== myChanId && oldChannelId !== myChanId) continue;\n }\n\n const [type, id] = getTypeAndChannelId(state, isMe);\n if (!type) continue;\n\n const template = Settings.plugins.VcNarrator[type + \"Message\"];\n const user = isMe && !Settings.plugins.VcNarrator.sayOwnName ? \"\" : UserStore.getUser(userId).username;\n const displayName = user && ((UserStore.getUser(userId) as any).globalName ?? user);\n const nickname = user && (GuildMemberStore.getNick(myGuildId, userId) ?? user);\n const channel = ChannelStore.getChannel(id).name;\n\n speak(formatText(template, user, channel, displayName, nickname));\n\n // updateStatuses(type, state, isMe);\n }\n },\n\n AUDIO_TOGGLE_SELF_MUTE() {\n const chanId = SelectedChannelStore.getVoiceChannelId()!;\n const s = VoiceStateStore.getVoiceStateForChannel(chanId) as VoiceState;\n if (!s) return;\n\n const event = s.mute || s.selfMute ? \"unmute\" : \"mute\";\n speak(formatText(Settings.plugins.VcNarrator[event + \"Message\"], \"\", ChannelStore.getChannel(chanId).name, \"\", \"\"));\n },\n\n AUDIO_TOGGLE_SELF_DEAF() {\n const chanId = SelectedChannelStore.getVoiceChannelId()!;\n const s = VoiceStateStore.getVoiceStateForChannel(chanId) as VoiceState;\n if (!s) return;\n\n const event = s.deaf || s.selfDeaf ? \"undeafen\" : \"deafen\";\n speak(formatText(Settings.plugins.VcNarrator[event + \"Message\"], \"\", ChannelStore.getChannel(chanId).name, \"\", \"\"));\n }\n },\n\n start() {\n if (typeof speechSynthesis === \"undefined\" || speechSynthesis.getVoices().length === 0) {\n new Logger(\"VcNarrator\").warn(\n \"SpeechSynthesis not supported or no Narrator voices found. Thus, this plugin will not work. Check my Settings for more info\"\n );\n return;\n }\n\n },\n\n optionsCache: null as Record<string, PluginOptionsItem> | null,\n\n get options() {\n return this.optionsCache ??= {\n voice: {\n type: OptionType.SELECT,\n description: \"Narrator Voice\",\n options: window.speechSynthesis?.getVoices().map(v => ({\n label: v.name,\n value: v.voiceURI,\n default: v.default\n })) ?? []\n },\n volume: {\n type: OptionType.SLIDER,\n description: \"Narrator Volume\",\n default: 1,\n markers: [0, 0.25, 0.5, 0.75, 1],\n stickToMarkers: false\n },\n rate: {\n type: OptionType.SLIDER,\n description: \"Narrator Speed\",\n default: 1,\n markers: [0.1, 0.5, 1, 2, 5, 10],\n stickToMarkers: false\n },\n sayOwnName: {\n description: \"Say own name\",\n type: OptionType.BOOLEAN,\n default: false\n },\n latinOnly: {\n description: \"Strip non latin characters from names before saying them\",\n type: OptionType.BOOLEAN,\n default: false\n },\n joinMessage: {\n type: OptionType.STRING,\n description: \"Join Message\",\n default: \"{{USER}} joined\"\n },\n leaveMessage: {\n type: OptionType.STRING,\n description: \"Leave Message\",\n default: \"{{USER}} left\"\n },\n moveMessage: {\n type: OptionType.STRING,\n description: \"Move Message\",\n default: \"{{USER}} moved to {{CHANNEL}}\"\n },\n muteMessage: {\n type: OptionType.STRING,\n description: \"Mute Message (only self for now)\",\n default: \"{{USER}} Muted\"\n },\n unmuteMessage: {\n type: OptionType.STRING,\n description: \"Unmute Message (only self for now)\",\n default: \"{{USER}} unmuted\"\n },\n deafenMessage: {\n type: OptionType.STRING,\n description: \"Deafen Message (only self for now)\",\n default: \"{{USER}} deafened\"\n },\n undeafenMessage: {\n type: OptionType.STRING,\n description: \"Undeafen Message (only self for now)\",\n default: \"{{USER}} undeafened\"\n }\n };\n },\n\n settingsAboutComponent({ tempSettings: s }) {\n const [hasVoices, hasEnglishVoices] = useMemo(() => {\n const voices = speechSynthesis.getVoices();\n return [voices.length !== 0, voices.some(v => v.lang.startsWith(\"en\"))];\n }, []);\n\n const types = useMemo(\n () => Object.keys(Vencord.Plugins.plugins.VcNarrator.options!).filter(k => k.endsWith(\"Message\")).map(k => k.slice(0, -7)),\n [],\n );\n\n let errorComponent: React.ReactElement | null = null;\n if (!hasVoices) {\n let error = \"No narrator voices found. \";\n error += navigator.platform?.toLowerCase().includes(\"linux\")\n ? \"Install speech-dispatcher or espeak and run Discord with the --enable-speech-dispatcher flag\"\n : \"Try installing some in the Narrator settings of your Operating System\";\n errorComponent = <ErrorCard>{error}</ErrorCard>;\n } else if (!hasEnglishVoices) {\n errorComponent = <ErrorCard>You don't have any English voices installed, so the narrator might sound weird</ErrorCard>;\n }\n\n return (\n <Forms.FormSection>\n <Forms.FormText>\n You can customise the spoken messages below. You can disable specific messages by setting them to nothing\n </Forms.FormText>\n <Forms.FormText>\n The special placeholders <code>{\"{{USER}}\"}</code>, <code>{\"{{DISPLAY_NAME}}\"}</code>, <code>{\"{{NICKNAME}}\"}</code> and <code>{\"{{CHANNEL}}\"}</code>{\" \"}\n will be replaced with the user's name (nothing if it's yourself), the user's display name, the user's nickname on current server and the channel's name respectively\n </Forms.FormText>\n {hasEnglishVoices && (\n <>\n <Forms.FormTitle className={Margins.top20} tag=\"h3\">Play Example Sounds</Forms.FormTitle>\n <div\n style={{\n display: \"grid\",\n gridTemplateColumns: \"repeat(4, 1fr)\",\n gap: \"1rem\",\n }}\n className={\"vc-narrator-buttons\"}\n >\n {types.map(t => (\n <Button key={t} onClick={() => playSample(s, t)}>\n {wordsToTitle([t])}\n </Button>\n ))}\n </div>\n </>\n )}\n {errorComponent}\n </Forms.FormSection>\n );\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport \"./index.css\";\n\nimport { openNotificationLogModal } from \"@api/Notifications/notificationLog\";\nimport { Settings } from \"@api/Settings\";\nimport ErrorBoundary from \"@components/ErrorBoundary\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\nimport { findExportedComponentLazy } from \"@webpack\";\nimport { Menu, Popout, useState } from \"@webpack/common\";\nimport type { ReactNode } from \"react\";\n\nconst HeaderBarIcon = findExportedComponentLazy(\"Icon\", \"Divider\");\n\nfunction VencordPopout(onClose: () => void) {\n const pluginEntries = [] as ReactNode[];\n\n for (const plugin of Object.values(Vencord.Plugins.plugins)) {\n if (plugin.toolboxActions && Vencord.Plugins.isPluginEnabled(plugin.name)) {\n pluginEntries.push(\n <Menu.MenuGroup\n label={plugin.name}\n key={`vc-toolbox-${plugin.name}`}\n >\n {Object.entries(plugin.toolboxActions).map(([text, action]) => {\n const key = `vc-toolbox-${plugin.name}-${text}`;\n\n return (\n <Menu.MenuItem\n id={key}\n key={key}\n label={text}\n action={action}\n />\n );\n })}\n </Menu.MenuGroup>\n );\n }\n }\n\n return (\n <Menu.Menu\n navId=\"vc-toolbox\"\n onClose={onClose}\n >\n <Menu.MenuItem\n id=\"vc-toolbox-notifications\"\n label=\"Open Notification Log\"\n action={openNotificationLogModal}\n />\n <Menu.MenuCheckboxItem\n id=\"vc-toolbox-quickcss-toggle\"\n checked={Settings.useQuickCss}\n label={\"Enable QuickCSS\"}\n action={() => {\n Settings.useQuickCss = !Settings.useQuickCss;\n onClose();\n }}\n />\n <Menu.MenuItem\n id=\"vc-toolbox-quickcss\"\n label=\"Open QuickCSS\"\n action={() => VencordNative.quickCss.openEditor()}\n />\n {...pluginEntries}\n </Menu.Menu>\n );\n}\n\nfunction VencordPopoutIcon(isShown: boolean) {\n return (\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 27 27\" width={24} height={24}>\n <path fill=\"currentColor\" d={isShown ? \"M9 0h1v1h1v2h1v2h3V3h1V1h1V0h1v2h1v2h1v7h-1v-1h-3V9h1V6h-1v4h-3v1h1v-1h2v1h3v1h-1v1h-3v2h1v1h1v1h1v3h-1v4h-2v-1h-1v-4h-1v4h-1v1h-2v-4H9v-3h1v-1h1v-1h1v-2H9v-1H8v-1h3V6h-1v3h1v1H8v1H7V4h1V2h1M5 19h2v1h1v1h1v3H4v-1h2v-1H4v-2h1m15-1h2v1h1v2h-2v1h2v1h-5v-3h1v-1h1m4 3h4v1h-4\" : \"M0 0h7v1H6v1H5v1H4v1H3v1H2v1h5v1H0V6h1V5h1V4h1V3h1V2h1V1H0m13 2h5v1h-1v1h-1v1h-1v1h3v1h-5V7h1V6h1V5h1V4h-3m8 5h1v5h1v-1h1v1h-1v1h1v-1h1v1h-1v3h-1v1h-2v1h-1v1h1v-1h2v-1h1v2h-1v1h-2v1h-1v-1h-1v1h-6v-1h-1v-1h-1v-2h1v1h2v1h3v1h1v-1h-1v-1h-3v-1h-4v-4h1v-2h1v-1h1v-1h1v2h1v1h1v-1h1v1h-1v1h2v-2h1v-2h1v-1h1M8 14h2v1H9v4h1v2h1v1h1v1h1v1h4v1h-6v-1H5v-1H4v-5h1v-1h1v-2h2m17 3h1v3h-1v1h-1v1h-1v2h-2v-2h2v-1h1v-1h1m1 0h1v3h-1v1h-2v-1h1v-1h1\"} />\n </svg>\n );\n}\n\nfunction VencordPopoutButton() {\n const [show, setShow] = useState(false);\n\n return (\n <Popout\n position=\"bottom\"\n align=\"right\"\n animation={Popout.Animation.NONE}\n shouldShow={show}\n onRequestClose={() => setShow(false)}\n renderPopout={() => VencordPopout(() => setShow(false))}\n >\n {(_, { isShown }) => (\n <HeaderBarIcon\n className=\"vc-toolbox-btn\"\n onClick={() => setShow(v => !v)}\n tooltip={isShown ? null : \"Vencord Toolbox\"}\n icon={() => VencordPopoutIcon(isShown)}\n selected={isShown}\n />\n )}\n </Popout>\n );\n}\n\nfunction ToolboxFragmentWrapper({ children }: { children: ReactNode[]; }) {\n children.splice(\n children.length - 1, 0,\n <ErrorBoundary noop={true}>\n <VencordPopoutButton />\n </ErrorBoundary>\n );\n\n return <>{children}</>;\n}\n\nexport default definePlugin({\n name: \"VencordToolbox\",\n description: \"Adds a button next to the inbox button in the channel header that houses Vencord quick actions\",\n authors: [Devs.Ven, Devs.AutumnVN],\n\n patches: [\n {\n find: \"toolbar:function\",\n replacement: {\n match: /(?<=toolbar:function.{0,100}\\()\\i.Fragment,/,\n replace: \"$self.ToolboxFragmentWrapper,\"\n }\n }\n ],\n\n ToolboxFragmentWrapper: ErrorBoundary.wrap(ToolboxFragmentWrapper, {\n fallback: () => <p style={{ color: \"red\" }}>Failed to render :(</p>\n })\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { addContextMenuPatch, NavContextMenuPatchCallback, removeContextMenuPatch } from \"@api/ContextMenu\";\nimport { definePluginSettings } from \"@api/Settings\";\nimport { ImageIcon } from \"@components/Icons\";\nimport { Devs } from \"@utils/constants\";\nimport { openImageModal } from \"@utils/discord\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { findByPropsLazy } from \"@webpack\";\nimport { GuildMemberStore, Menu } from \"@webpack/common\";\nimport type { Channel, Guild, User } from \"discord-types/general\";\n\nconst BannerStore = findByPropsLazy(\"getGuildBannerURL\");\n\ninterface UserContextProps {\n channel: Channel;\n guildId?: string;\n user: User;\n}\n\ninterface GuildContextProps {\n guild?: Guild;\n}\n\nconst settings = definePluginSettings({\n format: {\n type: OptionType.SELECT,\n description: \"Choose the image format to use for non animated images. Animated images will always use .gif\",\n options: [\n {\n label: \"webp\",\n value: \"webp\",\n default: true\n },\n {\n label: \"png\",\n value: \"png\",\n },\n {\n label: \"jpg\",\n value: \"jpg\",\n }\n ]\n },\n imgSize: {\n type: OptionType.SELECT,\n description: \"The image size to use\",\n options: [\"128\", \"256\", \"512\", \"1024\", \"2048\", \"4096\"].map(n => ({ label: n, value: n, default: n === \"1024\" }))\n }\n});\n\nfunction openImage(url: string) {\n const format = url.startsWith(\"/\") ? \"png\" : settings.store.format;\n\n const u = new URL(url, window.location.href);\n u.searchParams.set(\"size\", settings.store.imgSize);\n u.pathname = u.pathname.replace(/\\.(png|jpe?g|webp)$/, `.${format}`);\n url = u.toString();\n\n u.searchParams.set(\"size\", \"4096\");\n const originalUrl = u.toString();\n\n openImageModal(url, {\n original: originalUrl,\n height: 256\n });\n}\n\nconst UserContext: NavContextMenuPatchCallback = (children, { user, guildId }: UserContextProps) => () => {\n if (!user) return;\n const memberAvatar = GuildMemberStore.getMember(guildId!, user.id)?.avatar || null;\n\n children.splice(-1, 0, (\n <Menu.MenuGroup>\n <Menu.MenuItem\n id=\"view-avatar\"\n label=\"View Avatar\"\n action={() => openImage(BannerStore.getUserAvatarURL(user, true))}\n icon={ImageIcon}\n />\n {memberAvatar && (\n <Menu.MenuItem\n id=\"view-server-avatar\"\n label=\"View Server Avatar\"\n action={() => openImage(BannerStore.getGuildMemberAvatarURLSimple({\n userId: user.id,\n avatar: memberAvatar,\n guildId,\n canAnimate: true\n }, true))}\n icon={ImageIcon}\n />\n )}\n </Menu.MenuGroup>\n ));\n};\n\nconst GuildContext: NavContextMenuPatchCallback = (children, { guild }: GuildContextProps) => () => {\n if (!guild) return;\n\n const { id, icon, banner } = guild;\n if (!banner && !icon) return;\n\n children.splice(-1, 0, (\n <Menu.MenuGroup>\n {icon ? (\n <Menu.MenuItem\n id=\"view-icon\"\n label=\"View Icon\"\n action={() =>\n openImage(BannerStore.getGuildIconURL({\n id,\n icon,\n canAnimate: true\n }))\n }\n icon={ImageIcon}\n />\n ) : null}\n {banner ? (\n <Menu.MenuItem\n id=\"view-banner\"\n label=\"View Banner\"\n action={() =>\n openImage(BannerStore.getGuildBannerURL({\n id,\n banner,\n }, true))\n }\n icon={ImageIcon}\n />\n ) : null}\n </Menu.MenuGroup>\n ));\n};\n\nexport default definePlugin({\n name: \"ViewIcons\",\n authors: [Devs.Ven, Devs.TheKodeToad, Devs.Nuckyz],\n description: \"Makes avatars and banners in user profiles clickable, and adds View Icon/Banner entries in the user and server context menu\",\n tags: [\"ImageUtilities\"],\n\n settings,\n\n openImage,\n\n start() {\n addContextMenuPatch(\"user-context\", UserContext);\n addContextMenuPatch(\"guild-context\", GuildContext);\n },\n\n stop() {\n removeContextMenuPatch(\"user-context\", UserContext);\n removeContextMenuPatch(\"guild-context\", GuildContext);\n },\n\n patches: [\n // Make pfps clickable\n {\n find: \"User Profile Modal - Context Menu\",\n replacement: {\n match: /\\{src:(\\i)(?=,avatarDecoration)/,\n replace: \"{src:$1,onClick:()=>$self.openImage($1)\"\n }\n },\n // Make banners clickable\n {\n find: \".NITRO_BANNER,\",\n replacement: {\n // style: { backgroundImage: shouldShowBanner ? \"url(\".concat(bannerUrl,\n match: /style:\\{(?=backgroundImage:(\\i&&\\i)\\?\"url\\(\"\\.concat\\((\\i),)/,\n replace:\n // onClick: () => shouldShowBanner && ev.target.style.backgroundImage && openImage(bannerUrl), style: { cursor: shouldShowBanner ? \"pointer\" : void 0,\n 'onClick:ev=>$1&&ev.target.style.backgroundImage&&$self.openImage($2),style:{cursor:$1?\"pointer\":void 0,'\n }\n },\n {\n find: \".avatarPositionPanel\",\n replacement: {\n match: /(?<=avatarWrapperNonUserBot.{0,50})onClick:(\\i\\|\\|\\i)\\?void 0(?<=,avatarSrc:(\\i).+?)/,\n replace: \"style:($1)?{cursor:\\\"pointer\\\"}:{},onClick:$1?()=>{$self.openImage($2)}\"\n }\n }\n ]\n});\n", "/*\n * Vencord, a Discord client mod\n * Copyright (c) 2023 Vendicated and contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport { findByPropsLazy } from \"@webpack\";\nimport { Parser } from \"@webpack/common\";\n\nconst CodeContainerClasses = findByPropsLazy(\"markup\", \"codeContainer\");\n\n/**\n * Renders code in a Discord codeblock\n */\nexport function CodeBlock(props: { content?: string, lang: string; }) {\n return (\n <div className={CodeContainerClasses.markup}>\n {Parser.defaultRules.codeBlock.react(props, null, {})}\n </div>\n );\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { addContextMenuPatch, NavContextMenuPatchCallback, removeContextMenuPatch } from \"@api/ContextMenu\";\nimport { addButton, removeButton } from \"@api/MessagePopover\";\nimport { definePluginSettings } from \"@api/Settings\";\nimport { CodeBlock } from \"@components/CodeBlock\";\nimport ErrorBoundary from \"@components/ErrorBoundary\";\nimport { Flex } from \"@components/Flex\";\nimport { Devs } from \"@utils/constants\";\nimport { Margins } from \"@utils/margins\";\nimport { copyWithToast } from \"@utils/misc\";\nimport { closeModal, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalRoot, ModalSize, openModal } from \"@utils/modal\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { Button, ChannelStore, Forms, Menu, Text } from \"@webpack/common\";\nimport { Message } from \"discord-types/general\";\n\n\nconst CopyIcon = () => {\n return <svg viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\" width=\"18\" height=\"18\">\n <path d=\"M12.9297 3.25007C12.7343 3.05261 12.4154 3.05226 12.2196 3.24928L11.5746 3.89824C11.3811 4.09297 11.3808 4.40733 11.5739 4.60245L16.5685 9.64824C16.7614 9.84309 16.7614 10.1569 16.5685 10.3517L11.5739 15.3975C11.3808 15.5927 11.3811 15.907 11.5746 16.1017L12.2196 16.7507C12.4154 16.9477 12.7343 16.9474 12.9297 16.7499L19.2604 10.3517C19.4532 10.1568 19.4532 9.84314 19.2604 9.64832L12.9297 3.25007Z\" />\n <path d=\"M8.42616 4.60245C8.6193 4.40733 8.61898 4.09297 8.42545 3.89824L7.78047 3.24928C7.58466 3.05226 7.26578 3.05261 7.07041 3.25007L0.739669 9.64832C0.5469 9.84314 0.546901 10.1568 0.739669 10.3517L7.07041 16.7499C7.26578 16.9474 7.58465 16.9477 7.78047 16.7507L8.42545 16.1017C8.61898 15.907 8.6193 15.5927 8.42616 15.3975L3.43155 10.3517C3.23869 10.1569 3.23869 9.84309 3.43155 9.64824L8.42616 4.60245Z\" />\n </svg>;\n};\n\nfunction sortObject<T extends object>(obj: T): T {\n return Object.fromEntries(Object.entries(obj).sort(([k1], [k2]) => k1.localeCompare(k2))) as T;\n}\n\nfunction cleanMessage(msg: Message) {\n const clone = sortObject(JSON.parse(JSON.stringify(msg)));\n for (const key of [\n \"email\",\n \"phone\",\n \"mfaEnabled\",\n \"personalConnectionId\"\n ]) delete clone.author[key];\n\n // message logger added properties\n const cloneAny = clone as any;\n delete cloneAny.editHistory;\n delete cloneAny.deleted;\n cloneAny.attachments?.forEach(a => delete a.deleted);\n\n return clone;\n}\n\nfunction openViewRawModal(json: string, type: string, msgContent?: string) {\n const key = openModal(props => (\n <ErrorBoundary>\n <ModalRoot {...props} size={ModalSize.LARGE}>\n <ModalHeader>\n <Text variant=\"heading-lg/semibold\" style={{ flexGrow: 1 }}>View Raw</Text>\n <ModalCloseButton onClick={() => closeModal(key)} />\n </ModalHeader>\n <ModalContent>\n <div style={{ padding: \"16px 0\" }}>\n {!!msgContent && (\n <>\n <Forms.FormTitle tag=\"h5\">Content</Forms.FormTitle>\n <CodeBlock content={msgContent} lang=\"\" />\n <Forms.FormDivider className={Margins.bottom20} />\n </>\n )}\n\n <Forms.FormTitle tag=\"h5\">{type} Data</Forms.FormTitle>\n <CodeBlock content={json} lang=\"json\" />\n </div>\n </ModalContent >\n <ModalFooter>\n <Flex cellSpacing={10}>\n <Button onClick={() => copyWithToast(json, `${type} data copied to clipboard!`)}>\n Copy {type} JSON\n </Button>\n {!!msgContent && (\n <Button onClick={() => copyWithToast(msgContent, \"Content copied to clipboard!\")}>\n Copy Raw Content\n </Button>\n )}\n </Flex>\n </ModalFooter>\n </ModalRoot >\n </ErrorBoundary >\n ));\n}\n\nfunction openViewRawModalMessage(msg: Message) {\n msg = cleanMessage(msg);\n const msgJson = JSON.stringify(msg, null, 4);\n\n return openViewRawModal(msgJson, \"Message\", msg.content);\n}\n\nconst settings = definePluginSettings({\n clickMethod: {\n description: \"Change the button to view the raw content/data of any message.\",\n type: OptionType.SELECT,\n options: [\n { label: \"Left Click to view the raw content.\", value: \"Left\", default: true },\n { label: \"Right click to view the raw content.\", value: \"Right\" }\n ]\n }\n});\n\nfunction MakeContextCallback(name: string) {\n const callback: NavContextMenuPatchCallback = (children, props) => () => {\n if ((name === \"Guild\" && !props.guild) || (name === \"User\" && !props.user)) return;\n const lastChild = children.at(-1);\n if (lastChild?.key === \"developer-actions\") {\n const p = lastChild.props;\n if (!Array.isArray(p.children))\n p.children = [p.children];\n ({ children } = p);\n }\n\n children.splice(-1, 0,\n <Menu.MenuItem\n id={`vc-view-${name.toLowerCase()}-raw`}\n label=\"View Raw\"\n action={() => openViewRawModal(JSON.stringify(props[name.toLowerCase()], null, 4), name)}\n icon={CopyIcon}\n />\n );\n };\n return callback;\n}\n\n\nexport default definePlugin({\n name: \"ViewRaw\",\n description: \"Copy and view the raw content/data of any message, channel or guild\",\n authors: [Devs.KingFish, Devs.Ven, Devs.rad, Devs.ImLvna],\n dependencies: [\"MessagePopoverAPI\"],\n settings,\n\n start() {\n addButton(\"ViewRaw\", msg => {\n const handleClick = () => {\n if (settings.store.clickMethod === \"Right\") {\n copyWithToast(msg.content);\n } else {\n openViewRawModalMessage(msg);\n }\n };\n\n const handleContextMenu = e => {\n if (settings.store.clickMethod === \"Left\") {\n e.preventDefault();\n e.stopPropagation();\n copyWithToast(msg.content);\n } else {\n e.preventDefault();\n e.stopPropagation();\n openViewRawModalMessage(msg);\n }\n };\n\n const label = settings.store.clickMethod === \"Right\"\n ? \"Copy Raw (Left Click) / View Raw (Right Click)\"\n : \"View Raw (Left Click) / Copy Raw (Right Click)\";\n\n return {\n label,\n icon: CopyIcon,\n message: msg,\n channel: ChannelStore.getChannel(msg.channel_id),\n onClick: handleClick,\n onContextMenu: handleContextMenu\n };\n });\n\n addContextMenuPatch(\"guild-context\", MakeContextCallback(\"Guild\"));\n addContextMenuPatch(\"channel-context\", MakeContextCallback(\"Channel\"));\n addContextMenuPatch(\"user-context\", MakeContextCallback(\"User\"));\n },\n\n stop() {\n removeButton(\"CopyRawMessage\");\n removeContextMenuPatch(\"guild-context\", MakeContextCallback(\"Guild\"));\n removeContextMenuPatch(\"channel-context\", MakeContextCallback(\"Channel\"));\n removeContextMenuPatch(\"user-context\", MakeContextCallback(\"User\"));\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { definePluginSettings } from \"@api/Settings\";\nimport { OptionType } from \"@utils/types\";\n\nexport const settings = definePluginSettings({\n noiseSuppression: {\n type: OptionType.BOOLEAN,\n description: \"Noise Suppression\",\n default: true,\n },\n echoCancellation: {\n type: OptionType.BOOLEAN,\n description: \"Echo Cancellation\",\n default: true,\n },\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { PluginNative } from \"@utils/types\";\nimport { Button, showToast, Toasts, useState } from \"@webpack/common\";\n\nimport type { VoiceRecorder } from \".\";\nimport { settings } from \"./settings\";\n\nconst Native = VencordNative.pluginHelpers.VoiceMessages as PluginNative<typeof import(\"./native\")>;\n\nexport const VoiceRecorderDesktop: VoiceRecorder = ({ setAudioBlob, onRecordingChange }) => {\n const [recording, setRecording] = useState(false);\n\n const changeRecording = (recording: boolean) => {\n setRecording(recording);\n onRecordingChange?.(recording);\n };\n\n function toggleRecording() {\n const discordVoice = DiscordNative.nativeModules.requireModule(\"discord_voice\");\n const nowRecording = !recording;\n\n if (nowRecording) {\n discordVoice.startLocalAudioRecording(\n {\n echoCancellation: settings.store.echoCancellation,\n noiseCancellation: settings.store.noiseSuppression,\n },\n (success: boolean) => {\n if (success)\n changeRecording(true);\n else\n showToast(\"Failed to start recording\", Toasts.Type.FAILURE);\n }\n );\n } else {\n discordVoice.stopLocalAudioRecording(async (filePath: string) => {\n if (filePath) {\n const buf = await Native.readRecording(filePath);\n if (buf)\n setAudioBlob(new Blob([buf], { type: \"audio/ogg; codecs=opus\" }));\n else\n showToast(\"Failed to finish recording\", Toasts.Type.FAILURE);\n }\n changeRecording(false);\n });\n }\n }\n\n return (\n <Button onClick={toggleRecording}>\n {recording ? \"Stop\" : \"Start\"} recording\n </Button>\n );\n};\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { classNameFactory } from \"@api/Styles\";\n\nexport const cl = classNameFactory(\"vc-vmsg-\");\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { useTimer } from \"@utils/react\";\nimport { findComponentByCodeLazy } from \"@webpack\";\n\nimport { cl } from \"./utils\";\n\ninterface VoiceMessageProps {\n src: string;\n waveform: string;\n}\nconst VoiceMessage = findComponentByCodeLazy<VoiceMessageProps>(\"waveform:\", \"onVolumeChange\");\n\nexport type VoicePreviewOptions = {\n src?: string;\n waveform: string;\n recording?: boolean;\n};\nexport const VoicePreview = ({\n src,\n waveform,\n recording,\n}: VoicePreviewOptions) => {\n const durationMs = useTimer({\n deps: [recording]\n });\n\n const durationSeconds = recording ? Math.floor(durationMs / 1000) : 0;\n const durationDisplay = Math.floor(durationSeconds / 60) + \":\" + (durationSeconds % 60).toString().padStart(2, \"0\");\n\n if (src && !recording)\n return <VoiceMessage key={src} src={src} waveform={waveform} />;\n\n return (\n <div className={cl(\"preview\", recording ? \"preview-recording\" : [])}>\n <div className={cl(\"preview-indicator\")} />\n <div className={cl(\"preview-time\")}>{durationDisplay}</div>\n <div className={cl(\"preview-label\")}>{recording ? \"RECORDING\" : \"----\"}</div>\n </div>\n );\n};\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Button, useState } from \"@webpack/common\";\n\nimport type { VoiceRecorder } from \".\";\nimport { settings } from \"./settings\";\n\nexport const VoiceRecorderWeb: VoiceRecorder = ({ setAudioBlob, onRecordingChange }) => {\n const [recording, setRecording] = useState(false);\n const [paused, setPaused] = useState(false);\n const [recorder, setRecorder] = useState<MediaRecorder>();\n const [chunks, setChunks] = useState<Blob[]>([]);\n\n const changeRecording = (recording: boolean) => {\n setRecording(recording);\n onRecordingChange?.(recording);\n };\n\n function toggleRecording() {\n const nowRecording = !recording;\n\n if (nowRecording) {\n navigator.mediaDevices.getUserMedia({\n audio: {\n echoCancellation: settings.store.echoCancellation,\n noiseSuppression: settings.store.noiseSuppression,\n }\n }).then(stream => {\n const chunks = [] as Blob[];\n setChunks(chunks);\n\n const recorder = new MediaRecorder(stream);\n setRecorder(recorder);\n recorder.addEventListener(\"dataavailable\", e => {\n chunks.push(e.data);\n });\n recorder.start();\n\n changeRecording(true);\n });\n } else {\n if (recorder) {\n recorder.addEventListener(\"stop\", () => {\n setAudioBlob(new Blob(chunks, { type: \"audio/ogg; codecs=opus\" }));\n\n changeRecording(false);\n });\n recorder.stop();\n }\n }\n }\n\n return (\n <>\n <Button onClick={toggleRecording}>\n {recording ? \"Stop\" : \"Start\"} recording\n </Button>\n\n <Button\n disabled={!recording}\n onClick={() => {\n setPaused(!paused);\n if (paused) recorder?.resume();\n else recorder?.pause();\n }}\n >\n {paused ? \"Resume\" : \"Pause\"} recording\n </Button>\n </>\n );\n};\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport \"./styles.css\";\n\nimport { addContextMenuPatch, NavContextMenuPatchCallback, removeContextMenuPatch } from \"@api/ContextMenu\";\nimport { Microphone } from \"@components/Icons\";\nimport { Devs } from \"@utils/constants\";\nimport { ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, openModal } from \"@utils/modal\";\nimport { useAwaiter } from \"@utils/react\";\nimport definePlugin from \"@utils/types\";\nimport { chooseFile } from \"@utils/web\";\nimport { findByPropsLazy, findStoreLazy } from \"@webpack\";\nimport { Button, FluxDispatcher, Forms, lodash, Menu, MessageActions, PermissionsBits, PermissionStore, RestAPI, SelectedChannelStore, showToast, SnowflakeUtils, Toasts, useEffect, useState } from \"@webpack/common\";\nimport { ComponentType } from \"react\";\n\nimport { VoiceRecorderDesktop } from \"./DesktopRecorder\";\nimport { settings } from \"./settings\";\nimport { cl } from \"./utils\";\nimport { VoicePreview } from \"./VoicePreview\";\nimport { VoiceRecorderWeb } from \"./WebRecorder\";\n\nconst CloudUtils = findByPropsLazy(\"CloudUpload\");\nconst PendingReplyStore = findStoreLazy(\"PendingReplyStore\");\nconst OptionClasses = findByPropsLazy(\"optionName\", \"optionIcon\", \"optionLabel\");\n\nexport type VoiceRecorder = ComponentType<{\n setAudioBlob(blob: Blob): void;\n onRecordingChange?(recording: boolean): void;\n}>;\n\nconst VoiceRecorder = IS_DISCORD_DESKTOP ? VoiceRecorderDesktop : VoiceRecorderWeb;\n\nexport default definePlugin({\n name: \"VoiceMessages\",\n description: \"Allows you to send voice messages like on mobile. To do so, right click the upload button and click Send Voice Message\",\n authors: [Devs.Ven, Devs.Vap, Devs.Nickyux],\n settings,\n\n start() {\n addContextMenuPatch(\"channel-attach\", ctxMenuPatch);\n },\n\n stop() {\n removeContextMenuPatch(\"channel-attach\", ctxMenuPatch);\n }\n});\n\ntype AudioMetadata = {\n waveform: string,\n duration: number,\n};\nconst EMPTY_META: AudioMetadata = {\n waveform: \"AAAAAAAAAAAA\",\n duration: 1,\n};\n\nfunction sendAudio(blob: Blob, meta: AudioMetadata) {\n const channelId = SelectedChannelStore.getChannelId();\n const reply = PendingReplyStore.getPendingReply(channelId);\n if (reply) FluxDispatcher.dispatch({ type: \"DELETE_PENDING_REPLY\", channelId });\n\n const upload = new CloudUtils.CloudUpload({\n file: new File([blob], \"voice-message.ogg\", { type: \"audio/ogg; codecs=opus\" }),\n isClip: false,\n isThumbnail: false,\n platform: 1,\n }, channelId, false, 0);\n\n upload.on(\"complete\", () => {\n RestAPI.post({\n url: `/channels/${channelId}/messages`,\n body: {\n flags: 1 << 13,\n channel_id: channelId,\n content: \"\",\n nonce: SnowflakeUtils.fromTimestamp(Date.now()),\n sticker_ids: [],\n type: 0,\n attachments: [{\n id: \"0\",\n filename: upload.filename,\n uploaded_filename: upload.uploadedFilename,\n waveform: meta.waveform,\n duration_secs: meta.duration,\n }],\n message_reference: reply ? MessageActions.getSendMessageOptionsForReply(reply)?.messageReference : null,\n }\n });\n });\n upload.on(\"error\", () => showToast(\"Failed to upload voice message\", Toasts.Type.FAILURE));\n\n upload.upload();\n}\n\nfunction useObjectUrl() {\n const [url, setUrl] = useState<string>();\n const setWithFree = (blob: Blob) => {\n if (url)\n URL.revokeObjectURL(url);\n setUrl(URL.createObjectURL(blob));\n };\n\n return [url, setWithFree] as const;\n}\n\nfunction Modal({ modalProps }: { modalProps: ModalProps; }) {\n const [isRecording, setRecording] = useState(false);\n const [blob, setBlob] = useState<Blob>();\n const [blobUrl, setBlobUrl] = useObjectUrl();\n\n useEffect(() => () => {\n if (blobUrl)\n URL.revokeObjectURL(blobUrl);\n }, [blobUrl]);\n\n const [meta] = useAwaiter(async () => {\n if (!blob) return EMPTY_META;\n\n const audioContext = new AudioContext();\n const audioBuffer = await audioContext.decodeAudioData(await blob.arrayBuffer());\n const channelData = audioBuffer.getChannelData(0);\n\n // average the samples into much lower resolution bins, maximum of 256 total bins\n const bins = new Uint8Array(lodash.clamp(Math.floor(audioBuffer.duration * 10), Math.min(32, channelData.length), 256));\n const samplesPerBin = Math.floor(channelData.length / bins.length);\n\n // Get root mean square of each bin\n for (let binIdx = 0; binIdx < bins.length; binIdx++) {\n let squares = 0;\n for (let sampleOffset = 0; sampleOffset < samplesPerBin; sampleOffset++) {\n const sampleIdx = binIdx * samplesPerBin + sampleOffset;\n squares += channelData[sampleIdx] ** 2;\n }\n bins[binIdx] = ~~(Math.sqrt(squares / samplesPerBin) * 0xFF);\n }\n\n // Normalize bins with easing\n const maxBin = Math.max(...bins);\n const ratio = 1 + (0xFF / maxBin - 1) * Math.min(1, 100 * (maxBin / 0xFF) ** 3);\n for (let i = 0; i < bins.length; i++) bins[i] = Math.min(0xFF, ~~(bins[i] * ratio));\n\n return {\n waveform: window.btoa(String.fromCharCode(...bins)),\n duration: audioBuffer.duration,\n };\n }, {\n deps: [blob],\n fallbackValue: EMPTY_META,\n });\n\n return (\n <ModalRoot {...modalProps}>\n <ModalHeader>\n <Forms.FormTitle>Record Voice Message</Forms.FormTitle>\n </ModalHeader>\n\n <ModalContent className={cl(\"modal\")}>\n <div className={cl(\"buttons\")}>\n <VoiceRecorder\n setAudioBlob={blob => {\n setBlob(blob);\n setBlobUrl(blob);\n }}\n onRecordingChange={setRecording}\n />\n\n <Button\n onClick={async () => {\n const file = await chooseFile(\"audio/*\");\n if (file) {\n setBlob(file);\n setBlobUrl(file);\n }\n }}\n >\n Upload File\n </Button>\n </div>\n\n <Forms.FormTitle>Preview</Forms.FormTitle>\n <VoicePreview\n src={blobUrl}\n waveform={meta.waveform}\n recording={isRecording}\n />\n\n </ModalContent>\n\n <ModalFooter>\n <Button\n disabled={!blob}\n onClick={() => {\n sendAudio(blob!, meta);\n modalProps.onClose();\n showToast(\"Now sending voice message... Please be patient\", Toasts.Type.MESSAGE);\n }}\n >\n Send\n </Button>\n </ModalFooter>\n </ModalRoot>\n );\n}\n\nconst ctxMenuPatch: NavContextMenuPatchCallback = (children, props) => () => {\n if (props.channel.guild_id && !(PermissionStore.can(PermissionsBits.SEND_VOICE_MESSAGES, props.channel) && PermissionStore.can(PermissionsBits.SEND_MESSAGES, props.channel))) return;\n\n children.push(\n <Menu.MenuItem\n id=\"vc-send-vmsg\"\n label={\n <div className={OptionClasses.optionLabel}>\n <Microphone className={OptionClasses.optionIcon} height={24} width={24} />\n <div className={OptionClasses.optionName}>Send voice message</div>\n </div>\n }\n action={() => openModal(modalProps => <Modal modalProps={modalProps} />)}\n />\n );\n};\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { definePluginSettings } from \"@api/Settings\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin, { OptionType } from \"@utils/types\";\nimport { saveFile } from \"@utils/web\";\nimport { findByPropsLazy } from \"@webpack\";\nimport { Clipboard, ComponentDispatch } from \"@webpack/common\";\n\nconst ctxMenuCallbacks = findByPropsLazy(\"contextMenuCallbackNative\");\n\nasync function fetchImage(url: string) {\n const res = await fetch(url);\n if (res.status !== 200) return;\n\n return await res.blob();\n}\n\n\nconst settings = definePluginSettings({\n // This needs to be all in one setting because to enable any of these, we need to make Discord use their desktop context\n // menu handler instead of the web one, which breaks the other menus that aren't enabled\n addBack: {\n type: OptionType.BOOLEAN,\n description: \"Add back the Discord context menus for images, links and the chat input bar\",\n // Web slate menu has proper spellcheck suggestions and image context menu is also pretty good,\n // so disable this by default. Vesktop just doesn't, so enable by default\n default: IS_VESKTOP,\n restartNeeded: true\n }\n});\n\nexport default definePlugin({\n name: \"WebContextMenus\",\n description: \"Re-adds context menus missing in the web version of Discord: Links & Images (Copy/Open Link/Image), Text Area (Copy, Cut, Paste, SpellCheck)\",\n authors: [Devs.Ven],\n enabledByDefault: true,\n required: IS_VESKTOP,\n\n settings,\n\n start() {\n if (settings.store.addBack) {\n window.removeEventListener(\"contextmenu\", ctxMenuCallbacks.contextMenuCallbackWeb);\n window.addEventListener(\"contextmenu\", ctxMenuCallbacks.contextMenuCallbackNative);\n this.changedListeners = true;\n }\n },\n\n stop() {\n if (this.changedListeners) {\n window.removeEventListener(\"contextmenu\", ctxMenuCallbacks.contextMenuCallbackNative);\n window.addEventListener(\"contextmenu\", ctxMenuCallbacks.contextMenuCallbackWeb);\n }\n },\n\n patches: [\n // Add back Copy & Open Link\n {\n // There is literally no reason for Discord to make this Desktop only.\n // The only thing broken is copy, but they already have a different copy function\n // with web support????\n find: \"open-native-link\",\n replacement: [\n {\n // if (IS_DESKTOP || null == ...)\n match: /if\\(!\\i\\.\\i\\|\\|null==/,\n replace: \"if(null==\"\n },\n // Fix silly Discord calling the non web support copy\n {\n match: /\\i\\.\\i\\.copy/,\n replace: \"Vencord.Webpack.Common.Clipboard.copy\"\n }\n ]\n },\n\n // Add back Copy & Save Image\n {\n find: 'id:\"copy-image\"',\n replacement: [\n {\n // if (!IS_WEB || null ==\n match: /!\\i\\.isPlatformEmbedded/,\n replace: \"false\"\n },\n {\n match: /return\\s*?\\[\\i\\.\\i\\.canCopyImage\\(\\)/,\n replace: \"return [true\"\n },\n {\n match: /(?<=COPY_IMAGE_MENU_ITEM,)action:/,\n replace: \"action:()=>$self.copyImage(arguments[0]),oldAction:\"\n },\n {\n match: /(?<=SAVE_IMAGE_MENU_ITEM,)action:/,\n replace: \"action:()=>$self.saveImage(arguments[0]),oldAction:\"\n },\n ]\n },\n\n // Add back image context menu\n {\n find: 'navId:\"image-context\"',\n all: true,\n predicate: () => settings.store.addBack,\n replacement: {\n // return IS_DESKTOP ? React.createElement(Menu, ...)\n match: /return \\i\\.\\i(?=\\?|&&)/,\n replace: \"return true\"\n }\n },\n\n // Add back link context menu\n {\n find: '\"interactionUsernameProfile\"',\n predicate: () => settings.store.addBack,\n replacement: {\n match: /if\\((?=\"A\"===\\i\\.tagName&&\"\"!==\\i\\.textContent)/,\n replace: \"if(false&&\"\n }\n },\n\n // Add back slate / text input context menu\n {\n find: 'getElementById(\"slate-toolbar\"',\n predicate: () => settings.store.addBack,\n replacement: {\n match: /(?<=handleContextMenu\\(\\i\\)\\{.{0,200}isPlatformEmbedded)\\?/,\n replace: \"||true?\"\n }\n },\n {\n find: \".SLASH_COMMAND_SUGGESTIONS_TOGGLED,{\",\n predicate: () => settings.store.addBack,\n replacement: [\n {\n // if (!IS_DESKTOP) return null;\n match: /if\\(!\\i\\.\\i\\)return null;/,\n replace: \"\"\n },\n {\n // Change calls to DiscordNative.clipboard to us instead\n match: /\\b\\i\\.\\i\\.(copy|cut|paste)/g,\n replace: \"$self.$1\"\n }\n ]\n },\n {\n find: '\"add-to-dictionary\"',\n predicate: () => settings.store.addBack,\n replacement: {\n match: /let\\{text:\\i=\"\"/,\n replace: \"return [null,null];$&\"\n }\n },\n\n // Add back \"Show My Camera\" context menu\n {\n find: '.default(\"MediaEngineWebRTC\");',\n replacement: {\n match: /supports\\(\\i\\)\\{switch\\(\\i\\)\\{case (\\i).Features/,\n replace: \"$&.DISABLE_VIDEO:return true;case $1.Features\"\n }\n }\n ],\n\n async copyImage(url: string) {\n // Clipboard only supports image/png, jpeg and similar won't work. Thus, we need to convert it to png\n // via canvas first\n const img = new Image();\n img.onload = () => {\n const canvas = document.createElement(\"canvas\");\n canvas.width = img.naturalWidth;\n canvas.height = img.naturalHeight;\n canvas.getContext(\"2d\")!.drawImage(img, 0, 0);\n\n canvas.toBlob(data => {\n navigator.clipboard.write([\n new ClipboardItem({\n \"image/png\": data!\n })\n ]);\n }, \"image/png\");\n };\n img.crossOrigin = \"anonymous\";\n img.src = url;\n },\n\n async saveImage(url: string) {\n const data = await fetchImage(url);\n if (!data) return;\n\n const name = new URL(url).pathname.split(\"/\").pop()!;\n const file = new File([data], name, { type: data.type });\n\n saveFile(file);\n },\n\n copy() {\n const selection = document.getSelection();\n if (!selection) return;\n\n Clipboard.copy(selection.toString());\n },\n\n cut() {\n this.copy();\n ComponentDispatch.dispatch(\"INSERT_TEXT\", { rawText: \"\" });\n },\n\n async paste() {\n const clip = (await navigator.clipboard.read())[0];\n if (!clip) return;\n\n const data = new DataTransfer();\n for (const type of clip.types) {\n if (type === \"image/png\") {\n const file = new File([await clip.getType(type)], \"unknown.png\", { type });\n data.items.add(file);\n } else if (type === \"text/plain\") {\n const blob = await clip.getType(type);\n data.setData(type, await blob.text());\n }\n }\n\n document.dispatchEvent(\n new ClipboardEvent(\"paste\", {\n clipboardData: data\n })\n );\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\nimport { findByPropsLazy } from \"@webpack\";\nimport { ComponentDispatch, FluxDispatcher, NavigationRouter, SelectedGuildStore, SettingsRouter } from \"@webpack/common\";\n\nconst KeyBinds = findByPropsLazy(\"JUMP_TO_GUILD\", \"SERVER_NEXT\");\n\nexport default definePlugin({\n name: \"WebKeybinds\",\n description: \"Re-adds keybinds missing in the web version of Discord: ctrl+t, ctrl+shift+t, ctrl+tab, ctrl+shift+tab, ctrl+1-9, ctrl+,. Only works fully on Vesktop/ArmCord, not inside your browser\",\n authors: [Devs.Ven],\n enabledByDefault: true,\n\n onKey(e: KeyboardEvent) {\n const hasCtrl = e.ctrlKey || (e.metaKey && navigator.platform.includes(\"Mac\"));\n\n if (hasCtrl) switch (e.key) {\n case \"t\":\n case \"T\":\n e.preventDefault();\n if (e.shiftKey) {\n if (SelectedGuildStore.getGuildId()) NavigationRouter.transitionToGuild(\"@me\");\n ComponentDispatch.safeDispatch(\"TOGGLE_DM_CREATE\");\n } else {\n FluxDispatcher.dispatch({\n type: \"QUICKSWITCHER_SHOW\",\n query: \"\",\n queryMode: null\n });\n }\n break;\n case \",\":\n e.preventDefault();\n SettingsRouter.open(\"My Account\");\n break;\n case \"Tab\":\n const handler = e.shiftKey ? KeyBinds.SERVER_PREV : KeyBinds.SERVER_NEXT;\n handler.action(e);\n break;\n default:\n if (e.key >= \"1\" && e.key <= \"9\") {\n e.preventDefault();\n KeyBinds.JUMP_TO_GUILD.action(e, `mod+${e.key}`);\n }\n break;\n }\n },\n\n start() {\n document.addEventListener(\"keydown\", this.onKey);\n },\n\n stop() {\n document.removeEventListener(\"keydown\", this.onKey);\n }\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport ErrorBoundary from \"@components/ErrorBoundary\";\nimport { Devs } from \"@utils/constants\";\nimport { sleep } from \"@utils/misc\";\nimport { Queue } from \"@utils/Queue\";\nimport { useForceUpdater } from \"@utils/react\";\nimport definePlugin from \"@utils/types\";\nimport { findByPropsLazy, findComponentByCodeLazy } from \"@webpack\";\nimport { ChannelStore, FluxDispatcher, React, RestAPI, Tooltip } from \"@webpack/common\";\nimport { CustomEmoji } from \"@webpack/types\";\nimport { Message, ReactionEmoji, User } from \"discord-types/general\";\n\nconst UserSummaryItem = findComponentByCodeLazy(\"defaultRenderUser\", \"showDefaultAvatarsForNullUsers\");\nconst AvatarStyles = findByPropsLazy(\"moreUsers\", \"emptyUser\", \"avatarContainer\", \"clickableAvatar\");\n\nconst queue = new Queue();\nlet reactions: Record<string, ReactionCacheEntry>;\n\nfunction fetchReactions(msg: Message, emoji: ReactionEmoji, type: number) {\n const key = emoji.name + (emoji.id ? `:${emoji.id}` : \"\");\n return RestAPI.get({\n url: `/channels/${msg.channel_id}/messages/${msg.id}/reactions/${key}`,\n query: {\n limit: 100,\n type\n },\n oldFormErrors: true\n })\n .then(res => FluxDispatcher.dispatch({\n type: \"MESSAGE_REACTION_ADD_USERS\",\n channelId: msg.channel_id,\n messageId: msg.id,\n users: res.body,\n emoji,\n reactionType: type\n }))\n .catch(console.error)\n .finally(() => sleep(250));\n}\n\nfunction getReactionsWithQueue(msg: Message, e: ReactionEmoji, type: number) {\n const key = `${msg.id}:${e.name}:${e.id ?? \"\"}:${type}`;\n const cache = reactions[key] ??= { fetched: false, users: {} };\n if (!cache.fetched) {\n queue.unshift(() => fetchReactions(msg, e, type));\n cache.fetched = true;\n }\n\n return cache.users;\n}\n\nfunction makeRenderMoreUsers(users: User[]) {\n return function renderMoreUsers(_label: string, _count: number) {\n return (\n <Tooltip text={users.slice(5).map(u => u.username).join(\", \")} >\n {({ onMouseEnter, onMouseLeave }) => (\n <div\n className={AvatarStyles.moreUsers}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n >\n +{users.length - 5}\n </div>\n )}\n </Tooltip >\n );\n };\n}\n\nfunction handleClickAvatar(event: React.MouseEvent<HTMLElement, MouseEvent>) {\n event.stopPropagation();\n}\n\nexport default definePlugin({\n name: \"WhoReacted\",\n description: \"Renders the avatars of users who reacted to a message\",\n authors: [Devs.Ven, Devs.KannaDev],\n\n patches: [{\n find: \",reactionRef:\",\n replacement: {\n match: /(\\i)\\?null:\\(0,\\i\\.jsx\\)\\(\\i\\.\\i,{className:\\i\\.reactionCount,.*?}\\),/,\n replace: \"$&$1?null:$self.renderUsers(this.props),\"\n }\n }, {\n find: '.displayName=\"MessageReactionsStore\";',\n replacement: {\n match: /(?<=CONNECTION_OPEN:function\\(\\){)(\\i)={}/,\n replace: \"$&;$self.reactions=$1\"\n }\n }],\n\n renderUsers(props: RootObject) {\n return props.message.reactions.length > 10 ? null : (\n <ErrorBoundary noop>\n <this._renderUsers {...props} />\n </ErrorBoundary>\n );\n },\n\n _renderUsers({ message, emoji, type }: RootObject) {\n const forceUpdate = useForceUpdater();\n React.useEffect(() => {\n const cb = (e: any) => {\n if (e.messageId === message.id)\n forceUpdate();\n };\n FluxDispatcher.subscribe(\"MESSAGE_REACTION_ADD_USERS\", cb);\n\n return () => FluxDispatcher.unsubscribe(\"MESSAGE_REACTION_ADD_USERS\", cb);\n }, [message.id]);\n\n const reactions = getReactionsWithQueue(message, emoji, type);\n const users = Object.values(reactions).filter(Boolean) as User[];\n\n for (const user of users) {\n FluxDispatcher.dispatch({\n type: \"USER_UPDATE\",\n user\n });\n }\n\n return (\n <div\n style={{ marginLeft: \"0.5em\", transform: \"scale(0.9)\" }}\n >\n <div onClick={handleClickAvatar}>\n <UserSummaryItem\n users={users}\n guildId={ChannelStore.getChannel(message.channel_id)?.guild_id}\n renderIcon={false}\n max={5}\n showDefaultAvatarsForNullUsers\n showUserPopout\n renderMoreUsers={makeRenderMoreUsers(users)}\n />\n </div>\n </div>\n );\n },\n\n set reactions(value: any) {\n reactions = value;\n }\n});\n\ninterface ReactionCacheEntry {\n fetched: boolean;\n users: Record<string, User>;\n}\n\ninterface RootObject {\n message: Message;\n readOnly: boolean;\n isLurking: boolean;\n isPendingMember: boolean;\n useChatFontScaling: boolean;\n emoji: CustomEmoji;\n count: number;\n burst_user_ids: any[];\n burst_count: number;\n burst_colors: any[];\n burst_me: boolean;\n me: boolean;\n type: number;\n hideEmoji: boolean;\n remainingBurstCurrency: number;\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { ApplicationCommandInputType, ApplicationCommandOptionType, findOption, sendBotMessage } from \"@api/Commands\";\nimport { Devs } from \"@utils/constants\";\nimport definePlugin from \"@utils/types\";\n\nexport default definePlugin({\n name: \"Wikisearch\",\n description: \"Searches Wikipedia for your requested query. (/wikisearch)\",\n authors: [Devs.Samu],\n dependencies: [\"CommandsAPI\"],\n commands: [\n {\n name: \"wikisearch\",\n description: \"Searches Wikipedia for your request.\",\n inputType: ApplicationCommandInputType.BUILT_IN,\n options: [\n {\n name: \"search\",\n description: \"Word to search for\",\n type: ApplicationCommandOptionType.STRING,\n required: true\n },\n ],\n execute: async (_, ctx) => {\n const word = findOption(_, \"search\", \"\");\n\n if (!word) {\n return sendBotMessage(ctx.channel.id, {\n content: \"No word was defined!\"\n });\n }\n\n const dataSearchParams = new URLSearchParams({\n action: \"query\",\n format: \"json\",\n list: \"search\",\n formatversion: \"2\",\n origin: \"*\",\n srsearch: word\n });\n\n const data = await fetch(\"https://en.wikipedia.org/w/api.php?\" + dataSearchParams).then(response => response.json())\n .catch(err => {\n console.log(err);\n sendBotMessage(ctx.channel.id, { content: \"There was an error. Check the console for more info\" });\n return null;\n });\n\n if (!data) return;\n\n if (!data.query?.search?.length) {\n console.log(data);\n return sendBotMessage(ctx.channel.id, { content: \"No results given\" });\n }\n\n const altData = await fetch(`https://en.wikipedia.org/w/api.php?action=query&format=json&prop=info%7Cdescription%7Cimages%7Cimageinfo%7Cpageimages&list=&meta=&indexpageids=1&pageids=${data.query.search[0].pageid}&formatversion=2&origin=*`)\n .then(res => res.json())\n .then(data => data.query.pages[0])\n .catch(err => {\n console.log(err);\n sendBotMessage(ctx.channel.id, { content: \"There was an error. Check the console for more info\" });\n return null;\n });\n\n if (!altData) return;\n\n const thumbnailData = altData.thumbnail;\n\n const thumbnail = thumbnailData && {\n url: thumbnailData.source.replace(/(50px-)/ig, \"1000px-\"),\n height: thumbnailData.height * 100,\n width: thumbnailData.width * 100\n };\n\n sendBotMessage(ctx.channel.id, {\n embeds: [\n {\n type: \"rich\",\n title: data.query.search[0].title,\n url: `https://wikipedia.org/w/index.php?curid=${data.query.search[0].pageid}`,\n color: \"0x8663BE\",\n description: data.query.search[0].snippet.replace(/(&nbsp;|<([^>]+)>)/ig, \"\").replace(/(&quot;)/ig, \"\\\"\") + \"...\",\n image: thumbnail,\n footer: {\n text: \"Powered by the Wikimedia API\",\n },\n }\n ] as any\n });\n }\n }\n ]\n});\n", "/*\n * Vencord, a Discord client mod\n * Copyright (c) 2023 Vendicated and contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport { definePluginSettings } from \"@api/Settings\";\nimport { makeRange } from \"@components/PluginSettings/components\";\nimport { Devs } from \"@utils/constants\";\nimport { Logger } from \"@utils/Logger\";\nimport definePlugin, { OptionType, PluginNative } from \"@utils/types\";\nimport { findByPropsLazy } from \"@webpack\";\nimport { ChannelStore, GuildStore, UserStore } from \"@webpack/common\";\nimport type { Channel, Embed, GuildMember, MessageAttachment, User } from \"discord-types/general\";\n\nconst enum ChannelTypes {\n DM = 1,\n GROUP_DM = 3\n}\n\ninterface Message {\n guild_id: string,\n attachments: MessageAttachment[],\n author: User,\n channel_id: string,\n components: any[],\n content: string,\n edited_timestamp: string,\n embeds: Embed[],\n sticker_items?: Sticker[],\n flags: number,\n id: string,\n member: GuildMember,\n mention_everyone: boolean,\n mention_roles: string[],\n mentions: Mention[],\n nonce: string,\n pinned: false,\n referenced_message: any,\n timestamp: string,\n tts: boolean,\n type: number;\n}\n\ninterface Mention {\n avatar: string,\n avatar_decoration_data: any,\n discriminator: string,\n global_name: string,\n id: string,\n public_flags: number,\n username: string;\n}\n\ninterface Sticker {\n t: \"Sticker\";\n description: string;\n format_type: number;\n guild_id: string;\n id: string;\n name: string;\n tags: string;\n type: number;\n}\n\ninterface Call {\n channel_id: string,\n guild_id: string,\n message_id: string,\n region: string,\n ringing: string[];\n}\n\nconst MuteStore = findByPropsLazy(\"isSuppressEveryoneEnabled\");\nconst XSLog = new Logger(\"XSOverlay\");\n\nconst settings = definePluginSettings({\n ignoreBots: {\n type: OptionType.BOOLEAN,\n description: \"Ignore messages from bots\",\n default: false\n },\n pingColor: {\n type: OptionType.STRING,\n description: \"User mention color\",\n default: \"#7289da\"\n },\n channelPingColor: {\n type: OptionType.STRING,\n description: \"Channel mention color\",\n default: \"#8a2be2\"\n },\n soundPath: {\n type: OptionType.STRING,\n description: \"Notification sound (default/warning/error)\",\n default: \"default\"\n },\n timeout: {\n type: OptionType.NUMBER,\n description: \"Notif duration (secs)\",\n default: 1.0,\n },\n opacity: {\n type: OptionType.SLIDER,\n description: \"Notif opacity\",\n default: 1,\n markers: makeRange(0, 1, 0.1)\n },\n volume: {\n type: OptionType.SLIDER,\n description: \"Volume\",\n default: 0.2,\n markers: makeRange(0, 1, 0.1)\n },\n});\n\nconst Native = VencordNative.pluginHelpers.XsOverlay as PluginNative<typeof import(\"./native\")>;\n\nexport default definePlugin({\n name: \"XSOverlay\",\n description: \"Forwards discord notifications to XSOverlay, for easy viewing in VR\",\n authors: [Devs.Nyako],\n tags: [\"vr\", \"notify\"],\n settings,\n flux: {\n CALL_UPDATE({ call }: { call: Call; }) {\n if (call?.ringing?.includes(UserStore.getCurrentUser().id)) {\n const channel = ChannelStore.getChannel(call.channel_id);\n sendOtherNotif(\"Incoming call\", `${channel.name} is calling you...`);\n }\n },\n MESSAGE_CREATE({ message, optimistic }: { message: Message; optimistic: boolean; }) {\n // Apparently without this try/catch, discord's socket connection dies if any part of this errors\n try {\n if (optimistic) return;\n const channel = ChannelStore.getChannel(message.channel_id);\n if (!shouldNotify(message, channel)) return;\n\n const pingColor = settings.store.pingColor.replaceAll(\"#\", \"\").trim();\n const channelPingColor = settings.store.channelPingColor.replaceAll(\"#\", \"\").trim();\n let finalMsg = message.content;\n let titleString = \"\";\n\n if (channel.guild_id) {\n const guild = GuildStore.getGuild(channel.guild_id);\n titleString = `${message.author.username} (${guild.name}, #${channel.name})`;\n }\n\n\n switch (channel.type) {\n case ChannelTypes.DM:\n titleString = message.author.username.trim();\n break;\n case ChannelTypes.GROUP_DM:\n const channelName = channel.name.trim() ?? channel.rawRecipients.map(e => e.username).join(\", \");\n titleString = `${message.author.username} (${channelName})`;\n break;\n }\n\n if (message.referenced_message) {\n titleString += \" (reply)\";\n }\n\n if (message.embeds.length > 0) {\n finalMsg += \" [embed] \";\n if (message.content === \"\") {\n finalMsg = \"sent message embed(s)\";\n }\n }\n\n if (message.sticker_items) {\n finalMsg += \" [sticker] \";\n if (message.content === \"\") {\n finalMsg = \"sent a sticker\";\n }\n }\n\n const images = message.attachments.filter(e =>\n typeof e?.content_type === \"string\"\n && e?.content_type.startsWith(\"image\")\n );\n\n\n images.forEach(img => {\n finalMsg += ` [image: ${img.filename}] `;\n });\n\n message.attachments.filter(a => a && !a.content_type?.startsWith(\"image\")).forEach(a => {\n finalMsg += ` [attachment: ${a.filename}] `;\n });\n\n // make mentions readable\n if (message.mentions.length > 0) {\n finalMsg = finalMsg.replace(/<@!?(\\d{17,20})>/g, (_, id) => `<color=#${pingColor}><b>@${UserStore.getUser(id)?.username || \"unknown-user\"}</color></b>`);\n }\n\n if (message.mention_roles.length > 0) {\n for (const roleId of message.mention_roles) {\n const role = GuildStore.getGuild(channel.guild_id).roles[roleId];\n if (!role) continue;\n const roleColor = role.colorString ?? `#${pingColor}`;\n finalMsg = finalMsg.replace(`<@&${roleId}>`, `<b><color=${roleColor}>@${role.name}</color></b>`);\n }\n }\n\n // make emotes and channel mentions readable\n const emoteMatches = finalMsg.match(new RegExp(\"(<a?:\\\\w+:\\\\d+>)\", \"g\"));\n const channelMatches = finalMsg.match(new RegExp(\"<(#\\\\d+)>\", \"g\"));\n\n if (emoteMatches) {\n for (const eMatch of emoteMatches) {\n finalMsg = finalMsg.replace(new RegExp(`${eMatch}`, \"g\"), `:${eMatch.split(\":\")[1]}:`);\n }\n }\n\n if (channelMatches) {\n for (const cMatch of channelMatches) {\n let channelId = cMatch.split(\"<#\")[1];\n channelId = channelId.substring(0, channelId.length - 1);\n finalMsg = finalMsg.replace(new RegExp(`${cMatch}`, \"g\"), `<b><color=#${channelPingColor}>#${ChannelStore.getChannel(channelId).name}</color></b>`);\n }\n }\n\n sendMsgNotif(titleString, finalMsg, message);\n } catch (err) {\n XSLog.error(`Failed to catch MESSAGE_CREATE: ${err}`);\n }\n }\n }\n});\n\nfunction sendMsgNotif(titleString: string, content: string, message: Message) {\n fetch(`https://cdn.discordapp.com/avatars/${message.author.id}/${message.author.avatar}.png?size=128`).then(response => response.arrayBuffer()).then(result => {\n const msgData = {\n messageType: 1,\n index: 0,\n timeout: settings.store.timeout,\n height: calculateHeight(cleanMessage(content)),\n opacity: settings.store.opacity,\n volume: settings.store.volume,\n audioPath: settings.store.soundPath,\n title: titleString,\n content: content,\n useBase64Icon: true,\n icon: result,\n sourceApp: \"Vencord\"\n };\n Native.sendToOverlay(msgData);\n });\n}\n\nfunction sendOtherNotif(content: string, titleString: string) {\n const msgData = {\n messageType: 1,\n index: 0,\n timeout: settings.store.timeout,\n height: calculateHeight(cleanMessage(content)),\n opacity: settings.store.opacity,\n volume: settings.store.volume,\n audioPath: settings.store.soundPath,\n title: titleString,\n content: content,\n useBase64Icon: false,\n icon: null,\n sourceApp: \"Vencord\"\n };\n Native.sendToOverlay(msgData);\n}\n\nfunction shouldNotify(message: Message, channel: Channel) {\n const currentUser = UserStore.getCurrentUser();\n if (message.author.id === currentUser.id) return false;\n if (message.author.bot && settings.store.ignoreBots) return false;\n if (MuteStore.allowAllMessages(channel) || message.mention_everyone && !MuteStore.isSuppressEveryoneEnabled(message.guild_id)) return true;\n\n return message.mentions.some(m => m.id === currentUser.id);\n}\n\nfunction calculateHeight(content: string) {\n if (content.length <= 100) return 100;\n if (content.length <= 200) return 150;\n if (content.length <= 300) return 200;\n return 250;\n}\n\nfunction cleanMessage(content: string) {\n return content.replace(new RegExp(\"<[^>]*>\", \"g\"), \"\");\n}\n", "import p0 from \"./plugins/_api/badges\";\nimport p1 from \"./plugins/_api/commands\";\nimport p2 from \"./plugins/_api/contextMenu\";\nimport p3 from \"./plugins/_api/memberListDecorators\";\nimport p4 from \"./plugins/_api/messageAccessories\";\nimport p5 from \"./plugins/_api/messageDecorations\";\nimport p6 from \"./plugins/_api/messageEvents\";\nimport p7 from \"./plugins/_api/messagePopover\";\nimport p8 from \"./plugins/_api/notices\";\nimport p9 from \"./plugins/_api/serverList\";\nimport p10 from \"./plugins/_core/noTrack\";\nimport p11 from \"./plugins/_core/settings\";\nimport p12 from \"./plugins/_core/supportHelper\";\nimport p13 from \"./plugins/alwaysAnimate\";\nimport p14 from \"./plugins/alwaysTrust\";\nimport p15 from \"./plugins/anonymiseFileNames\";\nimport p16 from \"./plugins/arRPC.web\";\nimport p17 from \"./plugins/banger\";\nimport p18 from \"./plugins/betterFolders\";\nimport p19 from \"./plugins/betterGifAltText\";\nimport p20 from \"./plugins/betterNotes\";\nimport p21 from \"./plugins/betterRoleDot\";\nimport p22 from \"./plugins/betterUploadButton\";\nimport p23 from \"./plugins/biggerStreamPreview\";\nimport p24 from \"./plugins/blurNsfw\";\nimport p25 from \"./plugins/callTimer\";\nimport p26 from \"./plugins/clearURLs\";\nimport p27 from \"./plugins/clientTheme\";\nimport p28 from \"./plugins/colorSighted\";\nimport p29 from \"./plugins/consoleShortcuts\";\nimport p30 from \"./plugins/copyUserURLs\";\nimport p31 from \"./plugins/crashHandler\";\nimport p32 from \"./plugins/customRPC\";\nimport p33 from \"./plugins/dearrow\";\nimport p34 from \"./plugins/decor\";\nimport p35 from \"./plugins/disableDMCallIdle\";\nimport p36 from \"./plugins/emoteCloner\";\nimport p37 from \"./plugins/experiments\";\nimport p38 from \"./plugins/f8break\";\nimport p39 from \"./plugins/fakeNitro\";\nimport p40 from \"./plugins/fakeProfileThemes\";\nimport p41 from \"./plugins/favEmojiFirst\";\nimport p42 from \"./plugins/favGifSearch\";\nimport p43 from \"./plugins/fixSpotifyEmbeds.desktop\";\nimport p44 from \"./plugins/forceOwnerCrown\";\nimport p45 from \"./plugins/friendInvites\";\nimport p46 from \"./plugins/gameActivityToggle\";\nimport p47 from \"./plugins/gifPaste\";\nimport p48 from \"./plugins/greetStickerPicker\";\nimport p49 from \"./plugins/hideAttachments\";\nimport p50 from \"./plugins/iLoveSpam\";\nimport p51 from \"./plugins/ignoreActivities\";\nimport p52 from \"./plugins/imageZoom\";\nimport p53 from \"./plugins/invisibleChat.desktop\";\nimport p54 from \"./plugins/keepCurrentChannel\";\nimport p55 from \"./plugins/lastfm\";\nimport p56 from \"./plugins/loadingQuotes\";\nimport p57 from \"./plugins/memberCount\";\nimport p58 from \"./plugins/messageClickActions\";\nimport p59 from \"./plugins/messageLinkEmbeds\";\nimport p60 from \"./plugins/messageLogger\";\nimport p61 from \"./plugins/messageTags\";\nimport p62 from \"./plugins/moreCommands\";\nimport p63 from \"./plugins/moreKaomoji\";\nimport p64 from \"./plugins/moreUserTags\";\nimport p65 from \"./plugins/moyai\";\nimport p66 from \"./plugins/muteNewGuild\";\nimport p67 from \"./plugins/mutualGroupDMs\";\nimport p68 from \"./plugins/noBlockedMessages\";\nimport p69 from \"./plugins/noDevtoolsWarning\";\nimport p70 from \"./plugins/noF1\";\nimport p71 from \"./plugins/noMosaic\";\nimport p72 from \"./plugins/noPendingCount\";\nimport p73 from \"./plugins/noProfileThemes\";\nimport p74 from \"./plugins/noReplyMention\";\nimport p75 from \"./plugins/noScreensharePreview\";\nimport p76 from \"./plugins/noTypingAnimation\";\nimport p77 from \"./plugins/noUnblockToJump\";\nimport p78 from \"./plugins/normalizeMessageLinks\";\nimport p79 from \"./plugins/notificationVolume\";\nimport p80 from \"./plugins/nsfwGateBypass\";\nimport p81 from \"./plugins/onePingPerDM\";\nimport p82 from \"./plugins/oneko\";\nimport p83 from \"./plugins/openInApp\";\nimport p84 from \"./plugins/partyMode\";\nimport p85 from \"./plugins/permissionFreeWill\";\nimport p86 from \"./plugins/permissionsViewer\";\nimport p87 from \"./plugins/petpet\";\nimport p88 from \"./plugins/pictureInPicture\";\nimport p89 from \"./plugins/pinDms\";\nimport p90 from \"./plugins/plainFolderIcon\";\nimport p91 from \"./plugins/platformIndicators\";\nimport p92 from \"./plugins/previewMessage\";\nimport p93 from \"./plugins/pronoundb\";\nimport p94 from \"./plugins/quickMention\";\nimport p95 from \"./plugins/quickReply\";\nimport p96 from \"./plugins/reactErrorDecoder\";\nimport p97 from \"./plugins/readAllNotificationsButton\";\nimport p98 from \"./plugins/relationshipNotifier\";\nimport p99 from \"./plugins/revealAllSpoilers\";\nimport p100 from \"./plugins/reverseImageSearch\";\nimport p101 from \"./plugins/roleColorEverywhere\";\nimport p102 from \"./plugins/searchReply\";\nimport p103 from \"./plugins/secretRingTone\";\nimport p104 from \"./plugins/sendTimestamps\";\nimport p105 from \"./plugins/serverListIndicators\";\nimport p106 from \"./plugins/serverProfile\";\nimport p107 from \"./plugins/shikiCodeblocks.desktop\";\nimport p108 from \"./plugins/showAllMessageButtons\";\nimport p109 from \"./plugins/showConnections\";\nimport p110 from \"./plugins/showHiddenChannels\";\nimport p111 from \"./plugins/showMeYourName\";\nimport p112 from \"./plugins/showTimeouts\";\nimport p113 from \"./plugins/silentMessageToggle\";\nimport p114 from \"./plugins/silentTyping\";\nimport p115 from \"./plugins/sortFriendRequests\";\nimport p116 from \"./plugins/spotifyControls\";\nimport p117 from \"./plugins/spotifyCrack\";\nimport p118 from \"./plugins/spotifyShareCommands\";\nimport p119 from \"./plugins/startupTimings\";\nimport p120 from \"./plugins/superReactionTweaks\";\nimport p121 from \"./plugins/textReplace\";\nimport p122 from \"./plugins/themeAttributes\";\nimport p123 from \"./plugins/timeBarAllActivities\";\nimport p124 from \"./plugins/translate\";\nimport p125 from \"./plugins/typingIndicator\";\nimport p126 from \"./plugins/typingTweaks\";\nimport p127 from \"./plugins/unindent\";\nimport p128 from \"./plugins/unsuppressEmbeds\";\nimport p129 from \"./plugins/urbanDictionary\";\nimport p130 from \"./plugins/userVoiceShow\";\nimport p131 from \"./plugins/usrbg\";\nimport p132 from \"./plugins/validUser\";\nimport p133 from \"./plugins/vcDoubleClick\";\nimport p134 from \"./plugins/vcNarrator\";\nimport p135 from \"./plugins/vencordToolbox\";\nimport p136 from \"./plugins/viewIcons\";\nimport p137 from \"./plugins/viewRaw\";\nimport p138 from \"./plugins/voiceMessages\";\nimport p139 from \"./plugins/webContextMenus.web\";\nimport p140 from \"./plugins/webKeybinds.web\";\nimport p141 from \"./plugins/whoReacted\";\nimport p142 from \"./plugins/wikisearch\";\nimport p143 from \"./plugins/xsOverlay.desktop\";\nexport default {\n[p0.name]:p0,\n[p1.name]:p1,\n[p2.name]:p2,\n[p3.name]:p3,\n[p4.name]:p4,\n[p5.name]:p5,\n[p6.name]:p6,\n[p7.name]:p7,\n[p8.name]:p8,\n[p9.name]:p9,\n[p10.name]:p10,\n[p11.name]:p11,\n[p12.name]:p12,\n[p13.name]:p13,\n[p14.name]:p14,\n[p15.name]:p15,\n[p16.name]:p16,\n[p17.name]:p17,\n[p18.name]:p18,\n[p19.name]:p19,\n[p20.name]:p20,\n[p21.name]:p21,\n[p22.name]:p22,\n[p23.name]:p23,\n[p24.name]:p24,\n[p25.name]:p25,\n[p26.name]:p26,\n[p27.name]:p27,\n[p28.name]:p28,\n[p29.name]:p29,\n[p30.name]:p30,\n[p31.name]:p31,\n[p32.name]:p32,\n[p33.name]:p33,\n[p34.name]:p34,\n[p35.name]:p35,\n[p36.name]:p36,\n[p37.name]:p37,\n[p38.name]:p38,\n[p39.name]:p39,\n[p40.name]:p40,\n[p41.name]:p41,\n[p42.name]:p42,\n[p43.name]:p43,\n[p44.name]:p44,\n[p45.name]:p45,\n[p46.name]:p46,\n[p47.name]:p47,\n[p48.name]:p48,\n[p49.name]:p49,\n[p50.name]:p50,\n[p51.name]:p51,\n[p52.name]:p52,\n[p53.name]:p53,\n[p54.name]:p54,\n[p55.name]:p55,\n[p56.name]:p56,\n[p57.name]:p57,\n[p58.name]:p58,\n[p59.name]:p59,\n[p60.name]:p60,\n[p61.name]:p61,\n[p62.name]:p62,\n[p63.name]:p63,\n[p64.name]:p64,\n[p65.name]:p65,\n[p66.name]:p66,\n[p67.name]:p67,\n[p68.name]:p68,\n[p69.name]:p69,\n[p70.name]:p70,\n[p71.name]:p71,\n[p72.name]:p72,\n[p73.name]:p73,\n[p74.name]:p74,\n[p75.name]:p75,\n[p76.name]:p76,\n[p77.name]:p77,\n[p78.name]:p78,\n[p79.name]:p79,\n[p80.name]:p80,\n[p81.name]:p81,\n[p82.name]:p82,\n[p83.name]:p83,\n[p84.name]:p84,\n[p85.name]:p85,\n[p86.name]:p86,\n[p87.name]:p87,\n[p88.name]:p88,\n[p89.name]:p89,\n[p90.name]:p90,\n[p91.name]:p91,\n[p92.name]:p92,\n[p93.name]:p93,\n[p94.name]:p94,\n[p95.name]:p95,\n[p96.name]:p96,\n[p97.name]:p97,\n[p98.name]:p98,\n[p99.name]:p99,\n[p100.name]:p100,\n[p101.name]:p101,\n[p102.name]:p102,\n[p103.name]:p103,\n[p104.name]:p104,\n[p105.name]:p105,\n[p106.name]:p106,\n[p107.name]:p107,\n[p108.name]:p108,\n[p109.name]:p109,\n[p110.name]:p110,\n[p111.name]:p111,\n[p112.name]:p112,\n[p113.name]:p113,\n[p114.name]:p114,\n[p115.name]:p115,\n[p116.name]:p116,\n[p117.name]:p117,\n[p118.name]:p118,\n[p119.name]:p119,\n[p120.name]:p120,\n[p121.name]:p121,\n[p122.name]:p122,\n[p123.name]:p123,\n[p124.name]:p124,\n[p125.name]:p125,\n[p126.name]:p126,\n[p127.name]:p127,\n[p128.name]:p128,\n[p129.name]:p129,\n[p130.name]:p130,\n[p131.name]:p131,\n[p132.name]:p132,\n[p133.name]:p133,\n[p134.name]:p134,\n[p135.name]:p135,\n[p136.name]:p136,\n[p137.name]:p137,\n[p138.name]:p138,\n[p139.name]:p139,\n[p140.name]:p140,\n[p141.name]:p141,\n[p142.name]:p142,\n[p143.name]:p143,\n};", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport ErrorBoundary from \"@components/ErrorBoundary\";\nimport { User } from \"discord-types/general\";\nimport { ComponentType, HTMLProps } from \"react\";\n\nimport Plugins from \"~plugins\";\n\nexport const enum BadgePosition {\n START,\n END\n}\n\nexport interface ProfileBadge {\n /** The tooltip to show on hover. Required for image badges */\n description?: string;\n /** Custom component for the badge (tooltip not included) */\n component?: ComponentType<ProfileBadge & BadgeUserArgs>;\n /** The custom image to use */\n image?: string;\n link?: string;\n /** Action to perform when you click the badge */\n onClick?(): void;\n /** Should the user display this badge? */\n shouldShow?(userInfo: BadgeUserArgs): boolean;\n /** Optional props (e.g. style) for the badge, ignored for component badges */\n props?: HTMLProps<HTMLImageElement>;\n /** Insert at start or end? */\n position?: BadgePosition;\n /** The badge name to display, Discord uses this. Required for component badges */\n key?: string;\n}\n\nconst Badges = new Set<ProfileBadge>();\n\n/**\n * Register a new badge with the Badges API\n * @param badge The badge to register\n */\nexport function addBadge(badge: ProfileBadge) {\n badge.component &&= ErrorBoundary.wrap(badge.component, { noop: true });\n Badges.add(badge);\n}\n\n/**\n * Unregister a badge from the Badges API\n * @param badge The badge to remove\n */\nexport function removeBadge(badge: ProfileBadge) {\n return Badges.delete(badge);\n}\n\n/**\n * Inject badges into the profile badges array.\n * You probably don't need to use this.\n */\nexport function _getBadges(args: BadgeUserArgs) {\n const badges = [] as ProfileBadge[];\n for (const badge of Badges) {\n if (!badge.shouldShow || badge.shouldShow(args)) {\n badge.position === BadgePosition.START\n ? badges.unshift({ ...badge, ...args })\n : badges.push({ ...badge, ...args });\n }\n }\n const donorBadges = (Plugins.BadgeAPI as unknown as typeof import(\"../plugins/_api/badges\").default).getDonorBadges(args.user.id);\n if (donorBadges) badges.unshift(...donorBadges);\n\n return badges;\n}\n\nexport interface BadgeUserArgs {\n user: User;\n profile: Profile;\n premiumSince: Date;\n premiumGuildSince?: Date;\n}\n\ninterface ConnectedAccount {\n type: string;\n id: string;\n name: string;\n verified: boolean;\n}\n\ninterface Profile {\n connectedAccounts: ConnectedAccount[];\n premiumType: number;\n premiumSince: string;\n premiumGuildSince?: any;\n lastFetched: number;\n profileFetchFailed: boolean;\n application?: any;\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport * as $Badges from \"./Badges\";\nimport * as $Commands from \"./Commands\";\nimport * as $ContextMenu from \"./ContextMenu\";\nimport * as $DataStore from \"./DataStore\";\nimport * as $MemberListDecorators from \"./MemberListDecorators\";\nimport * as $MessageAccessories from \"./MessageAccessories\";\nimport * as $MessageDecorations from \"./MessageDecorations\";\nimport * as $MessageEventsAPI from \"./MessageEvents\";\nimport * as $MessagePopover from \"./MessagePopover\";\nimport * as $Notices from \"./Notices\";\nimport * as $Notifications from \"./Notifications\";\nimport * as $ServerList from \"./ServerList\";\nimport * as $Settings from \"./Settings\";\nimport * as $Styles from \"./Styles\";\n\n/**\n * An API allowing you to listen to Message Clicks or run your own logic\n * before a message is sent\n *\n * If your plugin uses this, you must add MessageEventsAPI to its dependencies\n */\nexport const MessageEvents = $MessageEventsAPI;\n/**\n * An API allowing you to create custom notices\n * (snackbars on the top, like the Update prompt)\n */\nexport const Notices = $Notices;\n/**\n * An API allowing you to register custom commands\n */\nexport const Commands = $Commands;\n/**\n * A wrapper around IndexedDB. This can store arbitrarily\n * large data and supports a lot of datatypes (Blob, Map, ...).\n * For a full list, see the mdn link below\n *\n * This should always be preferred over the Settings API if possible, as\n * localstorage has very strict size restrictions and blocks the event loop\n *\n * Make sure your keys are unique (tip: prefix them with ur plugin name)\n * and please clean up no longer needed entries.\n *\n * This is actually just idb-keyval, so if you're familiar with that, you're golden!\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm#supported_types}\n */\nexport const DataStore = $DataStore;\n/**\n * An API allowing you to add custom components as message accessories\n */\nexport const MessageAccessories = $MessageAccessories;\n/**\n * An API allowing you to add custom buttons in the message popover\n */\nexport const MessagePopover = $MessagePopover;\n/**\n * An API allowing you to add badges to user profiles\n */\nexport const Badges = $Badges;\n/**\n * An API allowing you to add custom elements to the server list\n */\nexport const ServerList = $ServerList;\n/**\n * An API allowing you to add components as message accessories\n */\nexport const MessageDecorations = $MessageDecorations;\n/**\n * An API allowing you to add components to member list users, in both DM's and servers\n */\nexport const MemberListDecorators = $MemberListDecorators;\n/**\n * An API allowing you to persist data\n */\nexport const Settings = $Settings;\n/**\n * An API allowing you to dynamically load styles\n * a\n */\nexport const Styles = $Styles;\n/**\n * An API allowing you to display notifications\n */\nexport const Notifications = $Notifications;\n\n/**\n * An api allowing you to patch and add/remove items to/from context menus\n */\nexport const ContextMenu = $ContextMenu;\n", "/*!\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nexport * as Api from \"./api\";\nexport * as Plugins from \"./plugins\";\nexport * as Util from \"./utils\";\nexport * as QuickCss from \"./utils/quickCss\";\nexport * as Updater from \"./utils/updater\";\nexport * as Webpack from \"./webpack\";\nexport { PlainSettings, Settings };\n\nimport \"./utils/quickCss\";\nimport \"./webpack/patchWebpack\";\n\nimport { StartAt } from \"@utils/types\";\n\nimport { get as dsGet } from \"./api/DataStore\";\nimport { showNotification } from \"./api/Notifications\";\nimport { PlainSettings, Settings } from \"./api/Settings\";\nimport { patches, PMLogger, startAllPlugins } from \"./plugins\";\nimport { localStorage } from \"./utils/localStorage\";\nimport { relaunch } from \"./utils/native\";\nimport { getCloudSettings, putCloudSettings } from \"./utils/settingsSync\";\nimport { checkForUpdates, update, UpdateLogger } from \"./utils/updater\";\nimport { onceReady } from \"./webpack\";\nimport { SettingsRouter } from \"./webpack/common\";\n\nasync function syncSettings() {\n // pre-check for local shared settings\n if (\n Settings.cloud.authenticated &&\n !await dsGet(\"Vencord_cloudSecret\") // this has been enabled due to local settings share or some other bug\n ) {\n // show a notification letting them know and tell them how to fix it\n showNotification({\n title: \"Cloud Integrations\",\n body: \"We've noticed you have cloud integrations enabled in another client! Due to limitations, you will \" +\n \"need to re-authenticate to continue using them. Click here to go to the settings page to do so!\",\n color: \"var(--yellow-360)\",\n onClick: () => SettingsRouter.open(\"VencordCloud\")\n });\n return;\n }\n\n if (\n Settings.cloud.settingsSync && // if it's enabled\n Settings.cloud.authenticated // if cloud integrations are enabled\n ) {\n if (localStorage.Vencord_settingsDirty) {\n await putCloudSettings();\n delete localStorage.Vencord_settingsDirty;\n } else if (await getCloudSettings(false)) { // if we synchronized something (false means no sync)\n // we show a notification here instead of allowing getCloudSettings() to show one to declutter the amount of\n // potential notifications that might occur. getCloudSettings() will always send a notification regardless if\n // there was an error to notify the user, but besides that we only want to show one notification instead of all\n // of the possible ones it has (such as when your settings are newer).\n showNotification({\n title: \"Cloud Settings\",\n body: \"Your settings have been updated! Click here to restart to fully apply changes!\",\n color: \"var(--green-360)\",\n onClick: relaunch\n });\n }\n }\n}\n\nasync function init() {\n await onceReady;\n startAllPlugins(StartAt.WebpackReady);\n\n syncSettings();\n\n if (!IS_WEB) {\n try {\n const isOutdated = await checkForUpdates();\n if (!isOutdated) return;\n\n if (Settings.autoUpdate) {\n await update();\n if (Settings.autoUpdateNotification)\n setTimeout(() => showNotification({\n title: \"Vencord has been updated!\",\n body: \"Click here to restart\",\n permanent: true,\n noPersist: true,\n onClick: relaunch\n }), 10_000);\n return;\n }\n\n if (Settings.notifyAboutUpdates)\n setTimeout(() => showNotification({\n title: \"A Vencord update is available!\",\n body: \"Click here to view the update\",\n permanent: true,\n noPersist: true,\n onClick() {\n SettingsRouter.open(\"VencordUpdater\");\n }\n }), 10_000);\n } catch (err) {\n UpdateLogger.error(\"Failed to check for updates\", err);\n }\n }\n\n if (IS_DEV) {\n const pendingPatches = patches.filter(p => !p.all && p.predicate?.() !== false);\n if (pendingPatches.length)\n PMLogger.warn(\n \"Webpack has finished initialising, but some patches haven't been applied yet.\",\n \"This might be expected since some Modules are lazy loaded, but please verify\",\n \"that all plugins are working as intended.\",\n \"You are seeing this warning because this is a Development build of Vencord.\",\n \"\\nThe following patches have not been applied:\",\n \"\\n\\n\" + pendingPatches.map(p => `${p.plugin}: ${p.find}`).join(\"\\n\")\n );\n }\n}\n\nstartAllPlugins(StartAt.Init);\ninit();\n\ndocument.addEventListener(\"DOMContentLoaded\", () => {\n startAllPlugins(StartAt.DOMContentLoaded);\n\n if (IS_DISCORD_DESKTOP && Settings.winNativeTitleBar && navigator.platform.toLowerCase().startsWith(\"win\")) {\n document.head.append(Object.assign(document.createElement(\"style\"), {\n id: \"vencord-native-titlebar-style\",\n textContent: \"[class*=titleBar]{display: none!important}\"\n }));\n }\n}, { once: true });\n", "/*!\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nexport * from \"./ChangeList\";\nexport * from \"./constants\";\nexport * from \"./debounce\";\nexport * from \"./discord\";\nexport * from \"./guards\";\nexport * from \"./lazy\";\nexport * from \"./localStorage\";\nexport * from \"./Logger\";\nexport * from \"./margins\";\nexport * from \"./misc\";\nexport * from \"./modal\";\nexport * from \"./onceDefined\";\nexport * from \"./onlyOnce\";\nexport * from \"./patches\";\nexport * from \"./Queue\";\nexport * from \"./react\";\nexport * from \"./text\";\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport type { LiteralUnion } from \"type-fest\";\n\n/**\n * Wait for a property to be defined on the target, then call the callback with\n * the value\n * @param target Object\n * @param property Property to be defined\n * @param callback Callback\n *\n * @example onceDefined(window, \"webpackChunkdiscord_app\", wpInstance => wpInstance.push(...));\n */\nexport function onceDefined<T extends object, P extends LiteralUnion<keyof T, PropertyKey>>(\n target: T, property: P, callback: (v: P extends keyof T ? T[P] : any) => void\n): void {\n const propertyAsAny = property as any;\n\n if (property in target)\n return void callback(target[propertyAsAny]);\n\n Object.defineProperty(target, property, {\n set(v) {\n delete target[propertyAsAny];\n target[propertyAsAny] = v;\n callback(v);\n },\n configurable: true,\n enumerable: false\n });\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { addSettingsListener, Settings } from \"@api/Settings\";\n\n\nlet style: HTMLStyleElement;\nlet themesStyle: HTMLStyleElement;\n\nfunction createStyle(id: string) {\n const style = document.createElement(\"style\");\n style.id = id;\n document.documentElement.append(style);\n return style;\n}\n\nasync function initSystemValues() {\n const values = await VencordNative.themes.getSystemValues();\n const variables = Object.entries(values)\n .filter(([, v]) => v !== \"#\")\n .map(([k, v]) => `--${k}: ${v};`)\n .join(\"\");\n\n createStyle(\"vencord-os-theme-values\").textContent = `:root{${variables}}`;\n}\n\nexport async function toggle(isEnabled: boolean) {\n if (!style) {\n if (isEnabled) {\n style = createStyle(\"vencord-custom-css\");\n VencordNative.quickCss.addChangeListener(css => {\n style.textContent = css;\n // At the time of writing this, changing textContent resets the disabled state\n style.disabled = !Settings.useQuickCss;\n });\n style.textContent = await VencordNative.quickCss.get();\n }\n } else\n style.disabled = !isEnabled;\n}\n\nasync function initThemes() {\n themesStyle ??= createStyle(\"vencord-themes\");\n\n const { themeLinks, enabledThemes } = Settings;\n\n const links: string[] = [...themeLinks];\n\n if (IS_WEB) {\n for (const theme of enabledThemes) {\n const themeData = await VencordNative.themes.getThemeData(theme);\n if (!themeData) continue;\n const blob = new Blob([themeData], { type: \"text/css\" });\n links.push(URL.createObjectURL(blob));\n }\n } else {\n const localThemes = enabledThemes.map(theme => `vencord:///themes/${theme}?v=${Date.now()}`);\n links.push(...localThemes);\n }\n\n themesStyle.textContent = links.map(link => `@import url(\"${link.trim()}\");`).join(\"\\n\");\n}\n\ndocument.addEventListener(\"DOMContentLoaded\", () => {\n initSystemValues();\n initThemes();\n\n toggle(Settings.useQuickCss);\n addSettingsListener(\"useQuickCss\", toggle);\n\n addSettingsListener(\"themeLinks\", initThemes);\n addSettingsListener(\"enabledThemes\", initThemes);\n\n if (!IS_WEB)\n VencordNative.quickCss.addThemeChangeListener(initThemes);\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nexport * as Common from \"./common\";\nexport * from \"./webpack\";\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n*/\n\nimport { WEBPACK_CHUNK } from \"@utils/constants\";\nimport { Logger } from \"@utils/Logger\";\nimport { canonicalizeReplacement } from \"@utils/patches\";\nimport { PatchReplacement } from \"@utils/types\";\n\nimport { traceFunction } from \"../debug/Tracer\";\nimport { _initWebpack } from \".\";\n\nlet webpackChunk: any[];\n\nconst logger = new Logger(\"WebpackInterceptor\", \"#8caaee\");\n\nif (window[WEBPACK_CHUNK]) {\n logger.info(`Patching ${WEBPACK_CHUNK}.push (was already existent, likely from cache!)`);\n _initWebpack(window[WEBPACK_CHUNK]);\n patchPush(window[WEBPACK_CHUNK]);\n} else {\n Object.defineProperty(window, WEBPACK_CHUNK, {\n get: () => webpackChunk,\n set: v => {\n if (v?.push) {\n if (!v.push.$$vencordOriginal) {\n logger.info(`Patching ${WEBPACK_CHUNK}.push`);\n patchPush(v);\n }\n\n if (_initWebpack(v)) {\n logger.info(\"Successfully initialised Vencord webpack\");\n // @ts-ignore\n delete window[WEBPACK_CHUNK];\n window[WEBPACK_CHUNK] = v;\n }\n }\n webpackChunk = v;\n },\n configurable: true\n });\n\n // wreq.m is the webpack module factory.\n // normally, this is populated via webpackGlobal.push, which we patch below.\n // However, Discord has their .m prepopulated.\n // Thus, we use this hack to immediately access their wreq.m and patch all already existing factories\n //\n // Update: Discord now has TWO webpack instances. Their normal one and sentry\n // Sentry does not push chunks to the global at all, so this same patch now also handles their sentry modules\n Object.defineProperty(Function.prototype, \"m\", {\n set(v: any) {\n // When using react devtools or other extensions, we may also catch their webpack here.\n // This ensures we actually got the right one\n if (new Error().stack?.includes(\"discord.com\")) {\n logger.info(\"Found webpack module factory\");\n patchFactories(v);\n }\n\n Object.defineProperty(this, \"m\", {\n value: v,\n configurable: true,\n });\n },\n configurable: true\n });\n}\n\nfunction patchPush(webpackGlobal: any) {\n function handlePush(chunk: any) {\n try {\n patchFactories(chunk[1]);\n } catch (err) {\n logger.error(\"Error in handlePush\", err);\n }\n\n return handlePush.$$vencordOriginal.call(webpackGlobal, chunk);\n }\n\n handlePush.$$vencordOriginal = webpackGlobal.push;\n // Webpack overwrites .push with its own push like so: `d.push = n.bind(null, d.push.bind(d));`\n // it wraps the old push (`d.push.bind(d)`). this old push is in this case our handlePush.\n // If we then repatched the new push, we would end up with recursive patching, which leads to our patches\n // being applied multiple times.\n // Thus, override bind to use the original push\n handlePush.bind = (...args: unknown[]) => handlePush.$$vencordOriginal.bind(...args);\n\n Object.defineProperty(webpackGlobal, \"push\", {\n get: () => handlePush,\n set(v) {\n handlePush.$$vencordOriginal = v;\n },\n configurable: true\n });\n}\n\nfunction patchFactories(factories: Record<string | number, (module: { exports: any; }, exports: any, require: any) => void>) {\n const { subscriptions, listeners } = Vencord.Webpack;\n const { patches } = Vencord.Plugins;\n\n for (const id in factories) {\n let mod = factories[id];\n // Discords Webpack chunks for some ungodly reason contain random\n // newlines. Cyn recommended this workaround and it seems to work fine,\n // however this could potentially break code, so if anything goes weird,\n // this is probably why.\n // Additionally, `[actual newline]` is one less char than \"\\n\", so if Discord\n // ever targets newer browsers, the minifier could potentially use this trick and\n // cause issues.\n //\n // 0, prefix is to turn it into an expression: 0,function(){} would be invalid syntax without the 0,\n let code: string = \"0,\" + mod.toString().replaceAll(\"\\n\", \"\");\n const originalMod = mod;\n const patchedBy = new Set();\n\n const factory = factories[id] = function (module, exports, require) {\n try {\n mod(module, exports, require);\n } catch (err) {\n // Just rethrow discord errors\n if (mod === originalMod) throw err;\n\n logger.error(\"Error in patched chunk\", err);\n return void originalMod(module, exports, require);\n }\n\n exports = module.exports;\n\n if (!exports) return;\n\n // There are (at the time of writing) 11 modules exporting the window\n // Make these non enumerable to improve webpack search performance\n if (exports === window && require.c) {\n Object.defineProperty(require.c, id, {\n value: require.c[id],\n enumerable: false,\n configurable: true,\n writable: true\n });\n return;\n }\n\n for (const callback of listeners) {\n try {\n callback(exports, id);\n } catch (err) {\n logger.error(\"Error in webpack listener\", err);\n }\n }\n\n for (const [filter, callback] of subscriptions) {\n try {\n if (filter(exports)) {\n subscriptions.delete(filter);\n callback(exports, id);\n } else if (exports.default && filter(exports.default)) {\n subscriptions.delete(filter);\n callback(exports.default, id);\n }\n } catch (err) {\n logger.error(\"Error while firing callback for webpack chunk\", err);\n }\n }\n } as any as { toString: () => string, original: any, (...args: any[]): void; };\n\n // for some reason throws some error on which calling .toString() leads to infinite recursion\n // when you force load all chunks???\n factory.toString = () => mod.toString();\n factory.original = originalMod;\n\n for (let i = 0; i < patches.length; i++) {\n const patch = patches[i];\n const executePatch = traceFunction(`patch by ${patch.plugin}`, (match: string | RegExp, replace: string) => code.replace(match, replace));\n if (patch.predicate && !patch.predicate()) continue;\n\n if (code.includes(patch.find)) {\n patchedBy.add(patch.plugin);\n\n const previousMod = mod;\n const previousCode = code;\n\n // we change all patch.replacement to array in plugins/index\n for (const replacement of patch.replacement as PatchReplacement[]) {\n if (replacement.predicate && !replacement.predicate()) continue;\n const lastMod = mod;\n const lastCode = code;\n\n canonicalizeReplacement(replacement, patch.plugin);\n\n try {\n const newCode = executePatch(replacement.match, replacement.replace as string);\n if (newCode === code) {\n if (!patch.noWarn) {\n logger.warn(`Patch by ${patch.plugin} had no effect (Module id is ${id}): ${replacement.match}`);\n if (IS_DEV) {\n logger.debug(\"Function Source:\\n\", code);\n }\n }\n\n if (patch.group) {\n logger.warn(`Undoing patch group ${patch.find} by ${patch.plugin} because replacement ${replacement.match} had no effect`);\n code = previousCode;\n mod = previousMod;\n patchedBy.delete(patch.plugin);\n break;\n }\n } else {\n code = newCode;\n mod = (0, eval)(`// Webpack Module ${id} - Patched by ${[...patchedBy].join(\", \")}\\n${newCode}\\n//# sourceURL=WebpackModule${id}`);\n }\n } catch (err) {\n logger.error(`Patch by ${patch.plugin} errored (Module id is ${id}): ${replacement.match}\\n`, err);\n\n if (IS_DEV) {\n const changeSize = code.length - lastCode.length;\n const match = lastCode.match(replacement.match)!;\n\n // Use 200 surrounding characters of context\n const start = Math.max(0, match.index! - 200);\n const end = Math.min(lastCode.length, match.index! + match[0].length + 200);\n // (changeSize may be negative)\n const endPatched = end + changeSize;\n\n const context = lastCode.slice(start, end);\n const patchedContext = code.slice(start, endPatched);\n\n // inline require to avoid including it in !IS_DEV builds\n const diff = (require(\"diff\") as typeof import(\"diff\")).diffWordsWithSpace(context, patchedContext);\n let fmt = \"%c %s \";\n const elements = [] as string[];\n for (const d of diff) {\n const color = d.removed\n ? \"red\"\n : d.added\n ? \"lime\"\n : \"grey\";\n fmt += \"%c%s\";\n elements.push(\"color:\" + color, d.value);\n }\n\n logger.errorCustomFmt(...Logger.makeTitle(\"white\", \"Before\"), context);\n logger.errorCustomFmt(...Logger.makeTitle(\"white\", \"After\"), patchedContext);\n const [titleFmt, ...titleElements] = Logger.makeTitle(\"white\", \"Diff\");\n logger.errorCustomFmt(titleFmt + fmt, ...titleElements, ...elements);\n }\n\n patchedBy.delete(patch.plugin);\n if (patch.group) {\n logger.warn(`Undoing patch group ${patch.find} by ${patch.plugin} because replacement ${replacement.match} errored`);\n code = previousCode;\n mod = previousMod;\n break;\n }\n\n code = lastCode;\n mod = lastMod;\n }\n }\n\n if (!patch.all) patches.splice(i--, 1);\n }\n }\n }\n}\n"],
"mappings": ";;;;67BAAA,IAkBaA,EACFC,EAnBXC,EAAAC,EAAA,kBAkBaH,EAAiC,OAAO,IAAI,gBAAgB,EAC9DC,EACP,IAAIG,KAAUH,EAAuB,QAAQ,QAAQ,OAAO,MAAM,eAAe,GAAGG,CAAI,ICpB5F,IAkBaC,GAlBbC,GAAAC,EAAA,kBAAAC,IAkBaH,GAAN,KAAa,CAahB,YAAmBI,EAAqBC,EAAgB,QAAS,CAA9C,UAAAD,EAAqB,WAAAC,CAA2B,CAJnE,OAAO,UAAUA,EAAeC,EAAsC,CAClE,MAAO,CAAC,YAAa,GAAI,eAAeD,0DAA+DC,CAAK,CAChH,CAIQ,KAAKC,EAAoDC,EAAoBC,EAAaC,EAAY,GAAI,CAC9G,QAAQH,GACJ,oBAAoB,KAAK,QAAQG,IACjC,eAAeF,0DACf,GACA,eAAe,KAAK,8DAClB,GAAGC,CACT,CACJ,CAEO,OAAOA,EAAa,CACvB,KAAK,KAAK,MAAO,UAAWA,CAAI,CACpC,CAEO,QAAQA,EAAa,CACxB,KAAK,KAAK,OAAQ,UAAWA,CAAI,CACrC,CAEO,SAASA,EAAa,CACzB,KAAK,KAAK,QAAS,UAAWA,CAAI,CACtC,CAEO,eAAeE,KAAgBF,EAAa,CAC/C,KAAK,KAAK,QAAS,UAAWA,EAAME,CAAG,CAC3C,CAEO,QAAQF,EAAa,CACxB,KAAK,KAAK,OAAQ,UAAWA,CAAI,CACrC,CAEO,SAASA,EAAa,CACzB,KAAK,KAAK,QAAS,UAAWA,CAAI,CACtC,CACJ,IClEA,IAkBIG,GAESC,EApBbC,GAAAC,EAAA,kBAAAC,IAkBIJ,GAAW,GAEFC,EAAkF,CAAC,EAEhG,QAAWI,IAAO,CAAC,MAAO,SAAU,OAAQ,OAAO,EAC/C,QAAWC,IAAQ,CAAC,EAAG,GAAI,EAAE,EAAY,CACrC,IAAMC,EAAK,QAAQF,KAAOC,IAC1BL,EAAQ,GAAGI,IAAMC,KAAUC,EAC3BP,IAAY,IAAIO,YAAaF,KAAOC,OACxC,CAGJ,SAAS,iBAAiB,mBAAoB,IAC1C,SAAS,KAAK,OAAO,OAAO,OAAO,SAAS,cAAc,OAAO,EAAG,CAChE,YAAaN,GACb,GAAI,iBACR,CAAC,CAAC,EAAG,CAAE,KAAM,EAAK,CAAC,IChBhB,SAASQ,GAAYC,EAAkBC,EAAW,EAAY,CACjE,IAAIC,EAAQ,EACRC,EACJ,MAAO,KACC,CAACA,GAASF,EAAWC,MACrBC,EAAQH,EAAQ,EACZ,CAACG,GAASF,IAAaC,GACvB,QAAQ,MAAM,uBAAwBF,CAAO,GAE9CG,EAEf,CA0DO,SAASC,GAAaJ,EAAkBC,EAAW,EAAGI,EAAU,GAAU,CAC7E,IAAIC,EAAa,GACZD,GACD,WAAW,IAAMC,EAAa,GAAO,CAAC,EAE1C,IAAIJ,EAAQ,EACNK,EAAa,OAAO,OAAO,UAAY,CAAE,EAAG,CAC9C,CAACC,IAAS,OACV,CAACC,KAAQ,CACL,MAAI,CAACF,EAAWC,KAAWP,EAAWC,MAClCK,EAAWC,IAAUR,EAAQ,EACzB,CAACO,EAAWC,KAAWP,IAAaC,GACpC,QAAQ,MAAM,uBAAwBF,CAAO,GAE9CO,EAAWC,GACtB,CACJ,CAAC,EAED,OAAO,IAAI,MAAMD,EAAY,CACzB,GAAGG,GACH,IAAIC,EAAQC,EAAGC,EAAU,CAKrB,MAAI,CAACR,GAAWC,EACLF,GACH,IAAM,QAAQ,IAAIO,EAAOF,IAAM,EAAGG,EAAGC,CAAQ,EAC7CZ,EACA,EACJ,EAEG,QAAQ,IAAIU,EAAOF,IAAM,EAAGG,EAAGC,CAAQ,CAClD,CACJ,CAAC,CACL,CA1HA,IAiCMC,GAEAJ,GAEAD,GACAD,GAtCNO,GAAAC,EAAA,kBAAAC,IAiCMH,GAAiB,CAAC,YAAa,SAAU,WAAW,EAEpDJ,GAA6B,CAAC,EAE9BD,GAAO,OAAO,IAAI,kBAAkB,EACpCD,GAAS,OAAO,IAAI,qBAAqB,EAE/C,QAAWU,IAAU,CACjB,QACA,YACA,iBACA,iBACA,2BACA,iBACA,MACA,eACA,UACA,oBACA,MACA,gBACJ,EACIR,GAAQQ,GACJ,CAACP,KAAgBQ,IAAgB,QAAQD,GAAQP,EAAOF,IAAM,EAAG,GAAGU,CAAI,EAGhFT,GAAQ,QAAUC,GAAU,CACxB,IAAMS,EAAIT,EAAOF,IAAM,EACjBY,EAAO,QAAQ,QAAQD,CAAC,EAC9B,QAAWE,KAAOR,GACTO,EAAK,SAASC,CAAG,GAAGD,EAAK,KAAKC,CAAG,EAE1C,OAAOD,CACX,EAEAX,GAAQ,yBAA2B,CAACC,EAAQC,IAAM,CAC9C,GAAI,OAAOA,GAAM,UAAYE,GAAe,SAASF,CAAC,EAClD,OAAO,QAAQ,yBAAyBD,EAAQC,CAAC,EAErD,IAAMW,EAAa,QAAQ,yBAAyBZ,EAAOF,IAAM,EAAGG,CAAC,EAErE,OAAIW,GAAY,OAAO,eAAeZ,EAAQC,EAAGW,CAAU,EACpDA,CACX,ICzDO,SAASC,GAAsCC,EAAuCC,EAAW,EAAG,CACvG,IAAMC,EAAMC,GAASH,EAASC,CAAQ,EAChCF,EAAiBK,GAAa,CAChC,IAAMC,EAAYH,EAAI,GAAKI,GAC3B,OAAOC,EAACF,EAAA,CAAW,GAAGD,EAAO,CACjC,EAEA,OAAAL,EAAc,kBAAoBG,EAE3BH,CACX,CA5BA,IAUMO,GAVNE,GAAAC,EAAA,kBAAAC,IAQAC,KAEML,GAAgB,IAAM,OCUrB,SAASM,GAAkBC,EAAwB,CACtD,GAAI,OAAOA,GAAU,SAAU,OAAOA,EACtC,IAAMC,EAAcD,EAAM,OACrB,WAAW,MAAO,mBAAmB,EAC1C,OAAO,IAAI,OAAOC,EAAaD,EAAM,KAAK,CAC9C,CAEO,SAASE,GAAoBC,EAA6BC,EAAwC,CACrG,IAAMC,EAAO,2BAA2B,KAAK,UAAUD,CAAU,KAEjE,OAAI,OAAOD,GAAY,WACZA,EAAQ,WAAW,QAASE,CAAI,EAEpC,IAAIC,IAASH,EAAQ,GAAGG,CAAI,EAAE,WAAW,QAASD,CAAI,CACjE,CAEO,SAASE,GAA0BC,EAAwCC,EAA+B,CAC7G,GAAID,EAAW,IAAK,CAChB,IAAME,EAAWF,EAAW,IAC5BA,EAAW,IAAM,UAAY,CACzB,OAAOC,EAAaC,EAAS,KAAK,IAAI,CAAC,CAC3C,CACJ,MAAWF,EAAW,QAClBA,EAAW,MAAQC,EAAaD,EAAW,KAAK,GAEpD,OAAOA,CACX,CAEO,SAASG,GAAwBC,EAA0DC,EAAgB,CAC9G,IAAMC,EAAc,OAAO,0BAA0BF,CAAW,EAChEE,EAAY,MAAQP,GAAuBO,EAAY,MAAOf,EAAiB,EAC/Ee,EAAY,QAAUP,GAClBO,EAAY,QACZX,GAAWD,GAAoBC,EAASU,CAAM,CAClD,EACA,OAAO,iBAAiBD,EAAaE,CAAW,CACpD,CAxDA,IAAAC,GAAAC,EAAA,kBAAAC,MCAA,IA+CMC,GAGOC,GAlDbC,GAAAC,EAAA,kBAAAC,IAkBAC,KA6BML,GACF,CAAiBM,EAAcC,EAAMC,IAAgCD,EAE5DN,GACPD,KCuBC,SAASS,GAAaC,EAAiD,CAC1E,GAAIC,KAAU,OAAQ,KAAM,MAI5B,OAFAD,EAAS,KAAK,CAAC,CAAC,OAAO,SAAS,CAAC,EAAG,CAAC,EAAGE,GAAKC,GAAOD,CAAC,CAAC,EACtDF,EAAS,IAAI,EACRG,IAELF,GAAQE,GAAK,EACN,IAHW,EAItB,CAUA,SAASC,GAAqBC,KAAmBC,EAAmB,CAChE,IAAMC,EAAM,IAAI,MAAM,WAAWF,mBAAwB,EACzDG,GAAO,MAAMD,EAAK,UAAWD,CAAM,CAKvC,CA8BO,SAASG,GAAQH,EAAkB,CACtC,GAAI,OAAOA,GAAW,WAClB,MAAM,IAAI,MAAM,2CAA6C,OAAOA,CAAM,EAE9E,IAAMI,EAAM,CAAC,EACb,QAAWC,KAAOV,GAAO,CACrB,IAAMW,EAAMX,GAAMU,GACd,CAACC,GAAK,UAENN,EAAOM,EAAI,OAAO,GAClBF,EAAI,KAAKE,EAAI,OAAO,EAEpBA,EAAI,QAAQ,SAAWN,EAAOM,EAAI,QAAQ,OAAO,GACjDF,EAAI,KAAKE,EAAI,QAAQ,OAAO,EACpC,CAEA,OAAOF,CACX,CAoGO,SAASG,MAAqBC,EAAgB,CACjD,IAAMC,EAAKC,GAAa,GAAGF,CAAI,EAC/B,OAAKC,EAEEZ,GAAK,EAAEY,GAFE,IAGpB,CAgBO,SAASE,GAA0BC,EAAoBC,EAAmB,CAG7E,OAAOC,GAAaF,EAASC,CAAQ,CACzC,CAUO,SAASE,GAA6CH,EAAoBC,EAAmB,CAGhG,OAAOG,GAAiBJ,EAASC,CAAQ,CAC7C,CAKO,SAASI,GAASjB,EAAkB,CAGvC,OAAOc,GAAU,IAAMI,GAAKlB,CAAM,CAAC,CACvC,CAKO,SAASmB,MAAeC,EAAiB,CAC5C,IAAMC,EAAMH,GAAKI,GAAQ,QAAQ,GAAGF,CAAK,EAAG,CAAE,WAAY,EAAK,CAAC,EAChE,OAAKC,GACDvB,GAAqB,cAAe,GAAGsB,CAAK,EACzCC,CACX,CAKO,SAASE,KAAmBH,EAAiB,CAGhD,OAAON,GAAU,IAAMK,GAAY,GAAGC,CAAK,CAAC,CAChD,CAKO,SAASI,MAAchB,EAAgB,CAC1C,IAAMa,EAAMH,GAAKI,GAAQ,OAAO,GAAGd,CAAI,EAAG,CAAE,WAAY,EAAK,CAAC,EAC9D,OAAKa,GACDvB,GAAqB,aAAc,GAAGU,CAAI,EACvCa,CACX,CAKO,SAASI,MAAkBjB,EAAgB,CAG9C,OAAOM,GAAU,IAAMU,GAAW,GAAGhB,CAAI,CAAC,CAC9C,CAKO,SAASkB,GAAUC,EAAc,CACpC,IAAMN,EAAMH,GAAKI,GAAQ,YAAYK,CAAI,EAAG,CAAE,WAAY,EAAK,CAAC,EAChE,OAAKN,GACDvB,GAAqB,YAAa6B,CAAI,EACnCN,CACX,CAKO,SAASO,GAAcD,EAAc,CAGxC,OAAOb,GAAU,IAAMY,GAAUC,CAAI,CAAC,CAC1C,CAKO,SAASE,MAAuBrB,EAAgB,CACnD,IAAMa,EAAMH,GAAKI,GAAQ,gBAAgB,GAAGd,CAAI,EAAG,CAAE,WAAY,EAAK,CAAC,EACvE,OAAKa,GACDvB,GAAqB,sBAAuB,GAAGU,CAAI,EAChDa,CACX,CAKO,SAASS,GAA0C9B,EAAkB,CAIxE,OAAOgB,GAAiB,IAAM,CAC1B,IAAMK,EAAMH,GAAKlB,EAAQ,CAAE,WAAY,EAAK,CAAC,EAC7C,OAAKqB,GACDvB,GAAqB,gBAAiBE,CAAM,EACzCqB,CACX,CAAC,CACL,CAKO,SAASU,MAAmDvB,EAAgB,CAG/E,OAAOQ,GAAiB,IAAM,CAC1B,IAAMK,EAAMH,GAAKI,GAAQ,gBAAgB,GAAGd,CAAI,EAAG,CAAE,WAAY,EAAK,CAAC,EACvE,OAAKa,GACDvB,GAAqB,sBAAuB,GAAGU,CAAI,EAChDa,CACX,CAAC,CACL,CAKO,SAASW,MAAqDZ,EAAiB,CAGlF,OAAOJ,GAAiB,IAAM,CAC1B,IAAMK,EAAMH,GAAKI,GAAQ,QAAQ,GAAGF,CAAK,EAAG,CAAE,WAAY,EAAK,CAAC,EAChE,OAAKC,GACDvB,GAAqB,wBAAyB,GAAGsB,CAAK,EACnDC,EAAID,EAAM,GACrB,CAAC,CACL,CAOA,eAAsBa,GAAqBzB,EAAgB0B,EAAkB,+DAAgE,CACzI,IAAMC,EAAS5B,GAAkB,GAAGC,CAAI,EACxC,GAAI,CAAC2B,EAAQ,CACT,IAAMlC,EAAM,IAAI,MAAM,oDAAoD,EAC1EC,GAAO,KAAKD,EAAK,QAASO,EAAM,WAAY0B,CAAO,EAEnD,MACJ,CAEA,IAAME,EAAQD,EAAO,SAAS,EAAE,MAAME,GAAkBH,CAAO,CAAC,EAChE,GAAI,CAACE,EAAO,CACR,IAAMnC,EAAM,IAAI,MAAM,2EAA2E,EACjGC,GAAO,KAAKD,EAAK,QAASO,EAAM,WAAY0B,CAAO,EAMnD,MACJ,CAEA,GAAM,CAAC,CAAEzB,CAAE,EAAI2B,EACf,GAAI,CAAC3B,GAAM,CAAC,OAAOA,CAAE,EAAG,CACpB,IAAMR,EAAM,IAAI,MAAM,iIAAiI,EACvJC,GAAO,KAAKD,EAAK,QAASO,EAAM,WAAY0B,CAAO,EAMnD,MACJ,CAEA,aAAOrC,GAAa,GAAGY,CAAE,EAClBZ,GAAKY,CAAS,CACzB,CAUO,SAAS6B,GAAyB9B,EAAgB0B,EAAkB,+DAAgE,CAGvI,MAAO,IAAMD,GAAqBzB,EAAM0B,CAAO,CACnD,CAMO,SAASK,GAAQvC,EAAsCwC,EAAsB,CAAE,WAAAC,EAAa,EAAM,EAA+B,CAAC,EAAG,CAGxI,GAAI,OAAOzC,GAAW,SAClBA,EAASsB,GAAQ,QAAQtB,CAAM,UAC1B,MAAM,QAAQA,CAAM,EACzBA,EAASsB,GAAQ,QAAQ,GAAGtB,CAAM,UAC7B,OAAOA,GAAW,WACvB,MAAM,IAAI,MAAM,sDAAwD,OAAOA,CAAM,EAEzF,GAAM,CAAC0C,EAAUjC,CAAE,EAAIS,GAAKlB,EAAS,CAAE,WAAY,GAAM,UAAW,EAAK,CAAC,EAC1E,GAAI0C,EAAU,OAAO,KAAKF,EAASE,EAAUjC,CAAE,EAE/CkC,GAAc,IAAI3C,EAAQwC,CAAQ,CACtC,CAEO,SAASI,GAAYJ,EAAsB,CAC9CK,GAAU,IAAIL,CAAQ,CAC1B,CAEO,SAASM,GAAeN,EAAsB,CACjDK,GAAU,OAAOL,CAAQ,CAC7B,CAQO,SAASO,MAAUzB,EAAiC,CACvD,IAAM0B,EAAU,CAAC,EACXC,EAAYpD,GAAK,EACvBqD,EACA,QAAWzC,KAAMwC,EAAW,CACxB,IAAMrC,EAAUqC,EAAUxC,GAAI,UAAYwC,EAAUxC,GAC9C0C,EAAcvC,EAAQ,SAAS,EACrC,QAAWZ,KAAUsB,EAEjB,GADI,OAAOtB,GAAW,UAAY,CAACmD,EAAI,SAASnD,CAAM,GAClDA,aAAkB,QAAU,CAACA,EAAO,KAAKmD,CAAG,EAAG,SAASD,EAEhEF,EAAQvC,GAAMG,CAClB,CAEA,OAAOoC,CACX,CAUO,SAASI,GAAQ3C,EAAqB,CACzC,IAAMH,EAAMT,GAAK,EAAEY,GACnB,GAAI,CAACH,EAAK,OAAO,KAEjB,IAAME,EAAO;AAAA,8BACaC;AAAA;AAAA;AAAA;AAAA,IAI1BH,EAAI,SAAS;AAAA,sCACqBG;AAAA,EAGlC,SADsB,MAAMD,CAAI,CAEpC,CAxhBA,IA0BMN,GAEKmD,GAKEC,GAEFzD,GACAF,GAIE2B,GA6BAqB,GACAE,GAmCA3B,GAkDAqC,GAiEA7C,GAkCA8C,GA9PbC,EAAAC,EAAA,kBAAAC,IAkBAC,KACAC,KACAC,KACAC,KAGAC,KAEM9D,GAAS,IAAI+D,GAAO,SAAS,EAOtBX,GAAY,IAAI,QAAc1D,GAAKyD,GAAgBzD,CAAC,EAOpD0B,GAAU,CACnB,QAAS,IAAIF,IACTA,EAAM,SAAW,EACX8C,GAAKA,EAAE9C,EAAM,MAAQ,OACrB8C,GAAK9C,EAAM,MAAM+C,GAAKD,EAAEC,KAAO,MAAM,EAE/C,OAAQ,IAAI3D,IAA6B0D,GAAK,CAC1C,GAAI,OAAOA,GAAM,WAAY,MAAO,GACpC,IAAME,EAAI,SAAS,UAAU,SAAS,KAAKF,CAAC,EAC5C,QAAWG,KAAK7D,EACZ,GAAI,CAAC4D,EAAE,SAASC,CAAC,EAAG,MAAO,GAE/B,MAAO,EACX,EACA,YAAc1C,GAA2BuC,GACrCA,EAAE,aAAa,cAAgBvC,EAEnC,gBAAiB,IAAInB,IAA6B,CAC9C,IAAMR,EAASsB,GAAQ,OAAO,GAAGd,CAAI,EACrC,OAAO0D,GACClE,EAAOkE,CAAC,EAAU,GACjBA,EAAE,SACHA,EAAE,KAAalE,EAAOkE,EAAE,IAAI,EAC5BA,EAAE,OAAelE,EAAOkE,EAAE,MAAM,EAC7B,GAHiB,EAKhC,CACJ,EAEavB,GAAgB,IAAI,IACpBE,GAAY,IAAI,IAmChB3B,GAAOoD,GAAc,OAAQ,SAActE,EAAkB,CAAE,WAAAyC,EAAa,GAAO,UAAA8B,EAAY,EAAM,EAAoD,CAAC,EAAG,CACtK,GAAI,OAAOvE,GAAW,WAClB,MAAM,IAAI,MAAM,2CAA6C,OAAOA,CAAM,EAE9E,QAAWK,KAAOV,GAAO,CACrB,IAAMW,EAAMX,GAAMU,GAClB,GAAI,EAACC,GAAK,QAEV,IAAIN,EAAOM,EAAI,OAAO,EAClB,OAAOiE,EAAY,CAACjE,EAAI,QAASD,CAAG,EAAIC,EAAI,QAGhD,GAAIA,EAAI,QAAQ,SAAWN,EAAOM,EAAI,QAAQ,OAAO,EAAG,CACpD,IAAMkE,EAAQlE,EAAI,QAAQ,QAC1B,OAAOiE,EAAY,CAACC,EAAOnE,CAAG,EAAImE,CACtC,EACJ,CAEA,OAAK/B,GACD3C,GAAqB,OAAQE,CAAM,EAGhCuE,EAAY,CAAC,KAAM,IAAI,EAAI,IACtC,CAAC,EA2BYhB,GAAWe,GAAc,WAAY,YAAqBG,EAAuB,CAC1F,GAAI,CAAC,MAAM,QAAQA,CAAS,EACxB,MAAM,IAAI,MAAM,4CAA8C,OAAOA,CAAS,EAElF,GAAM,CAAE,OAAAC,CAAO,EAAID,EAEnB,GAAIC,IAAW,EACX,MAAM,IAAI,MAAM,gCAAgC,EAEpD,GAAIA,IAAW,EAIX,OAAOxD,GAAKuD,EAAU,EAAE,EAG5B,IAAMnD,EAAUmD,EAEZD,EAAQ,EACNxB,EAAU,MAAM0B,CAAM,EAE5BxB,EACA,QAAW7C,KAAOV,GAAO,CACrB,IAAMW,EAAMX,GAAMU,GAClB,GAAI,EAACC,GAAK,QAEV,QAASqE,EAAI,EAAGA,EAAID,EAAQC,IAAK,CAC7B,IAAM3E,EAASsB,EAAQqD,GAEvB,GAAI3E,IAAW,OAEf,IAAIA,EAAOM,EAAI,OAAO,EAAG,CAGrB,GAFA0C,EAAQ2B,GAAKrE,EAAI,QACjBgB,EAAQqD,GAAK,OACT,EAAEH,IAAUE,EAAQ,MAAMxB,EAC9B,KACJ,CAEA,GAAI5C,EAAI,QAAQ,SAAWN,EAAOM,EAAI,QAAQ,OAAO,EAAG,CAGpD,GAFA0C,EAAQ2B,GAAKrE,EAAI,QAAQ,QACzBgB,EAAQqD,GAAK,OACT,EAAEH,IAAUE,EAAQ,MAAMxB,EAC9B,KACJ,EACJ,CACJ,CAEA,GAAIsB,IAAUE,EAAQ,CAClB,IAAMzE,EAAM,IAAI,MAAM,OAAOyE,6BAAkCF,YAAgB,EAM3EtE,GAAO,KAAKD,CAAG,CAEvB,CAEA,OAAO+C,CACX,CAAC,EAMYtC,GAAe4D,GAAc,eAAgB,YAAyB9D,EAAgB,CAC/F0C,EACA,QAAWzC,KAAMZ,GAAK,EAAG,CACrB,IAAMsD,EAAMtD,GAAK,EAAEY,GAAI,SAAS,EAEhC,QAAW4D,KAAK7D,EACZ,GAAI,CAAC2C,EAAI,SAASkB,CAAC,EAAG,SAASnB,EAEnC,OAAOzC,CACX,CAEA,IAAMR,EAAM,IAAI,MAAM;AAAA,EAAuCO,EAAK,KAAK;AAAA,CAAI,CAAC,EAMxE,OAAAN,GAAO,KAAKD,CAAG,EAGZ,IACX,CAAC,EAaYuD,GAA2B,CAAC,IC9PzC,IAsBaoB,GACAC,GAvBbC,GAAAC,EAAA,kBAAAC,IAkBAC,IAIaL,GAAyCM,GAASC,GAAKA,EAAE,OAASA,EAAE,OAAS,CAACA,EAAE,eAAe,EAC/FN,GAA+CO,EAAgB,gBAAiB,eAAe,ICArG,SAASC,GAAsGC,EAAcC,EAAyC,CAGzK,IAAIC,EAAa,UAAY,CACzB,MAAM,IAAI,MAAM,8BAA8BF,aAAgB,CAClE,EAEMG,EAAgBC,GAAc,IAAMF,CAAO,EACjD,OAAAG,GAAQJ,EAASK,GAAW,CACxBJ,EAAUI,EACV,OAAO,OAAOH,EAAeG,CAAC,CAClC,EAAG,CAAE,WAAY,EAAK,CAAC,EAEhBH,CACX,CAEO,SAASI,GAAaP,EAAcQ,EAAsB,CAG7DH,GAAQI,GAAQ,YAAYT,CAAI,EAAGQ,EAAI,CAAE,WAAY,EAAK,CAAC,CAC/D,CA3CA,IAAAE,GAAAC,EAAA,kBAAAC,IAkBAA,KAGAC,MCrBA,IAwBWC,EAOAC,GACAC,EACAC,GACAC,GACAC,GACAC,GACAC,EACAC,GACAC,GACAC,GACAC,GACAC,GACAC,GACAC,GACAC,GACAC,GACAC,GACAC,GAGAC,GAEEC,GACAC,GACAC,GAEEC,GAzDfC,GAAAC,EAAA,kBAAAC,IAmBAC,IAEAC,KAGW5B,EAAQ,CAAC,EA6BPoB,GAAaS,GAA+B,aAAcC,GAAKA,GAAG,MAAM,SAAS,EAAE,SAAS,cAAc,CAAC,EAC3GT,GAAYQ,GAA8B,YAAaE,GAAQ,OAAO,sDAAsD,CAAC,EAC7HT,GAAOO,GAAyB,OAAQ,CAAC,UAAW,QAAS,MAAM,CAAC,EAEpE,CAAE,qBAAAN,IAAyBS,EAAgB,sBAAsB,EAE9EC,GAAQ,CAAC,WAAY,QAAQ,EAAGH,GAAK,EAChC,CAAE,SAAAX,GAAU,KAAAlB,GAAM,OAAAC,EAAQ,WAAYC,GAAQ,QAAAC,GAAS,UAAAC,GAAW,SAAAC,GAAU,KAAAC,EAAM,OAAAC,GAAQ,iBAAAC,GAAkB,OAAAC,GAAQ,YAAAC,GAAa,OAAAG,GAAQ,OAAAF,GAAQ,OAAAC,GAAQ,UAAAE,GAAW,aAAAC,GAAc,UAAAC,GAAW,OAAAC,EAAO,EAAIY,GACzM9B,EAAQ8B,CACZ,CAAC,IC9DD,IAsBWI,EAIEC,GA1BbC,GAAAC,EAAA,kBAAAC,IAmBAC,IAGWL,EAAO,CAAC,EAEnBM,GAAQ,CAAC,WAAY,mBAAmB,EAAGC,GAAKP,EAAOO,CAAC,EAE3CN,GAAmCO,EAAgB,mBAAoB,iBAAiB,IC1BrG,IAqBWC,EACAC,EACAC,GACAC,GACAC,GACAC,GACAC,GAEEC,GA7BbC,GAAAC,EAAA,kBAAAD,IAmBAE,IAUaH,GAA2EI,EAAgB,eAAgB,QAAQ,EAEhIC,GAAQ,WAAYC,GAAK,CACrBb,EAAQa,EACP,CAAE,UAAAX,GAAW,SAAAD,EAAU,QAAAE,GAAS,OAAAC,GAAQ,WAAAC,GAAY,YAAAC,EAAY,EAAIN,CACzE,CAAC,IClCD,IAQac,GACAC,GAEAC,GAXbC,GAAAC,EAAA,kBAAAC,IAMAC,IAEaN,GAA8BO,EAAgB,uBAAuB,EACrEN,GAAuBM,EAAgB,iBAAiB,EAExDL,GAA6BK,EAAgB,qCAAqC,ICX/F,IAyBaC,GAIDC,GAODC,GAKEC,GACFC,GACAC,GACAC,GACAC,GACAC,GAEAC,GACAC,EACAC,GACAC,GACAC,GACAC,EACAC,GACAC,GAKAC,GACAC,GACAC,GAaIC,GA3EfC,GAAAC,EAAA,kBAAAC,IAqBAC,IACAC,KAGazB,GAAe0B,EAAgB,eAAe,EAI/CzB,QACRA,IAAA,eAAiB,GAAjB,iBACAA,IAAA,eAAiB,GAAjB,iBACAA,IAAA,mBAAqB,GAArB,qBACAA,IAAA,2BAA6B,GAA7B,6BAJQA,QAAA,IAYCE,GAAuBuB,EAAgB,oBAAoB,EAkC3D,CAAE,mBAAAN,IAQTM,EAAgB,oBAAoB,EAE1CC,GAAa,aAAcC,GAAKT,GAAaS,CAAC,EAC9CD,GAAa,YAAaC,GAAKlB,EAAYkB,CAAC,EAC5CD,GAAa,mBAAoBE,GAAKlB,GAAmBkB,CAAC,EAC1DF,GAAa,eAAgBE,GAAKf,EAAee,CAAC,EAClDF,GAAa,uBAAwBE,GAAKjB,GAAuBiB,CAAC,EAClEF,GAAa,qBAAsBE,GAAKhB,GAAqBgB,CAAC,EAC9DF,GAAa,aAAcE,GAAKpB,GAAaoB,CAAC,EAC9CF,GAAa,mBAAoBE,GAAKd,GAAmBc,CAAC,EAC1DF,GAAa,oBAAqBE,GAAKb,GAAoBa,CAAC,EAC5DF,GAAa,kBAAmBE,GAAKzB,GAAkByB,CAAC,EACxDF,GAAa,gBAAiBE,GAAKtB,GAAgBsB,CAAC,EACpDF,GAAa,iBAAkBE,GAAKvB,GAAiBuB,CAAC,EACtDF,GAAa,oBAAqBE,GAAKxB,GAAoBwB,CAAC,EAC5DF,GAAa,eAAgBE,GAAK3B,GAAe2B,CAAC,EAClDF,GAAa,cAAeE,GAAKX,GAAcW,CAAC,EAChDF,GAAa,aAAcE,GAAKZ,GAAaY,CAAC,ICpG9C,IAAAC,GAAA,OAAAC,GAAAC,EAAA,kBAAAC,MCAA,IAAAC,GAAA,OAAAC,GAAAC,EAAA,kBAAAC,MCAA,IAAAC,GAAA,OAAAC,GAAAC,EAAA,kBAAAC,MCyGO,SAASC,GAAUC,EAAiBC,EAAOC,GAAU,QAAS,CACjEC,GAAO,KAAK,CACR,GAAIA,GAAO,MAAM,EACjB,QAAAH,EACA,KAAAC,CACJ,CAAC,CACL,CA/GA,IAwBWG,EAWAC,GAIEC,GACAC,GAEAC,GAEAC,GAEAC,GAEFC,GAGAC,GAEAC,GAGLX,GAMAY,GAKOX,GA8CAY,GACAC,GAIAC,GAIAC,GAEAC,GAEFC,GAGiBC,GAEfC,GAEPC,GACkBC,GAEXC,GACAC,GACAC,GA1IbC,GAAAC,EAAA,kBAAAC,IAqBAC,IAKAC,GAAQ,CAAC,WAAY,WAAW,EAAGC,GAAK,CACpC7B,EAAiB6B,EACjB,IAAMC,EAAK,IAAM,CACbD,EAAE,YAAY,kBAAmBC,CAAE,EACnCC,GAAc,CAClB,EACAF,EAAE,UAAU,kBAAmBC,CAAE,CACrC,CAAC,EAGDF,GAAQ,CAAC,oBAAqB,qBAAqB,EAAGC,GAAK5B,GAAoB4B,EAAE,iBAAiB,EAGrF3B,GAAqB8B,EAAgB,gBAAiB,KAAK,EAC3D7B,GAAkC6B,EAAgB,mBAAmB,EAErE5B,GAAsC4B,EAAgB,YAAa,kBAAkB,EAErF3B,GAAkC2B,EAAgB,WAAY,WAAW,EAEzE1B,GAAe2B,GAASJ,GAAKA,EAAE,WAAW,QAAQ,EAG/DD,GAAQ,CAAC,gBAAiB,kBAAkB,EAAGC,GAAKtB,GAAiBsB,CAAC,EAGtED,GAAQ,aAAcC,GAAKrB,GAASqB,CAAC,EAErCD,GAAQ,CAAC,OAAQ,OAAO,EAAGC,GAAKpB,GAASoB,CAAC,EAEpC/B,GAAY,CACd,QAAS,EACT,QAAS,EACT,QAAS,EACT,OAAQ,CACZ,EACMY,GAAgB,CAClB,IAAK,EACL,OAAQ,CACZ,EAEaX,GAAS,CAClB,KAAMD,GACN,SAAUY,GAEV,MAAO,KAAO,KAAK,OAAO,GAAK,KAAK,OAAO,GAAG,SAAS,EAAE,EAAE,MAAM,CAAC,CAsBtE,EAGAkB,GAAQ,YAAaC,GAAK,CACtB9B,GAAO,KAAO8B,EAAE,UAChB9B,GAAO,IAAM8B,EAAE,QACnB,CAAC,EAcYlB,GAAYqB,EAAgB,UAAW,kBAAkB,EACzDpB,GAAgBoB,EAAgB,kCAAmC,gBAAgB,EAInFnB,GAAwBmB,EAAgB,gBAAiB,eAAe,EAIxElB,GAAyBkB,EAAgB,gBAAiB,MAAM,EAEhEjB,GAAuCiB,EAAgB,eAAgB,cAAe,mBAAmB,EAGtHJ,GAAQ,CAAC,OAAQ,oBAAoB,EAAGC,GAAKb,GAAiBa,CAAC,GAElD,CAAE,YAAaZ,IAAoBgB,GAASJ,GAAK,OAAOA,EAAE,aAAa,eAAkB,QAAQ,GAEjGX,GAAkDgB,GAAe,uBAAuB,EAE/Ff,GAAgBgB,GAAQ,OAAO,8BAA8B,EACtD,CAAE,QAASf,IAAwDa,GAASJ,GAAKA,EAAE,SAAWV,GAAcU,EAAE,OAAO,CAAC,EAEtHR,GAAiBW,EAAgB,cAAe,aAAa,EAC7DV,GAAqBU,EAAgB,uBAAwB,uBAAuB,EACpFT,GAAgBS,EAAgB,eAAe,IC1I5D,IAAAI,GAAA,GAAAC,GAAAD,GAAA,YAAAE,GAAA,0BAAAC,GAAA,WAAAC,GAAA,WAAAC,EAAA,gBAAAC,GAAA,yBAAAC,GAAA,SAAAC,GAAA,iBAAAC,EAAA,cAAAC,GAAA,cAAAC,GAAA,sBAAAC,GAAA,mBAAAC,GAAA,mBAAAC,GAAA,WAAAC,GAAA,eAAAC,GAAA,cAAAC,GAAA,eAAAC,GAAA,SAAAC,GAAA,SAAAC,GAAA,mBAAAC,EAAA,UAAAC,EAAA,sBAAAC,GAAA,qBAAAC,GAAA,eAAAC,GAAA,kBAAAC,GAAA,eAAAC,GAAA,SAAAC,EAAA,cAAAC,GAAA,mBAAAC,GAAA,iBAAAC,GAAA,sBAAAC,GAAA,qBAAAC,GAAA,yBAAAC,GAAA,cAAAC,GAAA,WAAAC,GAAA,oBAAAC,GAAA,oBAAAC,GAAA,4BAAAC,GAAA,WAAAC,GAAA,kBAAAC,GAAA,yBAAAC,GAAA,UAAAC,EAAA,aAAAC,GAAA,mBAAAC,GAAA,sBAAAC,GAAA,YAAAC,GAAA,iBAAAC,GAAA,qBAAAC,GAAA,WAAAC,GAAA,yBAAAC,GAAA,uBAAAC,GAAA,mBAAAC,GAAA,WAAAC,GAAA,mBAAAC,GAAA,yBAAAC,GAAA,WAAAC,GAAA,WAAAC,GAAA,SAAAC,EAAA,gCAAAC,GAAA,aAAAC,GAAA,cAAAC,GAAA,cAAAC,GAAA,WAAAC,GAAA,YAAAC,GAAA,kBAAAC,GAAA,uBAAAC,GAAA,qBAAAC,GAAA,+BAAAC,GAAA,cAAAC,EAAA,cAAAC,GAAA,cAAAC,GAAA,gBAAAC,GAAA,SAAAC,GAAA,SAAAC,GAAA,WAAAC,GAAA,WAAAC,GAAA,cAAAC,GAAA,gBAAAC,GAAA,cAAAC,GAAA,YAAAC,GAAA,eAAAC,GAAA,WAAAC,GAAA,aAAAC,EAAA,uBAAAC,GAAA,aAAAC,GAAA,kBAAAC,GAAA,mBAAAC,KAAA,IAAAC,EAAAC,EAAA,kBAAAC,IAkBAC,KACAC,KACAC,KACAH,KACAI,KACAC,KACAC,KACAC,KACAC,KACAC,OC3BA,IAAOC,GAAPC,GAAAC,EAAA,KAAAC,IAAOH,GAAQ,YCAf,IAAOI,GAAPC,GAAAC,EAAA,KAAAC,IAAOH,GAAQ,uBCAf,IA0BaI,GACAC,GACAC,GACAC,GAcAC,EA6WAC,GAxZbC,EAAAC,EAAA,kBAAAC,IAkBAC,KACAC,KAOaV,GAAgB,0BAChBC,GAAe,+BACfC,GAAqB,WAAWS,KAAUC,GAAY,wBAAwBA,MAAe,KAC7FT,GAAqB,sBAcrBC,EAAsB,OAAO,OAAO,CAC7C,IAAK,CACD,KAAM,aACN,GAAI,mBACR,EACA,MAAO,CACH,KAAM,gBACN,GAAI,mBACR,EACA,IAAK,CACD,KAAM,aACN,GAAI,mBACR,EACA,KAAM,CACF,KAAM,UACN,GAAI,mBACR,EACA,OAAQ,CACJ,KAAM,SACN,GAAI,mBACR,EACA,UAAW,CACP,KAAM,YACN,GAAI,mBACR,EACA,OAAQ,CACJ,KAAM,SACN,GAAI,mBACR,EACA,OAAQ,CACJ,KAAM,UACN,GAAI,mBACR,EACA,KAAM,CACF,KAAM,OACN,GAAI,mBACR,EACA,MAAO,CACH,KAAM,QACN,GAAI,mBACR,EACA,UAAW,CACP,KAAM,MACN,GAAI,mBACR,EACA,KAAM,CACF,KAAM,OACN,GAAI,mBACR,EACA,OAAQ,CACJ,KAAM,SACN,GAAI,mBACR,EACA,IAAK,CACD,KAAM,MACN,GAAI,mBACR,EACA,OAAQ,CACJ,KAAM,SACN,GAAI,mBACR,EACA,MAAO,CACH,KAAM,QACN,GAAI,mBACR,EACA,QAAS,CACL,KAAM,UACN,GAAI,mBACR,EACA,YAAa,CACT,KAAM,cACN,GAAI,mBACR,EACA,MAAO,CACH,KAAM,QACN,GAAI,mBACR,EACA,QAAS,CACL,KAAM,WACN,GAAI,mBACR,EACA,aAAc,CACV,KAAM,eACN,GAAI,mBACR,EACA,WAAY,CACR,KAAM,aACN,GAAI,mBACR,EACA,QAAS,CACL,KAAM,UACN,GAAI,oBACR,EACA,oBAAqB,CACjB,KAAM,wBACN,GAAI,oBACR,EACA,MAAO,CACH,KAAM,QACN,GAAI,EACR,EACA,MAAO,CACH,KAAM,QACN,GAAI,mBACR,EACA,IAAK,CACD,KAAM,MACN,GAAI,mBACR,EACA,SAAU,CACN,KAAM,WACN,GAAI,mBACR,EACA,KAAM,CACF,KAAM,OACN,GAAI,mBACR,EACA,MAAO,CACH,KAAM,QACN,GAAI,mBACR,EACA,MAAO,CACH,KAAM,QACN,GAAI,mBACR,EACA,OAAQ,CACJ,KAAM,SACN,GAAI,mBACR,EACA,KAAM,CACF,KAAM,OACN,GAAI,mBACR,EACA,IAAK,CACD,KAAM,WACN,GAAI,mBACR,EACA,SAAU,CACN,KAAM,YACN,GAAI,mBACR,EACA,cAAe,CACX,KAAM,gBACN,GAAI,mBACR,EACA,OAAQ,CACJ,KAAM,iBACN,GAAI,mBACR,EACA,MAAO,CACH,KAAM,MACN,GAAI,mBACR,EACA,OAAQ,CACJ,KAAM,SACN,GAAI,kBACR,EACA,WAAY,CACR,KAAM,cACN,GAAI,mBACR,EACA,GAAI,CACA,KAAM,KACN,GAAI,mBACR,EACA,QAAS,CACL,KAAM,UACN,GAAI,mBACR,EACA,KAAM,CACF,KAAM,OACN,GAAI,oBACJ,MAAO,EACX,EACA,QAAS,CACL,KAAM,UACN,GAAI,mBACR,EACA,WAAY,CACR,KAAM,aACN,GAAI,kBACR,EACA,OAAQ,CACJ,KAAM,SACN,GAAI,mBACR,EACA,KAAM,CACF,KAAM,SACN,GAAI,mBACR,EACA,WAAY,CACR,KAAM,aACN,GAAI,mBACR,EACA,KAAM,CACF,KAAM,SACN,GAAI,mBACR,EACA,YAAa,CACT,KAAM,cACN,GAAI,mBACR,EACA,UAAW,CACP,KAAM,YACN,GAAI,mBACR,EACA,KAAM,CACF,KAAM,UACN,GAAI,mBACR,EACA,OAAQ,CACJ,KAAM,gBACN,GAAI,mBACR,EACA,MAAO,CACH,KAAM,QACN,GAAI,mBACR,EACA,OAAQ,CACJ,KAAM,SACN,GAAI,oBACR,EACA,QAAS,CACL,KAAM,UACN,GAAI,oBACR,EACA,IAAK,CACD,KAAM,MACN,GAAI,mBACR,EACA,SAAU,CACN,KAAM,WACN,GAAI,mBACR,EACA,MAAO,CACH,KAAM,QACN,GAAI,mBACR,EACA,MAAO,CACH,KAAM,kBACN,GAAI,mBACR,EACA,WAAY,CACR,KAAM,aACN,GAAI,mBACR,EACA,UAAW,CACP,KAAM,YACN,GAAI,mBACR,EACA,YAAa,CACT,KAAM,QACN,GAAI,mBACR,EACA,SAAU,CACN,KAAM,QACN,GAAI,mBACR,EACA,QAAS,CACL,KAAM,UACN,GAAI,mBACR,EACA,YAAa,CACT,KAAM,cACN,GAAI,mBACR,EACA,QAAS,CACL,KAAM,UACN,GAAI,mBACR,EACA,UAAW,CACP,KAAM,YACN,GAAI,mBACR,EACA,OAAQ,CACJ,KAAM,MACN,GAAI,mBACR,EACA,KAAM,CACF,KAAM,OACN,GAAI,mBACR,EACA,KAAM,CACF,KAAM,OACN,GAAI,mBACR,EACA,OAAQ,CACJ,KAAM,UACN,GAAI,mBACR,EACA,IAAK,CACD,KAAM,MACN,GAAI,mBACR,EACA,UAAW,CACP,KAAM,aACN,GAAI,mBACR,EACA,UAAW,CACP,KAAM,YACN,GAAI,mBACR,EACA,KAAM,CACF,KAAM,OACN,GAAI,oBACR,EACA,UAAW,CACP,KAAM,YACN,GAAI,mBACR,EACA,MAAO,CACH,KAAM,QACN,GAAI,mBACR,EACA,OAAQ,CACJ,KAAM,SACN,GAAI,kBACR,EACA,MAAO,CACH,KAAM,QACN,GAAI,mBACR,EACA,QAAS,CACL,KAAM,UACN,GAAI,mBACR,EACA,UAAW,CACP,KAAM,YACN,GAAI,mBACR,EACA,UAAW,CACP,KAAM,aACN,GAAI,mBACR,EACA,UAAW,CACP,KA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AEhFF,EAAUG,GAAa,WAAWF,EAAQ,GAAID,EAAQ,EAAE,GAAKA,EAC7D,QAAWP,KAAYW,GACnB,GAAI,CACAX,EAASO,EAASC,EAASC,CAAK,CACpC,OAASN,EAAP,CACEC,GAAoB,MAAM;AAAA,EAAgED,CAAC,CAC/F,CAER,CAEO,SAASb,GAAiBU,EAAyB,CACtD,OAAAW,GAAU,IAAIX,CAAQ,EACfA,CACX,CAEO,SAASP,GAAoBO,EAAyB,CACzD,OAAOW,GAAU,OAAOX,CAAQ,CACpC,CAxJA,IAwBMI,GAsDAH,GACAK,GAoDAK,GAnINC,GAAAC,EAAA,kBAAAC,IAkBAC,KACAC,IAKMZ,GAAsB,IAAIa,GAAO,gBAAiB,SAAS,EAsD3DhB,GAAgB,IAAI,IACpBK,GAAgB,IAAI,IAoDpBK,GAAY,IAAI,MCnItB,IAkBaO,GAlBbC,GAAAC,EAAA,kBAAAC,IAkBaH,GAAe,CACxB,oBACA,kBACA,iBACA,uBACA,uBACA,eACA,gBACA,4BACA,2BACA,QACA,aACA,mBACA,qBACA,eACA,eACA,gBACA,mBACA,cACA,gBACA,oBACA,mBACA,cACA,cACA,gBACA,eACA,wBACA,gBACA,gBACA,cACA,cACA,cACA,cACA,cACA,SACA,UACA,MACA,cACA,OACA,QACA,SACA,eACA,aACA,aACA,aACA,UACA,WACA,cACA,QACA,QACA,aACA,WACA,YACA,UACA,cACA,aACA,SACA,SACA,SACA,OACA,cACA,aACA,aACA,YACA,aACA,SACA,aACA,mBACA,YACA,UACA,QACA,YACA,OACA,QACA,MACA,OACA,cACA,WACA,cACA,gBACA,kBACA,SACA,YACA,SACA,sBACA,mBACA,OACA,kBACA,eACA,cACA,eACA,kBACA,kBACA,kBACA,iBACA,SACA,QACA,SACA,SACA,gBACA,yBACA,2BACA,kBACA,kBACA,sBACA,YACA,YACA,gBACA,iBACA,iBACA,qBACA,oBACA,oBACA,wBACA,kBACA,kBACA,sBACA,gBACA,gBACA,oBACA,YACA,aACA,cACA,oBACA,sBACA,iBACA,iBACA,iBACA,cA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CACX,EACA,CACI,MAAO,YACP,MAAO,CACX,EACA,CACI,MAAO,WACP,MAAO,CACX,EACA,CACI,MAAO,YACP,MAAO,CACX,CACJ,CACJ,EACA,WAAY,CACR,OACA,YAAa,mEACb,SAAUA,GACV,SAAUG,GACV,QAASC,EACb,EACA,cAAe,CACX,OACA,YAAa,iBACb,SAAUJ,GACV,QAAS,CACL,CACI,MAAO,OACP,MAAO,EACP,QAAS,EACb,EACA,CACI,MAAO,qBACP,MAAO,CACX,EACA,CACI,MAAO,4BACP,MAAO,CACX,EACA,CACI,MAAO,SACP,MAAO,CACX,CACJ,CACJ,EACA,UAAW,CACP,OACA,YAAa,mDACb,SAAUA,GACV,SAAUM,GACV,QAAUD,GACFA,GAASA,EAAQ,EAAU,0CACxB,EAEf,EACA,QAAS,CACL,OACA,YAAa,iDACb,SAAUL,GACV,SAAUM,GACV,QAAUD,GACFA,GAASA,EAAQ,EAAU,wCACxB,EAEf,EACA,SAAU,CACN,OACA,YAAa,qBACb,SAAUL,GACV,QAASO,EACb,EACA,gBAAiB,CACb,OACA,YAAa,oBACb,SAAUP,GACV,QAAUK,GACFA,GAASA,EAAM,OAAS,IAAY,4DACjC,EAEf,EACA,WAAY,CACR,OACA,YAAa,uBACb,SAAUL,GACV,QAASO,EACb,EACA,kBAAmB,CACf,OACA,YAAa,sBACb,SAAUP,GACV,QAAUK,GACFA,GAASA,EAAM,OAAS,IAAY,8DACjC,EAEf,EACA,cAAe,CACX,OACA,YAAa,gBACb,SAAUL,GACV,QAAUK,GACFA,GAASA,EAAM,OAAS,GAAW,uDAChC,EAEf,EACA,aAAc,CACV,OACA,YAAa,eACb,SAAUL,EACd,EACA,cAAe,CACX,OACA,YAAa,gBACb,SAAUA,GACV,QAAUK,GACFA,GAASA,EAAM,OAAS,GAAW,uDAChC,EAEf,EACA,aAAc,CACV,OACA,YAAa,eACb,SAAUL,EACd,CACJ,CAAC,EAoIMiC,GAAQc,EAAa,CACxB,KAAM,YACN,YAAa,4CACb,QAAS,CAACC,EAAK,QAASA,EAAK,QAAQ,EACrC,MAAO/C,GACP,KAAM,IAAMA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M,YACN,GAAM,UACN,IAAO,UACP,GAAM,WACN,QAAS,uBACT,QAAS,wBACT,GAAM,WACN,GAAM,WACN,GAAM,QACN,GAAM,SACN,GAAM,UACN,IAAO,QACP,GAAM,QACN,GAAM,UACN,GAAM,YACN,GAAM,WACN,GAAM,MACN,GAAM,WACN,GAAM,UACN,GAAM,SACN,GAAM,UACN,GAAM,WACN,GAAM,WACN,GAAM,SACN,GAAM,QACN,GAAM,UACN,GAAM,WACN,GAAM,iBACN,GAAM,QACN,IAAO,WACP,GAAM,SACN,GAAM,QACN,IAAO,QACP,GAAM,YACN,GAAM,YACN,GAAM,OACN,IAAO,UACP,GAAM,aACN,GAAM,QACN,GAAM,UACN,GAAM,WACN,GAAM,WACN,GAAM,UACN,GAAM,SACN,GAAM,QACN,GAAM,cACN,IAAO,UACP,GAAM,SACN,IAAO,OACP,GAAM,qBACN,IAAO,mBACP,GAAM,SACN,GAAM,MACN,GAAM,QACN,GAAM,UACN,GAAM,UACN,GAAM,aACN,GAAM,UACN,GAAM,gBACN,GAAM,aACN,IAAO,WACP,GAAM,WACN,GAAM,QACN,GAAM,YACN,GAAM,UACN,GAAM,QACN,GAAM,UACN,WAAY,uBACZ,IAAO,OACP,GAAM,YACN,GAAM,oBACN,GAAM,SACN,GAAM,YACN,GAAM,eACN,GAAM,QACN,GAAM,SACN,GAAM,UACN,GAAM,SACN,GAAM,aACN,GAAM,UACN,GAAM,UACN,GAAM,WACN,GAAM,UACN,GAAM,SACN,GAAM,WACN,GAAM,eACN,IAAO,SACP,GAAM,UACN,GAAM,UACN,GAAM,QACN,GAAM,SACN,GAAM,UACN,GAAM,SACN,GAAM,YACN,GAAM,SACN,GAAM,UACN,GAAM,YACN,GAAM,UACN,GAAM,UACN,GAAM,QACN,GAAM,QACN,GAAM,QACN,GAAM,SACN,GAAM,OACN,GAAM,WACN,GAAM,SACN,GAAM,UACN,GAAM,UACN,GAAM,MACN,GAAM,YACN,GAAM,OACN,GAAM,SACN,GAAM,QACN,GAAM,aACN,GAAM,QACN,GAAM,QACN,GAAM,UACN,GAAM,SACN,GAAM,MACV,ICrIA,eAAsBI,GAAUC,EAA2BC,EAAyC,CAChG,IAAMC,EAAaC,GAAS,MAAMH,EAAO,SACnCI,EAAaD,GAAS,MAAMH,EAAO,UAEnCK,EAAM,uDAAyD,IAAI,gBAAgB,CAGrF,OAAQ,MAER,GAAIH,EAEJ,GAAIE,EAEJ,GAAI,IAEJ,GAAI,IACJ,OAAQ,QAER,EAAGH,CACP,CAAC,EAEKK,EAAM,MAAM,MAAMD,CAAG,EAC3B,GAAI,CAACC,EAAI,GACL,MAAM,IAAI,MACN,wBAAwBL,OAAUC,QAAiBE;AAAA,EAC5CE,EAAI,UAAUA,EAAI,YAC7B,EAEJ,GAAM,CAAE,IAAAC,EAAK,UAAAC,CAAU,EAAqB,MAAMF,EAAI,KAAK,EAE3D,MAAO,CACH,IAAAC,EACA,KAAMC,EACF,IAAIC,GAAKA,GAAG,KAAK,EACjB,OAAO,OAAO,EACd,KAAK,EAAE,CACf,CACJ,CA1EA,IAsBaC,GAtBbC,GAAAC,EAAA,kBAAAC,IAkBAC,KAEAC,KAEaL,GAAKM,GAAiB,WAAW,ICM9C,SAASC,GAAe,CAAE,YAAAC,EAAa,YAAAC,CAAY,EAA+E,CAC9H,IAAMC,EAAeC,GAAS,IAAI,CAACH,CAAW,CAAC,EAAEA,GAE3CI,EAAUC,GACZ,IAAM,CACF,IAAMD,EAAU,OAAO,QAAQE,EAAS,EAAE,IAAI,CAAC,CAACC,EAAOC,CAAK,KAAO,CAAE,MAAAD,EAAO,MAAAC,CAAM,EAAE,EACpF,OAAKP,GACDG,EAAQ,MAAM,EAEXA,CACX,EAAG,CAAC,CACR,EAEA,OACIK,EAAC,WAAQ,UAAWC,EAAQ,UACxBD,EAACE,EAAM,UAAN,CAAgB,IAAI,MAChBR,GAAS,IAAIH,GAAa,WAC/B,EAEAS,EAACG,GAAA,CACG,QAASR,EACT,MAAOA,EAAQ,KAAKS,GAAKA,EAAE,QAAUX,CAAY,EACjD,YAAa,oBACb,gBAAiB,EACjB,cAAe,GACf,SAAUY,GAAKX,GAAS,MAAMH,GAAec,EACjD,CACJ,CAER,CAEA,SAASC,IAAsB,CAC3B,IAAMR,EAAQJ,GAAS,IAAI,CAAC,eAAe,CAAC,EAAE,cAE9C,OACIM,EAACO,GAAA,CACG,MAAOT,EACP,SAAUO,GAAKX,GAAS,MAAM,cAAgBW,EAC9C,KAAMX,GAAS,IAAI,cAAc,YACjC,WAAU,IACb,gBAED,CAER,CAGO,SAASc,GAAe,CAAE,UAAAC,CAAU,EAA+B,CACtE,OACIT,EAACU,GAAA,CAAW,GAAGD,GACXT,EAACW,GAAA,CAAY,UAAWC,GAAG,cAAc,GACrCZ,EAACE,EAAM,UAAN,CAAgB,IAAI,MAAK,WAE1B,EACAF,EAACa,GAAA,CAAiB,QAASJ,EAAU,QAAS,CAClD,EAEAT,EAACc,GAAA,CAAa,UAAWF,GAAG,eAAe,GACtCG,GAAoB,IAAIC,GACrBhB,EAACV,GAAA,CACG,IAAK0B,EACL,YAAaA,EACb,YAAaA,EAAE,SAAS,OAAO,EACnC,CACH,EAEDhB,EAACE,EAAM,YAAN,CAAkB,UAAWD,EAAQ,SAAU,EAEhDD,EAACM,GAAA,IAAoB,CACzB,CACJ,CAER,CApGA,IA0BMS,GA1BNE,GAAAC,EAAA,kBAAAC,IAkBAC,KACAC,KACAC,IAEAC,KACAC,KACAC,KAEMV,GAAsB,CAAC,gBAAiB,iBAAkB,YAAa,YAAY,ICAlF,SAASW,GAAc,CAAE,OAAAC,EAAS,GAAI,MAAAC,EAAQ,GAAI,UAAAC,CAAU,EAA6D,CAC5H,OACIC,EAAC,OACG,QAAQ,eACR,OAAQH,EACR,MAAOC,EACP,UAAWG,GAAQC,GAAG,MAAM,EAAGH,CAAS,GAExCC,EAAC,QAAK,KAAK,eAAe,EAAE,kRAAkR,CAClT,CAER,CAEO,SAASG,GAAqB,CAAE,WAAAC,CAAW,EAA2D,CACzG,GAAM,CAAE,cAAAC,CAAc,EAAIC,GAAS,IAAI,CAAC,eAAe,CAAC,EAExD,GAAIF,EAAW,KAAK,gBAAkB,SAClC,OAAO,KAEX,IAAMG,EAAS,IAAMD,GAAS,MAAM,cAAgB,CAACD,EAErD,OACIL,EAACQ,GAAA,CAAQ,KAAK,wBACT,CAAC,CAAE,aAAAC,EAAc,aAAAC,CAAa,IAC3BV,EAAC,OAAI,MAAO,CAAE,QAAS,MAAO,GAC1BA,EAACW,EAAA,CACG,gBAAc,SACd,aAAW,uBACX,KAAK,GACL,KAAMC,GAAY,MAClB,aAAcH,EACd,aAAcC,EACd,eAAgBG,GAAqB,OACrC,QAASC,GAAK,CACV,GAAIA,EAAE,SAAU,OAAOP,EAAO,EAE9BQ,GAAUC,GACNhB,EAACiB,GAAA,CAAe,UAAWD,EAAO,CACrC,CACL,EACA,cAAe,IAAMT,EAAO,EAC5B,MAAO,CAAE,QAAS,OAAQ,GAE1BP,EAAC,OAAI,UAAWa,GAAqB,eACjCb,EAACJ,GAAA,CAAc,UAAWM,GAAG,CAAE,iBAAkBG,CAAc,CAAC,EAAG,CACvE,CACJ,CACJ,CAER,CAER,CA7EA,IAAAa,GAAAC,EAAA,kBAAAC,IAkBAC,KACAC,KACAC,IAEAC,KACAC,KACAC,OCGO,SAASC,GAAgBC,EAAmBC,EAAwB,CACvEC,GAAmB,IAAIF,CAAS,EAAGC,CAAI,CAC3C,CAEA,SAASE,GAAQ,CAAE,UAAAC,CAAU,EAA+B,CACxD,OACIC,EAAC,UACG,QAASD,EACT,UAAWE,GAAG,SAAS,GAC1B,SAED,CAER,CAEO,SAASC,GAAqB,CAAE,QAAAC,CAAQ,EAA0B,CACrE,GAAM,CAACC,EAAaC,CAAc,EAAIC,EAA2B,EAWjE,OATAC,GAAU,IAAM,CAEZ,GAAK,CAAAJ,EAAgB,kBAErB,OAAAN,GAAmB,IAAIM,EAAQ,GAAIE,CAAc,EAE1C,IAAM,KAAKR,GAAmB,OAAOM,EAAQ,EAAE,CAC1D,EAAG,CAAC,CAAC,EAEAC,EAGDJ,EAAC,QAAK,UAAWC,GAAG,WAAW,GAC3BD,EAACQ,GAAA,CAAc,MAAO,GAAI,OAAQ,GAAI,EACrCC,GAAO,MAAML,EAAY,IAAI,EAC7B,IAAI,oBACaM,GAAUN,EAAY,MAAQA,EAAY,IAAI,MAAGJ,EAACF,GAAA,CAAQ,UAAW,IAAMO,EAAe,MAAS,EAAG,EAAE,GAC9H,EARqB,IAU7B,CAhEA,IAyBMR,GAzBNc,GAAAC,EAAA,kBAAAC,IAkBAC,IAGAC,KACAC,KACAC,KAEMpB,GAAqB,IAAI,MCzB/B,IAkCMqB,GAmBCC,GArDPC,GAAAC,EAAA,kBAAAC,IAkBAC,KAEAC,KACAC,KACAC,KACAC,KACAC,KACAC,IACAC,IACAC,IAEAC,KACAC,KACAC,KACAC,KAEMjB,GAA+C,CAACkB,EAAU,CAAE,QAAAC,CAAQ,IAAM,IAAM,CAClF,GAAI,CAACA,EAAQ,QAAS,OAEtB,IAAMC,EAAQC,GAA2B,YAAaH,CAAQ,EAC1D,CAACE,GAELA,EAAM,OAAOA,EAAM,UAAUE,GAAKA,GAAG,OAAO,KAAO,WAAW,EAAI,EAAG,EACjEC,EAACC,EAAK,SAAL,CACG,GAAG,WACH,MAAM,YACN,KAAMC,GACN,OAAQ,SAAY,CAChB,IAAMC,EAAQ,MAAMC,GAAU,WAAYR,EAAQ,OAAO,EACzDS,GAAgBT,EAAQ,GAAIO,CAAK,CACrC,EACJ,CACH,CACL,EAEOzB,GAAQ4B,EAAa,CACxB,KAAM,YACN,YAAa,2CACb,QAAS,CAACC,EAAK,GAAG,EAClB,aAAc,CAAC,wBAAyB,oBAAqB,kBAAkB,EAC/E,SAAAC,GAEA,UAAAJ,GAEA,QAAS,CACL,CACI,KAAM,yBACN,YAAa,CACT,MAAO,sDACP,QAAS,uEACb,CACJ,CACJ,EAEA,OAAQ,CACJK,GAAa,iBAAkBC,GAASV,EAACW,GAAA,CAAqB,QAASD,EAAM,QAAS,CAAE,EAExFE,GAAoB,UAAWnC,EAAe,EAE9CoC,GAAU,eAAgBjB,GACjBA,EAAQ,QAEN,CACH,MAAO,YACP,KAAMM,GACN,QAAAN,EACA,QAASkB,EAAa,WAAWlB,EAAQ,UAAU,EACnD,QAAS,SAAY,CACjB,IAAMO,EAAQ,MAAMC,GAAU,WAAYR,EAAQ,OAAO,EACzDS,GAAgBT,EAAQ,GAAIO,CAAK,CACrC,CACJ,EAX6B,IAYhC,EAED,KAAK,QAAUY,GAAmB,MAAOC,EAAGpB,IAAY,CAChD,CAACY,GAAS,MAAM,eAChB,CAACZ,EAAQ,UAEbA,EAAQ,SAAW,MAAMQ,GAAU,OAAQR,EAAQ,OAAO,GAAG,KACjE,CAAC,CACL,EAEA,MAAO,CACHqB,GAAsB,KAAK,OAAO,EAClCC,GAAuB,UAAWzC,EAAe,EACjD0C,GAAa,cAAc,EAC3BC,GAAgB,gBAAgB,CACpC,EAEA,YAAcC,GACVrB,EAACsB,EAAA,CAAc,KAAI,IACftB,EAACuB,GAAA,CAAqB,WAAYF,EAAY,CAClD,CAER,CAAC,ICpEM,SAASG,GAAkB,CAAE,EAAAC,EAAG,EAAAC,EAAG,MAAAC,CAAM,EAA6C,CACzF,MAAO,CACHC,EAAC,UAAO,IAAI,KAAKH,CAAE,EACnB,KACAG,EAAC,UAAO,IAAI,KAAKF,CAAE,EACnB,SAASC,wBACb,CACJ,CAnDA,IA0BME,GAgCAC,GA+BCC,GAzFPC,GAAAC,EAAA,kBAAAC,IAkBAC,IACAC,KACAC,IACAC,KACAC,IACAC,IAGMX,GAAWY,EAAqB,CAClC,YAAa,CACT,OACA,QAAS,GACT,YAAa,sCACjB,EACA,eAAgB,CACZ,OACA,QAAS,GACT,YAAa,0CACjB,EACA,sBAAuB,CACnB,OACA,QAAS,GACT,YAAa,0DACjB,CACJ,CAAC,EAgBKX,GAAaY,EAAc,KAAK,SAAU,CAAE,KAAAC,EAAM,QAAAC,CAAQ,EAAU,CACtE,OACIhB,EAAC,UACG,KAAK,SACL,QAAS,IAAM,CACXiB,GAAgBF,EAAK,EAAE,CAC3B,EACA,MAAO,CACH,QAAS,OACT,aAAc,SACd,IAAK,MACL,MAAOd,GAAS,MAAM,eAAiBiB,GAAiB,UAAUF,EAASD,EAAK,EAAE,GAAG,YAAc,OACnG,OAAQ,SACZ,GAECd,GAAS,MAAM,aACZD,EAAC,OAAI,MAAO,CAAE,UAAW,KAAM,GAC3BA,EAACmB,GAAA,CACG,KAAK,UACL,IAAKJ,EAAK,aAAaC,EAAS,GAAG,EAAG,CAC9C,EAEHE,GAAiB,QAAQF,EAAUD,EAAK,EAAE,GACnC,CAACC,GAAWI,GAAkB,YAAYL,EAAK,EAAE,GACjDA,EAAa,YACdA,EAAK,QAEhB,CAER,EAAG,CAAE,KAAM,EAAK,CAAC,EAEVZ,GAAQkB,EAAa,CACxB,KAAM,eACN,YAAa,wDACb,QAAS,CAACC,EAAK,EAAE,EACjB,QAAS,CAEL,CACI,KAAM,uBACN,YAAa,CACT,MAAO,sEACP,QAAS,0EACb,CACJ,EAEA,CACI,KAAM,uBACN,YAAa,CACT,MAAO,oEACP,QAAS,IACb,CACJ,EAEA,CACI,KAAM,uBACN,YAAa,CACT,MAAO,uIACP,QAAS,CAACC,EAAGC,EAAO3B,EAAGC,IAAM,gCAAgCD,SAASC,aAAa0B,iBACvF,EACA,UAAW,IAAMvB,GAAS,MAAM,qBACpC,CACJ,EACA,SAAAA,GAEA,kBAAmB,CACf,QAAS,OACT,aAAc,SACd,QAAS,QACb,EAEA,kBAAAL,GAEA,eAAe6B,EAAYD,EAAeE,EAAe,CACrD,GAAI,CAAC,MAAM,QAAQA,CAAQ,EAAG,OAAOA,EAErC,IAAIC,EAAU,EAEd,OAAOD,EAAS,IAAIE,GAChBA,EAAE,OAAS,SACL5B,EAACE,GAAA,CAAY,GAAGuB,EAAO,KAAMD,EAAMG,KAAY,EAC/CC,CACV,CACJ,CACJ,CAAC,IC7GD,SAASC,GAAeC,EAAiBC,EAAgB,CACrD,IAAMC,EAAOC,EAAU,QAAQF,CAAM,EACrC,OAAOG,GAAiB,QAAQJ,EAASC,CAAM,GAAMC,EAAa,YAAcA,EAAK,QACzF,CAEA,SAASG,GAAgB,CAAE,UAAAC,CAAU,EAA2B,CAC5D,IAAMC,EAAsCC,GACxC,CAACC,EAAW,EACZ,KAAO,CAAE,GAAGA,GAAY,eAAeH,CAAS,CAA4B,GAC5E,KACA,CAACI,EAAKC,IAAY,CACd,IAAMC,EAAU,OAAO,KAAKF,CAAG,EACzBG,EAAc,OAAO,KAAKF,CAAO,EAEvC,OAAOC,EAAQ,SAAWC,EAAY,QAAUA,EAAY,MAAMC,GAAOJ,EAAII,IAAQ,IAAI,CAC7F,CACJ,EACMC,EAA2BP,GAAmB,CAACQ,EAAoB,EAAG,IAAMA,GAAqB,aAAa,CAAC,EAC/GhB,EAAUiB,EAAa,WAAWX,CAAS,EAAE,SAOnD,GALI,CAACY,GAAS,MAAM,sBACOC,GAAuB,eAAenB,EAASM,CAAS,GAI/E,CAACY,GAAS,MAAM,uBACZH,IAAqBT,EAAW,OAAO,KAG/C,IAAMc,EAAOjB,EAAU,eAAe,GAAG,GAEnCkB,EAAmB,OAAO,KAAKd,CAAW,EAAE,OAAOe,GAAMA,IAAOF,GAAQ,EAAEG,GAAkB,UAAUD,CAAE,GAAK,CAACJ,GAAS,MAAM,oBAAoB,EACnJM,EAEJ,OAAQH,EAAiB,OAAQ,CAC7B,IAAK,GAAG,MACR,IAAK,GAAG,CACJG,EAAcC,GAAK,SAAS,gBAAgB,OAAO,CAAE,EAAG1B,GAAeC,EAASqB,EAAiB,EAAE,CAAE,CAAC,EACtG,KACJ,CACA,IAAK,GAAG,CACJG,EAAcC,GAAK,SAAS,iBAAiB,OAAO,CAAE,EAAG1B,GAAeC,EAASqB,EAAiB,EAAE,EAAG,EAAGtB,GAAeC,EAASqB,EAAiB,EAAE,CAAE,CAAC,EACxJ,KACJ,CACA,IAAK,GAAG,CACJG,EAAcC,GAAK,SAAS,mBAAmB,OAAO,CAAE,EAAG1B,GAAeC,EAASqB,EAAiB,EAAE,EAAG,EAAGtB,GAAeC,EAASqB,EAAiB,EAAE,EAAG,EAAGtB,GAAeC,EAASqB,EAAiB,EAAE,CAAE,CAAC,EAC3M,KACJ,CACA,QAAS,CACLG,EAAcE,EAAS,QAAQ,aAAa,QACtCC,GAAkB,CAAE,EAAG5B,GAAeC,EAASqB,EAAiB,EAAE,EAAG,EAAGtB,GAAeC,EAASqB,EAAiB,EAAE,EAAG,MAAOA,EAAiB,OAAS,CAAE,CAAC,EAC1JI,GAAK,SAAS,qBACpB,KACJ,CACJ,CAEA,OAAIJ,EAAiB,OAAS,EAEtBO,EAACC,GAAA,CAAQ,KAAML,GACVM,GACGF,EAAC,OACI,GAAGE,EACJ,MAAO,CAAE,WAAY,EAAG,OAAQ,GAAI,QAAS,OAAQ,WAAY,SAAU,OAAQ,EAAG,OAAQ,SAAU,GAExGF,EAACG,GAAA,CAAU,UAAW,EAAG,OAAQ,GAAM,CAC3C,CAER,EAID,IACX,CAxGA,IA2BMA,GAEAtB,GACAU,GA4EAD,GAkBCc,GA5HPC,GAAAC,EAAA,kBAAAC,IAkBAC,IACAC,KACAC,IACAC,IACAC,IACAC,IAEAC,KAEMX,GAAYY,GAA0B,OAAQ,cAAc,EAE5DlC,GAAcmC,GAAc,aAAa,EACzCzB,GAAyByB,GAAc,wBAAwB,EA4E/D1B,GAAW2B,EAAqB,CAClC,sBAAuB,CACnB,OACA,YAAa,0EACb,QAAS,EACb,EACA,qBAAsB,CAClB,OACA,YAAa,2DACb,QAAS,EACb,EACA,oBAAqB,CACjB,OACA,YAAa,0DACb,QAAS,EACb,CACJ,CAAC,EAEMb,GAAQc,EAAa,CACxB,KAAM,kBACN,YAAa,uDACb,QAAS,CAACC,EAAK,OAAQA,EAAK,SAAS,EACrC,SAAA7B,GAEA,QAAS,CAEL,CACI,KAAM,oBACN,YAAa,CACT,MAAO,qEACP,QAAS,iCACb,CACJ,EAEA,CAEI,KAAM,6KACN,YAAa,CACT,MAAO,8CACP,QAAS,iCACb,CACJ,CACJ,EAEA,gBAAkBZ,GACdsB,EAACoB,EAAA,CAAc,KAAI,IACfpB,EAACvB,GAAA,CAAgB,UAAWC,EAAW,CAC3C,CAER,CAAC,IC3JD,IAsBO2C,GAtBPC,GAAAC,EAAA,kBAAAC,IAkBAC,KACAC,IACAC,IAEON,GAAQO,EAAa,CACxB,KAAM,WACN,YAAa,4CACb,QAAS,CAACC,EAAK,GAAG,EAClB,aAAc,CAAC,kBAAkB,EACjC,QAAS,CACL,CACI,KAAM,WACN,YAAa,CACT,MAAO,2BACP,QAAS,CAACC,EAAGC,IAAY,sDAAsDA,YACnF,CACJ,CACJ,EAEA,SAASC,EAAa,CAElBA,EAAMA,EAAI,QAAQ,MAAO,MAAM,EAC/B,IAAMC,EAAYD,EAAI,MAAM,aAAa,GACnC,OAAO,CAACE,EAAMC,IAAS,KAAK,IAAID,EAAMC,EAAK,MAAM,EAAG,GAAQ,GAAK,EAEvE,OAAKF,EACED,EAAI,QAAQ,IAAI,OAAO,MAAMC,KAAc,IAAI,EAAG,EAAE,EADpCD,CAE3B,EAEA,YAAYI,EAAoB,CAC5BA,EAAI,QAAUA,EAAI,QAAQ,QAAQ,kBAAmBC,GAAK,CACtD,IAAMC,EAAQD,EAAE,MAAM;AAAA,CAAI,EAC1B,GAAIC,EAAM,OAAS,EAAG,OAAOD,EAC7B,IAAIE,EAAS,GACb,OAAID,EAAMA,EAAM,OAAS,KAAO,QAAOC,EAASD,EAAM,IAAI,GACnD,GAAGA,EAAM;AAAA,EAAO,KAAK,SAASA,EAAM,MAAM,CAAC,EAAE,KAAK;AAAA,CAAI,CAAC;AAAA,EAAMC,GACxE,CAAC,CACL,EAEA,OAAQ,CACJ,KAAK,QAAUC,GAAmB,CAACV,EAAGM,IAAQ,KAAK,YAAYA,CAAG,CAAC,EACnE,KAAK,QAAUK,GAAmB,CAACC,EAAMC,EAAMP,IAAQ,KAAK,YAAYA,CAAG,CAAC,CAChF,EAEA,MAAO,CACHQ,GAAsB,KAAK,OAAO,EAClCC,GAAsB,KAAK,OAAO,CACtC,CACJ,CAAC,IClED,IAwBMC,GAEAC,GA4BCC,GAtDPC,GAAAC,EAAA,kBAAAC,IAkBAC,KACAC,KACAC,IACAC,IACAC,IAEMV,GAAmB,GAAK,EAExBC,GAAuD,CAACU,EAAU,CAAE,QAAAC,EAAS,QAAS,CAAE,OAAAC,EAAQ,OAAAC,EAAQ,MAAAC,EAAO,GAAIC,CAAU,CAAE,IAAM,IAAM,CAC7I,IAAMC,GAAqBF,EAAQf,MAAsB,EACzD,GAAI,CAACiB,GAAqB,CAACH,EAAO,OAAQ,OAE1C,IAAMI,EAAgBN,EAAQ,UAAU,GAAK,CAAC,EAAEO,GAAgB,sBAAsB,CAAE,GAAIP,EAAQ,EAAG,CAAC,EAAIQ,GAAgB,aAC5H,GAAIP,EAAO,KAAOQ,EAAU,eAAe,EAAE,IAAM,CAACH,EAAe,OAEnE,IAAMI,EAAYC,GAA2B,SAAUZ,CAAQ,EACzDa,EAAcF,GAAW,UAAUG,GAAKA,GAAG,OAAO,KAAO,QAAQ,EACnE,CAACD,GAAe,CAACF,GAErBA,EAAU,OAAOE,EAAc,EAAG,EAC9BE,EAACC,EAAK,SAAL,CACG,GAAG,oBACH,IAAI,oBACJ,MAAOV,EAAoB,oBAAsB,kBACjD,MAAOA,EAAoB,OAAY,SACvC,KAAMA,EAAoBW,GAAeC,GACzC,OAAQ,IACJC,GAAQ,MAAM,CACV,IAAK,aAAalB,EAAQ,eAAeI,IACzC,KAAM,CAAE,MAAOC,EAAoBF,EAAQ,CAACf,GAAmBe,EAAQf,EAAiB,CAC5F,CAAC,EAET,CACH,CACL,EAEOE,GAAQ6B,EAAa,CACxB,KAAM,mBACN,QAAS,CAACC,EAAK,IAAKA,EAAK,SAAS,EAClC,YAAa,8CAEb,OAAQ,CACJC,GAAoB,UAAWhC,EAAuB,CAC1D,EAEA,MAAO,CACHiC,GAAuB,UAAWjC,EAAuB,CAC7D,CACJ,CAAC,IClED,IAwBMkC,GAQCC,GAhCPC,GAAAC,EAAA,kBAAAC,IAkBAC,KACAC,KACAC,IACAC,IACAF,IAEMN,GAAWS,EAAqB,CAClC,cAAe,CACX,OACA,YAAa,mFACb,QAAS,EACb,CACJ,CAAC,EAEMR,GAAQS,EAAa,CACxB,KAAM,kBACN,YAAa,iEACb,QAAS,CAACC,EAAK,MAAM,EACrB,aAAc,CAAC,aAAa,EAC5B,SAAAX,GACA,SAAU,CACN,CACI,KAAM,QACN,YAAa,yDACb,YACA,QAAS,CACL,CACI,OACA,KAAM,OACN,YAAa,6CACb,SAAU,EACd,CACJ,EACA,QAAS,MAAOY,EAAMC,IAAQ,CAC1B,GAAI,CACA,IAAMC,EAAgB,mBAAmBF,EAAK,GAAG,KAAK,EAChD,CAAE,KAAAG,CAAK,EAAI,MAAM,MAAM,kDAAkDD,cAAkBd,GAAS,MAAM,eAAe,EAAE,KAAKgB,GAAYA,EAAS,KAAK,CAAC,EAEjK,GAAI,CAACD,EAAK,OACN,OAAO,KAAKE,GAAeJ,EAAI,QAAQ,GAAI,CAAE,QAAS,mBAAoB,CAAC,EAE/E,IAAMK,EAAaH,EAAK,OAAO,CAACI,EAAMC,IAC3BD,EAAK,UAAYC,EAAK,UAAYD,EAAOC,CACnD,EAEKC,EAAWC,GAAiBA,EAC7B,WAAW;AAAA,EAAQ;AAAA,CAAI,EACvB,QAAQ,iBAAkB,MAAM,EAChC,QAAQ,aAAc,CAACC,EAAGC,IAAS,IAAIA,sDAAyD,mBAAmBA,CAAI,cAAcA,0BAA6B,EAClK,KAAK,EAEV,OAAO,KAAKP,GAAeJ,EAAI,QAAQ,GAAI,CACvC,OAAQ,CACJ,CACI,KAAM,OACN,OAAQ,CACJ,KAAM,gBAAgBK,EAAW,UACjC,IAAK,qDAAqD,mBAAmBA,EAAW,MAAM,GAClG,EACA,MAAOA,EAAW,KAClB,IAAK,mDAAmD,mBAAmBA,EAAW,IAAI,IAC1F,YAAaG,EAAQH,EAAW,UAAU,EAC1C,OAAQ,CACJ,CACI,KAAM,UACN,MAAOG,EAAQH,EAAW,OAAO,CACrC,EACA,CACI,KAAM,yBACN,MAAO,gFAAgFJ,cAAkBF,EAAK,GAAG,mDACrH,CACJ,EACA,MAAO,SACP,OAAQ,CAAE,KAAM,aAAMM,EAAW,UAAU,SAAS,iBAAUA,EAAW,YAAY,SAAS,IAAK,SAAU,6CAA8C,EAC3J,UAAW,IAAI,KAAKA,EAAW,UAAU,EAAE,YAAY,CAC3D,CACJ,CACJ,CAAC,CACL,OAASO,EAAP,CACER,GAAeJ,EAAI,QAAQ,GAAI,CAC3B,QAAS,2BAA2BY,KACxC,CAAC,CACL,CACJ,CACJ,CACJ,CACJ,CAAC,qBCxGD,IAwBMC,GACAC,GAEAC,GAQOC,GAnCbC,GAAAC,EAAA,kBAAAC,IAkBAC,KAEAC,IACAC,IAGMT,GAAiBU,EAAgB,gBAAiB,oBAAoB,EACtET,GAAoBU,GAAe,eAAgB,WAAW,EAE9DT,GAAU,IAAM,IAQTC,GAAsB,CAAC,CAAE,QAAAS,EAAS,MAAAC,EAAO,WAAAC,CAAW,IAC7DC,EAACd,GAAA,KACIa,GAAcC,EAACC,EAAM,UAAN,CAAgB,UAAU,iBAAgB,oBAAkB,EAC5ED,EAACE,EAAA,CACG,UAAU,gBACV,MAAOA,EAAO,OAAO,YACrB,KAAMA,EAAO,MAAM,MAEnB,QAAS,IAAM,CACPC,GAAgB,IAAIhB,GAASU,CAAO,EACpCZ,GAAe,mBAAmBY,EAAQ,EAAE,EAE5CO,GAAO,KAAK,CACR,QAAS,iDACT,GAAI,2CACJ,KAAMA,GAAO,KAAK,QAClB,QAAS,CACL,SAAUA,GAAO,SAAS,MAC9B,CACJ,CAAC,CACT,GAECN,CACL,CACJ,IC3DJ,IA4BMO,GAEAC,GAiBAC,GAsBCC,GArEPC,GAAAC,EAAA,kBAAAC,IAkBAC,IACAC,KACAC,IACAC,IACAC,IACAC,IAGAC,KAEMb,GAAkBc,GAAc,iBAAiB,EAEjDb,GAAWc,EAAqB,CAClC,uBAAwB,CACpB,OACA,YAAa,qDACb,QAAS,EACb,EACA,8BAA+B,CAC3B,OACA,YAAa,6DACb,QAAS,EACb,CACJ,CAAC,EAMKb,GAAoBc,EAAc,KAAK,CAAC,CAAE,KAAAC,CAAK,IAAiB,CAClE,GAAM,CAAE,UAAAC,CAAU,EAAIlB,GAAgB,qBAAqBiB,EAAK,EAAE,GAAK,CAAC,EACxE,GAAI,CAACC,EAAW,OAAO,KAEvB,IAAMC,EAAUC,EAAa,WAAWF,CAAS,EACjD,GAAI,CAACC,EAAS,OAAO,KAErB,IAAME,EAAQC,GAAW,SAASH,EAAQ,QAAQ,EAElD,GAAI,CAACE,EAAO,OAAO,KAEnB,IAAME,EAAS,GAAGF,EAAM,UAAUF,EAAQ,OAE1C,OACIK,EAACC,GAAA,CACG,QAASN,EACT,MAAOI,EACP,WAAYtB,GAAS,MAAM,8BAC/B,CAER,CAAC,EAEME,GAAQuB,EAAa,CACxB,KAAM,gBACN,YAAa,kFACb,QAAS,CAACC,EAAK,SAAS,EACxB,SAAA1B,GAEA,WAAW,CAAE,KAAAgB,CAAK,EAAc,CAC5B,OAAKhB,GAAS,MAAM,uBAIhBuB,EAAC,OAAI,UAAU,uBACXA,EAACtB,GAAA,CAAkB,KAAMe,EAAM,CACnC,EALO,IAOf,EAEA,YAAa,CAAC,CAAE,KAAAA,CAAK,IAAiB,CAClC,IAAMW,EAAaX,EAAK,KAAOY,EAAU,eAAe,EAAE,GAC1D,OACIL,EAAC,OAAI,UAAWI,EAAa,4BAA8B,IACvDJ,EAACtB,GAAA,CAAkB,KAAMe,EAAM,CACnC,CAER,EAEA,QAAS,CAEL,CACI,KAAM,yBACN,YAAa,CACT,MAAO,yCACP,QAAS,oCACb,CACJ,EAEA,CACI,KAAM,sBACN,YAAa,CACT,MAAO,iCACP,QAAS,mCACb,CACJ,CACJ,CACJ,CAAC,ICjHD,IAyBOa,GAzBPC,GAAAC,EAAA,KAAAC,KAkBC,OAAO,gBAAkB,IAAI,KAAO,IAAI,8BAA+B,CACpE,KAAM,8BACN,OAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EACR,WAAY,CAAC,EACb,IAAK,IACT,CAAC,EAEMH,GAAQ,gCCzBf,IA0BMI,GAEFC,GAEEC,GAiBCC,GA/CPC,GAAAC,EAAA,kBAAAC,IAkBAC,IACAC,KACAC,KACAC,IACAC,IAEAP,KAEMJ,GAAW,mEAEbC,GAAO,CAAC,EAENC,GAAWU,EAAqB,CAClC,WAAY,CACR,YAAa,4DACb,OACA,QAAS,CACL,CAAE,MAAO,eAAgB,MAAO,GAAM,QAAS,EAAK,EACpD,CAAE,MAAO,eAAgB,MAAO,EAAM,CAC1C,CACJ,EACA,gBAAiB,CACb,YAAa,8CACb,OACA,QAAS,GACT,cAAe,EACnB,CACJ,CAAC,EAEMT,GAAQU,EAAa,CACxB,KAAM,QACN,YAAa,kFACb,QAAS,CAACC,EAAK,SAAUA,EAAK,MAAOA,EAAK,WAAW,EACrD,SAAAZ,GACA,QAAS,CACL,CACI,KAAM,iBACN,YAAa,CACT,CACI,MAAO,oBACP,QAAS,2BACb,EACA,CACI,MAAO,uDACP,QAAS,uCACb,EACA,CACI,MAAO,qCACP,QAAS,yCACb,CACJ,CACJ,EACA,CACI,KAAM,8BACN,UAAW,IAAMA,GAAS,MAAM,gBAChC,YAAa,CACT,CACI,MAAO,mDACP,QAAS,yCACb,CACJ,CACJ,CACJ,EAGA,KAAAD,GAEA,uBAAwB,IAEhBc,EAACC,GAAA,CAAK,KAAK,0EAAyE,mCAAiC,EAI7H,oBAAoB,CAAE,UAAAC,EAAW,kBAAAC,CAAkB,EAAQ,CACvD,GAAID,EAAU,SAAS,OAAO,GACtBhB,GAAKiB,GACL,MAAO,CACH,gBAAiB,OAAOjB,GAAKiB,MAC7B,eAAgB,QAChB,mBAAoB,SACpB,iBAAkB,WACtB,CAGZ,EAEA,cAAc,CAAE,eAAAC,EAAgB,KAAAC,CAAK,EAAQ,CACzC,GAAI,EAAAD,GAAgB,QAAUjB,GAAS,MAAM,aACzCD,GAAKmB,EAAK,IAAK,OAAOnB,GAAKmB,EAAK,GACxC,EAEA,YAAY,CAAE,OAAAC,CAAO,EAAQ,CACzB,GAAIpB,GAAKoB,GAAS,MAAO,EAC7B,EAEA,gBAAgB,CAAE,eAAAF,EAAgB,KAAAC,CAAK,EAAQ,CAC3C,OAAOD,GAAgB,SAAW,CAAClB,GAAKmB,EAAK,KAAOlB,GAAS,MAAM,WACvE,EAEA,MAAM,OAAQ,CACVoB,GAAYnB,EAAK,EAEjB,IAAMoB,EAAM,MAAM,MAAMvB,EAAQ,EAC5BuB,EAAI,KACJtB,GAAO,MAAMsB,EAAI,KAAK,EACtB,KAAK,KAAOtB,GAEpB,CACJ,CAAC,ICjFD,SAASuB,GAAe,CAAE,KAAAC,EAAM,YAAAC,EAAa,YAAAC,EAAa,MAAAC,EAAO,MAAAC,CAAM,EAAiB,CACpF,GAAM,CAACC,EAAQC,CAAS,EAAIC,EAASP,EAAK,MAAM,EAGhD,GAAIK,EACA,OACIG,EAACP,EAAA,CACG,UAAU,UACV,OAAQI,EACR,UAAWL,EAAK,UAChB,cAAeI,EAAM,sBACrB,IAAKA,EAAM,IACf,EAIR,IAAMK,EAAWN,EAAMH,EAAK,QAASI,CAAK,EAE1C,OAEII,EAACN,EAAA,CACI,GAAGF,EACJ,cAAeI,EAAM,cAErBI,EAAC,QACG,aAAc,IAAM,CAChB,IAAME,EAAUD,IAAW,IAAI,OAAO,SACtC,GAAI,OAAOC,GAAY,SAAU,OAEjC,IAAMC,EAAKD,EAAQ,MAAM,YAAY,IAAI,GAGzC,GAFI,CAACC,GAEDC,GAAS,IAAID,CAAE,EACf,OAEJ,GAAIE,EAAU,QAAQF,CAAE,EACpB,OAAOL,EAAUK,CAAE,EAEvB,IAAMG,EAAQ,IAAM,CAChBF,GAAS,IAAID,CAAE,EAEfI,GAAM,QAAQ,IACVC,GAAU,QAAQL,CAAE,EACf,KAAK,IAAM,CACRL,EAAUK,CAAE,EACZC,GAAS,OAAOD,CAAE,CACtB,CAAC,EACA,MAAMM,GAAK,CACJA,GAAG,SAAW,MACdF,GAAM,QAAQ,IAAMG,GAAM,GAAI,EAAE,KAAKJ,CAAK,CAAC,EAC3CF,GAAS,OAAOD,CAAE,EAE1B,CAAC,EACA,QAAQ,IAAMO,GAAM,GAAG,CAAC,CACjC,CACJ,EAEAJ,EAAM,CACV,GAECL,CACL,CACJ,CAER,CA7GA,IA0BMG,GACAG,GAoFCI,GA/GPC,GAAAC,EAAA,kBAAAC,IAkBAC,KACAC,IACAC,KACAC,KACAC,IACAC,IAGMhB,GAAW,IAAI,IACfG,GAAQ,IAAIc,GAAM,CAAC,EAoFlBV,GAAQW,EAAa,CACxB,KAAM,YACN,YAAa,wGACb,QAAS,CAACC,EAAK,GAAG,EAClB,KAAM,CAAC,iBAAiB,EAExB,QAAS,CAAC,CACN,KAAM,sBACN,YAAa,CAET,MAAO,gHAEP,QAAS,mEACb,CACJ,CAAC,EAED,cAAc7B,EAAaD,EAAaD,EAAMG,EAAOC,EAAO,CACxD,OACII,EAACwB,EAAA,CAAc,KAAI,IACfxB,EAACT,GAAA,CACG,YAAaG,EACb,YAAaD,EACb,KAAMD,EACN,MAAOG,EACP,MAAOC,EACX,CACJ,CAER,CACJ,CAAC,IC5ID,IAsBM6B,GAKCC,GA3BPC,GAAAC,EAAA,kBAAAC,IAkBAC,IACAC,IACAC,IAEMP,GAAS,CAAC,EAKTC,GAAQO,EAAa,CACxB,KAAM,uBACN,YAAa,4DACb,QAAS,CAACC,EAAK,IAAKA,EAAK,KAAK,EAC9B,QAAS,CACL,GAAG,CACC,0BACA,kBACJ,EAAE,IAAIC,IAAS,CACX,KAAAA,EAKA,YAAa,CACT,CACI,MAAO,wCACP,QAAS,4DACb,CACJ,CACJ,EAAE,EACF,CAEI,KAAM,4BACN,YAAa,CACT,MAAO,uEACP,QAAS,CAACC,EAAGC,EAASC,IAAU,uEAC6CA,OAAWD,KAC5F,CACJ,CACJ,EAEA,iBAAiB,EAAe,CAAE,UAAAE,CAAU,EAAG,CAC3C,IAAMC,EAAUC,EAAa,WAAWF,CAAS,EACjD,MAAI,CAACC,GAAW,CAAC,CAAC,EAAG,EAAE,EAAE,SAASA,EAAQ,IAAI,EAAU,GACjD,EAAE,QAAU,CACvB,EAEA,SAASE,EAAgBC,EAAQ,CAC7B,IAAMC,EAAKD,EAAE,MAAM,QAAQ,GAC3B,GAAIE,GAAqB,kBAAkB,IAAMD,EAAI,CACjDF,EAAG,EACH,MACJ,CAEA,IAAMI,EAAQrB,GAAOmB,KAAQ,CAAE,QAAS,OAAQ,EAAG,CAAE,EAErD,aAAaE,EAAK,OAAO,EAGrB,EAAEA,EAAK,GAAK,GACZJ,EAAG,EACH,OAAOjB,GAAOmB,IAGdE,EAAK,QAAU,WAAW,IAAM,CAC5B,OAAOrB,GAAOmB,EAClB,EAAG,GAAG,CAEd,CACJ,CAAC,IC3CD,SAASG,GAAMC,EAAcC,EAAgBC,EAAS,QAAQ,WAAY,CACtE,GAAI,CAACF,EAAM,OAEX,IAAMG,EAAS,IAAI,yBAAyBH,CAAI,EAC5CI,EAAQ,gBAAgB,UAAU,EAAE,KAAKC,GAAKA,EAAE,WAAaJ,EAAS,KAAK,EAC3E,CAACG,IACD,IAAIE,GAAO,YAAY,EAAE,MAAM,UAAUL,EAAS,yCAAyC,EAC3FG,EAAQ,gBAAgB,UAAU,EAAE,KAAKC,GAAKA,EAAE,OAAO,EACvDJ,EAAS,MAAQG,GAAO,SACpB,CAACA,KAETD,EAAO,MAAQC,EACfD,EAAO,OAASF,EAAS,OACzBE,EAAO,KAAOF,EAAS,KACvB,gBAAgB,MAAME,CAAM,EAChC,CAEA,SAASI,GAAMC,EAAa,CACxB,IAAMC,EAAWP,EAAS,QAAQ,WAAW,UACvC,mDACA,6CAEN,OAAOM,EAAI,UAAU,MAAM,EACtB,QAAQC,EAAU,EAAE,EACpB,QAAQ,SAAU,GAAG,EACrB,KAAK,CACd,CAEA,SAASC,GAAWF,EAAaG,EAAcC,EAAiBC,EAAqBC,EAAkB,CACnG,OAAON,EACF,WAAW,WAAYD,GAAMI,CAAI,IAAMA,EAAO,UAAY,GAAG,EAC7D,WAAW,cAAeJ,GAAMK,CAAO,GAAK,SAAS,EACrD,WAAW,mBAAoBL,GAAMM,CAAW,IAAMA,EAAc,UAAY,GAAG,EACnF,WAAW,eAAgBN,GAAMO,CAAQ,IAAMA,EAAW,UAAY,GAAG,CAClF,CAcA,SAASC,GAAoB,CAAE,UAAAC,EAAW,aAAAC,CAAa,EAAeC,EAAe,CAMjF,GALIA,GAAQF,IAAcG,KACtBF,EAAeE,GACfA,GAAkBH,GAGlBA,IAAcC,EAAc,CAC5B,GAAID,EAAW,MAAO,CAACC,EAAe,OAAS,OAAQD,CAAS,EAChE,GAAIC,EAAc,MAAO,CAAC,QAASA,CAAY,CACnD,CAUA,MAAO,CAAC,GAAI,EAAE,CAClB,CAiCA,SAASG,GAAWC,EAAmBC,EAAc,CACjD,IAAMrB,EAAW,OAAO,OAAO,CAAC,EAAGC,EAAS,QAAQ,WAAYmB,CAAY,EACtEE,EAAcC,EAAU,eAAe,EACvCC,EAAYC,GAAmB,WAAW,EAEhD3B,GAAMW,GAAWT,EAASqB,EAAO,WAAYC,EAAY,SAAU,UAAYA,EAAoB,YAAcA,EAAY,SAAUI,GAAiB,QAAQF,EAAWF,EAAY,EAAE,GAAKA,EAAY,QAAQ,EAAGtB,CAAQ,CACjO,CAvJA,IAsCM2B,GAoDFT,GA+DGU,GAzJPC,GAAAC,EAAA,kBAAAC,IAkBAC,IACAC,KACAC,IACAC,KACAC,KACAC,KACAC,IACAC,IACAC,IAYMb,GAAkBc,EAAgB,2BAA4B,gCAAgC,EAmH7Fb,GAAQc,EAAa,CACxB,KAAM,aACN,YAAa,wEACb,QAAS,CAACC,EAAK,GAAG,EAElB,KAAM,CACF,oBAAoB,CAAE,YAAAC,CAAY,EAAmC,CACjE,IAAMpB,EAAYC,GAAmB,WAAW,EAC1CoB,EAAWC,GAAqB,kBAAkB,EAClDC,EAAOxB,EAAU,eAAe,EAAE,GAExC,GAAIyB,EAAa,WAAWH,CAAS,GAAG,OAAS,GAEjD,QAAWI,KAASL,EAAa,CAC7B,GAAM,CAAE,OAAAM,EAAQ,UAAAnC,EAAW,aAAAC,CAAa,EAAIiC,EACtChC,EAAOiC,IAAWH,EACxB,GAAI,CAAC9B,IACG,CAAC4B,GACD9B,IAAc8B,GAAY7B,IAAiB6B,GAAU,SAG7D,GAAM,CAACxB,EAAM8B,CAAE,EAAIrC,GAAoBmC,EAAOhC,CAAI,EAClD,GAAI,CAACI,EAAM,SAEX,IAAM+B,EAAWnD,EAAS,QAAQ,WAAWoB,EAAO,WAC9CX,EAAOO,GAAQ,CAAChB,EAAS,QAAQ,WAAW,WAAa,GAAKsB,EAAU,QAAQ2B,CAAM,EAAE,SACxFtC,EAAcF,IAAUa,EAAU,QAAQ2B,CAAM,EAAU,YAAcxC,GACxEG,EAAWH,IAASgB,GAAiB,QAAQF,EAAW0B,CAAM,GAAKxC,GACnEC,EAAUqC,EAAa,WAAWG,CAAE,EAAE,KAE5CrD,GAAMW,GAAW2C,EAAU1C,EAAMC,EAASC,EAAaC,CAAQ,CAAC,CAGpE,CACJ,EAEA,wBAAyB,CACrB,IAAMwC,EAASP,GAAqB,kBAAkB,EAChDQ,EAAI3B,GAAgB,wBAAwB0B,CAAM,EACxD,GAAI,CAACC,EAAG,OAER,IAAMC,EAAQD,EAAE,MAAQA,EAAE,SAAW,SAAW,OAChDxD,GAAMW,GAAWR,EAAS,QAAQ,WAAWsD,EAAQ,WAAY,GAAIP,EAAa,WAAWK,CAAM,EAAE,KAAM,GAAI,EAAE,CAAC,CACtH,EAEA,wBAAyB,CACrB,IAAMA,EAASP,GAAqB,kBAAkB,EAChDQ,EAAI3B,GAAgB,wBAAwB0B,CAAM,EACxD,GAAI,CAACC,EAAG,OAER,IAAMC,EAAQD,EAAE,MAAQA,EAAE,SAAW,WAAa,SAClDxD,GAAMW,GAAWR,EAAS,QAAQ,WAAWsD,EAAQ,WAAY,GAAIP,EAAa,WAAWK,CAAM,EAAE,KAAM,GAAI,EAAE,CAAC,CACtH,CACJ,EAEA,OAAQ,CACJ,GAAI,OAAO,gBAAoB,KAAe,gBAAgB,UAAU,EAAE,SAAW,EAAG,CACpF,IAAIhD,GAAO,YAAY,EAAE,KACrB,6HACJ,EACA,MACJ,CAEJ,EAEA,aAAc,KAEd,IAAI,SAAU,CACV,OAAO,KAAK,eAAiB,CACzB,MAAO,CACH,OACA,YAAa,iBACb,QAAS,OAAO,iBAAiB,UAAU,EAAE,IAAID,IAAM,CACnD,MAAOA,EAAE,KACT,MAAOA,EAAE,SACT,QAASA,EAAE,OACf,EAAE,GAAK,CAAC,CACZ,EACA,OAAQ,CACJ,OACA,YAAa,kBACb,QAAS,EACT,QAAS,CAAC,EAAG,IAAM,GAAK,IAAM,CAAC,EAC/B,eAAgB,EACpB,EACA,KAAM,CACF,OACA,YAAa,iBACb,QAAS,EACT,QAAS,CAAC,GAAK,GAAK,EAAG,EAAG,EAAG,EAAE,EAC/B,eAAgB,EACpB,EACA,WAAY,CACR,YAAa,eACb,OACA,QAAS,EACb,EACA,UAAW,CACP,YAAa,2DACb,OACA,QAAS,EACb,EACA,YAAa,CACT,OACA,YAAa,eACb,QAAS,iBACb,EACA,aAAc,CACV,OACA,YAAa,gBACb,QAAS,eACb,EACA,YAAa,CACT,OACA,YAAa,eACb,QAAS,+BACb,EACA,YAAa,CACT,OACA,YAAa,mCACb,QAAS,gBACb,EACA,cAAe,CACX,OACA,YAAa,qCACb,QAAS,kBACb,EACA,cAAe,CACX,OACA,YAAa,qCACb,QAAS,mBACb,EACA,gBAAiB,CACb,OACA,YAAa,uCACb,QAAS,qBACb,CACJ,CACJ,EAEA,uBAAuB,CAAE,aAAckD,CAAE,EAAG,CACxC,GAAM,CAACE,EAAWC,CAAgB,EAAIC,GAAQ,IAAM,CAChD,IAAMC,EAAS,gBAAgB,UAAU,EACzC,MAAO,CAACA,EAAO,SAAW,EAAGA,EAAO,KAAKvD,GAAKA,EAAE,KAAK,WAAW,IAAI,CAAC,CAAC,CAC1E,EAAG,CAAC,CAAC,EAECwD,EAAQF,GACV,IAAM,OAAO,KAAK,QAAQ,QAAQ,QAAQ,WAAW,OAAQ,EAAE,OAAOG,GAAKA,EAAE,SAAS,SAAS,CAAC,EAAE,IAAIA,GAAKA,EAAE,MAAM,EAAG,EAAE,CAAC,EACzH,CAAC,CACL,EAEIC,EAA4C,KAChD,GAAKN,EAMOC,IACRK,EAAiBC,EAACC,GAAA,KAAU,gFAA8E,OAP9F,CACZ,IAAIC,EAAQ,6BACZA,GAAS,UAAU,UAAU,YAAY,EAAE,SAAS,OAAO,EACrD,+FACA,wEACNH,EAAiBC,EAACC,GAAA,KAAWC,CAAM,CACvC,CAIA,OACIF,EAACG,EAAM,YAAN,KACGH,EAACG,EAAM,SAAN,KAAe,2GAEhB,EACAH,EAACG,EAAM,SAAN,KAAe,4BACaH,EAAC,YAAM,UAAW,EAAO,KAAEA,EAAC,YAAM,kBAAmB,EAAO,KAAEA,EAAC,YAAM,cAAe,EAAO,QAAKA,EAAC,YAAM,aAAc,EAAQ,IAAI,sKAE9J,EACCN,GACGM,EAAAI,EAAA,KACIJ,EAACG,EAAM,UAAN,CAAgB,UAAWE,EAAQ,MAAO,IAAI,MAAK,qBAAmB,EACvEL,EAAC,OACG,MAAO,CACH,QAAS,OACT,oBAAqB,iBACrB,IAAK,MACT,EACA,UAAW,uBAEVH,EAAM,IAAIS,GACPN,EAACO,EAAA,CAAO,IAAKD,EAAG,QAAS,IAAMlD,GAAWmC,EAAGe,CAAC,GACzCE,GAAa,CAACF,CAAC,CAAC,CACrB,CACH,CACL,CACJ,EAEHP,CACL,CAER,CACJ,CAAC,qBC5TD,SAASU,GAAcC,EAAqB,CACxC,IAAMC,EAAgB,CAAC,EAEvB,QAAWC,KAAU,OAAO,OAAO,QAAQ,QAAQ,OAAO,EAClDA,EAAO,gBAAkB,QAAQ,QAAQ,gBAAgBA,EAAO,IAAI,GACpED,EAAc,KACVE,EAACC,EAAK,UAAL,CACG,MAAOF,EAAO,KACd,IAAK,cAAcA,EAAO,QAEzB,OAAO,QAAQA,EAAO,cAAc,EAAE,IAAI,CAAC,CAACG,EAAMC,CAAM,IAAM,CAC3D,IAAMC,EAAM,cAAcL,EAAO,QAAQG,IAEzC,OACIF,EAACC,EAAK,SAAL,CACG,GAAIG,EACJ,IAAKA,EACL,MAAOF,EACP,OAAQC,EACZ,CAER,CAAC,CACL,CACJ,EAIR,OACIH,EAACC,EAAK,KAAL,CACG,MAAM,aACN,QAASJ,GAETG,EAACC,EAAK,SAAL,CACG,GAAG,2BACH,MAAM,wBACN,OAAQI,GACZ,EACAL,EAACC,EAAK,iBAAL,CACG,GAAG,6BACH,QAASK,EAAS,YAClB,MAAO,kBACP,OAAQ,IAAM,CACVA,EAAS,YAAc,CAACA,EAAS,YACjCT,EAAQ,CACZ,EACJ,EACAG,EAACC,EAAK,SAAL,CACG,GAAG,sBACH,MAAM,gBACN,OAAQ,IAAM,cAAc,SAAS,WAAW,EACpD,EACC,GAAGH,CACR,CAER,CAEA,SAASS,GAAkBC,EAAkB,CACzC,OACIR,EAAC,OAAI,MAAM,6BAA6B,QAAQ,YAAY,MAAO,GAAI,OAAQ,IAC3EA,EAAC,QAAK,KAAK,eAAe,EAAGQ,EAAU,iRAAmR,+aAAgb,CAC9uB,CAER,CAEA,SAASC,IAAsB,CAC3B,GAAM,CAACC,EAAMC,CAAO,EAAIC,EAAS,EAAK,EAEtC,OACIZ,EAACa,GAAA,CACG,SAAS,SACT,MAAM,QACN,UAAWA,GAAO,UAAU,KAC5B,WAAYH,EACZ,eAAgB,IAAMC,EAAQ,EAAK,EACnC,aAAc,IAAMf,GAAc,IAAMe,EAAQ,EAAK,CAAC,GAErD,CAACG,EAAG,CAAE,QAAAN,CAAQ,IACXR,EAACe,GAAA,CACG,UAAU,iBACV,QAAS,IAAMJ,EAAQK,GAAK,CAACA,CAAC,EAC9B,QAASR,EAAU,KAAO,kBAC1B,KAAM,IAAMD,GAAkBC,CAAO,EACrC,SAAUA,EACd,CAER,CAER,CAEA,SAASS,GAAuB,CAAE,SAAAC,CAAS,EAA+B,CACtE,OAAAA,EAAS,OACLA,EAAS,OAAS,EAAG,EACrBlB,EAACmB,EAAA,CAAc,KAAM,IACjBnB,EAACS,GAAA,IAAoB,CACzB,CACJ,EAEOT,EAAAoB,EAAA,KAAGF,CAAS,CACvB,CAjIA,IA6BMH,GAsGCM,GAnIPC,GAAAC,EAAA,kBAAAC,IAkBAC,KAEAC,KACAC,IACAC,KACAC,IACAC,IACAC,IACAC,IAGMjB,GAAgBkB,GAA0B,OAAQ,SAAS,EAsG1DZ,GAAQa,EAAa,CACxB,KAAM,iBACN,YAAa,iGACb,QAAS,CAACC,EAAK,IAAKA,EAAK,QAAQ,EAEjC,QAAS,CACL,CACI,KAAM,mBACN,YAAa,CACT,MAAO,8CACP,QAAS,+BACb,CACJ,CACJ,EAEA,uBAAwBhB,EAAc,KAAKF,GAAwB,CAC/D,SAAU,IAAMjB,EAAC,KAAE,MAAO,CAAE,MAAO,KAAM,GAAG,qBAAmB,CACnE,CAAC,CACL,CAAC,IClFD,SAASoC,GAAUC,EAAa,CAC5B,IAAMC,EAASD,EAAI,WAAW,GAAG,EAAI,MAAQE,GAAS,MAAM,OAEtDC,EAAI,IAAI,IAAIH,EAAK,OAAO,SAAS,IAAI,EAC3CG,EAAE,aAAa,IAAI,OAAQD,GAAS,MAAM,OAAO,EACjDC,EAAE,SAAWA,EAAE,SAAS,QAAQ,sBAAuB,IAAIF,GAAQ,EACnED,EAAMG,EAAE,SAAS,EAEjBA,EAAE,aAAa,IAAI,OAAQ,MAAM,EACjC,IAAMC,EAAcD,EAAE,SAAS,EAE/BE,GAAeL,EAAK,CAChB,SAAUI,EACV,OAAQ,GACZ,CAAC,CACL,CAlFA,IA4BME,GAYAJ,GA4CAK,GA6BAC,GAuCCC,GAxJPC,GAAAC,EAAA,kBAAAC,IAkBAC,KACAC,IACAC,KACAC,IACAC,KACAC,IACAC,IACAC,IAGMd,GAAce,EAAgB,mBAAmB,EAYjDnB,GAAWoB,EAAqB,CAClC,OAAQ,CACJ,OACA,YAAa,+FACb,QAAS,CACL,CACI,MAAO,OACP,MAAO,OACP,QAAS,EACb,EACA,CACI,MAAO,MACP,MAAO,KACX,EACA,CACI,MAAO,MACP,MAAO,KACX,CACJ,CACJ,EACA,QAAS,CACL,OACA,YAAa,wBACb,QAAS,CAAC,MAAO,MAAO,MAAO,OAAQ,OAAQ,MAAM,EAAE,IAAIC,IAAM,CAAE,MAAOA,EAAG,MAAOA,EAAG,QAASA,IAAM,MAAO,EAAE,CACnH,CACJ,CAAC,EAmBKhB,GAA2C,CAACiB,EAAU,CAAE,KAAAC,EAAM,QAAAC,CAAQ,IAAwB,IAAM,CACtG,GAAI,CAACD,EAAM,OACX,IAAME,EAAeC,GAAiB,UAAUF,EAAUD,EAAK,EAAE,GAAG,QAAU,KAE9ED,EAAS,OAAO,GAAI,EAChBK,EAACC,EAAK,UAAL,KACGD,EAACC,EAAK,SAAL,CACG,GAAG,cACH,MAAM,cACN,OAAQ,IAAM/B,GAAUO,GAAY,iBAAiBmB,EAAM,EAAI,CAAC,EAChE,KAAMM,GACV,EACCJ,GACGE,EAACC,EAAK,SAAL,CACG,GAAG,qBACH,MAAM,qBACN,OAAQ,IAAM/B,GAAUO,GAAY,8BAA8B,CAC9D,OAAQmB,EAAK,GACb,OAAQE,EACR,QAAAD,EACA,WAAY,EAChB,EAAG,EAAI,CAAC,EACR,KAAMK,GACV,CAER,CACH,CACL,EAEMvB,GAA4C,CAACgB,EAAU,CAAE,MAAAQ,CAAM,IAAyB,IAAM,CAChG,GAAI,CAACA,EAAO,OAEZ,GAAM,CAAE,GAAAC,EAAI,KAAAC,EAAM,OAAAC,CAAO,EAAIH,EACzB,CAACG,GAAU,CAACD,GAEhBV,EAAS,OAAO,GAAI,EAChBK,EAACC,EAAK,UAAL,KACII,EACGL,EAACC,EAAK,SAAL,CACG,GAAG,YACH,MAAM,YACN,OAAQ,IACJ/B,GAAUO,GAAY,gBAAgB,CAClC,GAAA2B,EACA,KAAAC,EACA,WAAY,EAChB,CAAC,CAAC,EAEN,KAAMH,GACV,EACA,KACHI,EACGN,EAACC,EAAK,SAAL,CACG,GAAG,cACH,MAAM,cACN,OAAQ,IACJ/B,GAAUO,GAAY,kBAAkB,CACpC,GAAA2B,EACA,OAAAE,CACJ,EAAG,EAAI,CAAC,EAEZ,KAAMJ,GACV,EACA,IACR,CACH,CACL,EAEOtB,GAAQ2B,EAAa,CACxB,KAAM,YACN,QAAS,CAACC,EAAK,IAAKA,EAAK,YAAaA,EAAK,MAAM,EACjD,YAAa,8HACb,KAAM,CAAC,gBAAgB,EAEvB,SAAAnC,GAEA,UAAAH,GAEA,OAAQ,CACJuC,GAAoB,eAAgB/B,EAAW,EAC/C+B,GAAoB,gBAAiB9B,EAAY,CACrD,EAEA,MAAO,CACH+B,GAAuB,eAAgBhC,EAAW,EAClDgC,GAAuB,gBAAiB/B,EAAY,CACxD,EAEA,QAAS,CAEL,CACI,KAAM,oCACN,YAAa,CACT,MAAO,kCACP,QAAS,yCACb,CACJ,EAEA,CACI,KAAM,iBACN,YAAa,CAET,MAAO,+DACP,QAEI,yGACR,CACJ,EACA,CACI,KAAM,uBACN,YAAa,CACT,MAAO,uFACP,QAAS,uEACb,CACJ,CACJ,CACJ,CAAC,IC1LM,SAASgC,GAAUC,EAA4C,CAClE,OACIC,EAAC,OAAI,UAAWC,GAAqB,QAChCC,GAAO,aAAa,UAAU,MAAMH,EAAO,KAAM,CAAC,CAAC,CACxD,CAER,CApBA,IASME,GATNE,GAAAC,EAAA,kBAAAC,IAMAC,IACAC,IAEMN,GAAuBO,EAAgB,SAAU,eAAe,IC+BtE,SAASC,GAA6BC,EAAW,CAC7C,OAAO,OAAO,YAAY,OAAO,QAAQA,CAAG,EAAE,KAAK,CAAC,CAACC,CAAE,EAAG,CAACC,CAAE,IAAMD,EAAG,cAAcC,CAAE,CAAC,CAAC,CAC5F,CAEA,SAASC,GAAaC,EAAc,CAChC,IAAMC,EAAQN,GAAW,KAAK,MAAM,KAAK,UAAUK,CAAG,CAAC,CAAC,EACxD,QAAWE,IAAO,CACd,QACA,QACA,aACA,sBACJ,EAAG,OAAOD,EAAM,OAAOC,GAGvB,IAAMC,EAAWF,EACjB,cAAOE,EAAS,YAChB,OAAOA,EAAS,QAChBA,EAAS,aAAa,QAAQC,GAAK,OAAOA,EAAE,OAAO,EAE5CH,CACX,CAEA,SAASI,GAAiBC,EAAcC,EAAcC,EAAqB,CACvE,IAAMN,EAAMO,GAAUC,GAClBC,EAACC,EAAA,KACGD,EAACE,GAAA,CAAW,GAAGH,EAAO,cAClBC,EAACG,GAAA,KACGH,EAACI,EAAA,CAAK,QAAQ,sBAAsB,MAAO,CAAE,SAAU,CAAE,GAAG,UAAQ,EACpEJ,EAACK,GAAA,CAAiB,QAAS,IAAMC,GAAWf,CAAG,EAAG,CACtD,EACAS,EAACO,GAAA,KACGP,EAAC,OAAI,MAAO,CAAE,QAAS,QAAS,GAC3B,CAAC,CAACH,GACCG,EAAAQ,EAAA,KACIR,EAACS,EAAM,UAAN,CAAgB,IAAI,MAAK,SAAO,EACjCT,EAACU,GAAA,CAAU,QAASb,EAAY,KAAK,GAAG,EACxCG,EAACS,EAAM,YAAN,CAAkB,UAAWE,EAAQ,SAAU,CACpD,EAGJX,EAACS,EAAM,UAAN,CAAgB,IAAI,MAAMb,EAAK,OAAK,EACrCI,EAACU,GAAA,CAAU,QAASf,EAAM,KAAK,OAAO,CAC1C,CACJ,EACAK,EAACY,GAAA,KACGZ,EAACa,GAAA,CAAK,YAAa,IACfb,EAACc,EAAA,CAAO,QAAS,IAAMC,GAAcpB,EAAM,GAAGC,6BAAgC,GAAG,QACvEA,EAAK,OACf,EACC,CAAC,CAACC,GACCG,EAACc,EAAA,CAAO,QAAS,IAAMC,GAAclB,EAAY,8BAA8B,GAAG,kBAElF,CAER,CACJ,CACJ,CACJ,CACH,CACL,CAEA,SAASmB,GAAwB3B,EAAc,CAC3CA,EAAMD,GAAaC,CAAG,EACtB,IAAM4B,EAAU,KAAK,UAAU5B,EAAK,KAAM,CAAC,EAE3C,OAAOK,GAAiBuB,EAAS,UAAW5B,EAAI,OAAO,CAC3D,CAaA,SAAS6B,GAAoBC,EAAc,CAoBvC,MAnB8C,CAACC,EAAUrB,IAAU,IAAM,CACrE,GAAKoB,IAAS,SAAW,CAACpB,EAAM,OAAWoB,IAAS,QAAU,CAACpB,EAAM,KAAO,OAC5E,IAAMsB,EAAYD,EAAS,GAAG,EAAE,EAChC,GAAIC,GAAW,MAAQ,oBAAqB,CACxC,IAAMC,EAAID,EAAU,MACf,MAAM,QAAQC,EAAE,QAAQ,IACzBA,EAAE,SAAW,CAACA,EAAE,QAAQ,GAC3B,CAAE,SAAAF,CAAS,EAAIE,CACpB,CAEAF,EAAS,OAAO,GAAI,EAChBpB,EAACuB,EAAK,SAAL,CACG,GAAI,WAAWJ,EAAK,YAAY,QAChC,MAAM,WACN,OAAQ,IAAMzB,GAAiB,KAAK,UAAUK,EAAMoB,EAAK,YAAY,GAAI,KAAM,CAAC,EAAGA,CAAI,EACvF,KAAMK,GACV,CACJ,CACJ,CAEJ,CA5IA,IAiCMA,GA2EAC,GAmCCC,GA/IPC,GAAAC,EAAA,kBAAAC,IAkBAC,KACAC,KACAC,IACAC,KACAC,KACAC,KACAC,IACAC,KACAC,KACAC,KACAC,IACAC,IAIMjB,GAAW,IACNxB,EAAC,OAAI,QAAQ,YAAY,KAAK,eAAe,cAAY,OAAO,MAAM,KAAK,OAAO,MACrFA,EAAC,QAAK,EAAE,mZAAmZ,EAC3ZA,EAAC,QAAK,EAAE,mZAAmZ,CAC/Z,EAuEEyB,GAAWiB,EAAqB,CAClC,YAAa,CACT,YAAa,iEACb,OACA,QAAS,CACL,CAAE,MAAO,sCAAuC,MAAO,OAAQ,QAAS,EAAK,EAC7E,CAAE,MAAO,uCAAwC,MAAO,OAAQ,CACpE,CACJ,CACJ,CAAC,EA0BMhB,GAAQiB,EAAa,CACxB,KAAM,UACN,YAAa,sEACb,QAAS,CAACC,EAAK,SAAUA,EAAK,IAAKA,EAAK,IAAKA,EAAK,MAAM,EACxD,aAAc,CAAC,mBAAmB,EAClC,SAAAnB,GAEA,OAAQ,CACJoB,GAAU,UAAWxD,GAAO,CACxB,IAAMyD,EAAc,IAAM,CAClBrB,GAAS,MAAM,cAAgB,QAC/BV,GAAc1B,EAAI,OAAO,EAEzB2B,GAAwB3B,CAAG,CAEnC,EAEM0D,EAAoBC,GAAK,CACvBvB,GAAS,MAAM,cAAgB,QAC/BuB,EAAE,eAAe,EACjBA,EAAE,gBAAgB,EAClBjC,GAAc1B,EAAI,OAAO,IAEzB2D,EAAE,eAAe,EACjBA,EAAE,gBAAgB,EAClBhC,GAAwB3B,CAAG,EAEnC,EAMA,MAAO,CACH,MALUoC,GAAS,MAAM,cAAgB,QACvC,iDACA,iDAIF,KAAMD,GACN,QAASnC,EACT,QAAS4D,EAAa,WAAW5D,EAAI,UAAU,EAC/C,QAASyD,EACT,cAAeC,CACnB,CACJ,CAAC,EAEDG,GAAoB,gBAAiBhC,GAAoB,OAAO,CAAC,EACjEgC,GAAoB,kBAAmBhC,GAAoB,SAAS,CAAC,EACrEgC,GAAoB,eAAgBhC,GAAoB,MAAM,CAAC,CACnE,EAEA,MAAO,CACHiC,GAAa,gBAAgB,EAC7BC,GAAuB,gBAAiBlC,GAAoB,OAAO,CAAC,EACpEkC,GAAuB,kBAAmBlC,GAAoB,SAAS,CAAC,EACxEkC,GAAuB,eAAgBlC,GAAoB,MAAM,CAAC,CACtE,CACJ,CAAC,qBCrMD,IAqBamC,GArBbC,GAAAC,EAAA,kBAAAC,IAkBAC,IACAC,IAEaL,GAAWM,EAAqB,CACzC,iBAAkB,CACd,OACA,YAAa,oBACb,QAAS,EACb,EACA,iBAAkB,CACd,OACA,YAAa,oBACb,QAAS,EACb,CACJ,CAAC,IChCD,IAwBMC,IAxBNC,GAAAC,EAAA,kBAAAC,IAmBAC,IAGAC,KAEML,IAAS,cAAc,cAAc,gBCxB3C,IAoBaM,GApBbC,GAAAC,EAAA,kBAAAC,IAkBAC,KAEaJ,GAAKK,GAAiB,UAAU,ICpB7C,IA2BMC,GAOOC,GAlCbC,GAAAC,EAAA,kBAAAC,IAkBAA,KACAC,IAEAC,KAMMN,GAAeO,GAA2C,YAAa,gBAAgB,EAOhFN,GAAe,CAAC,CACzB,IAAAO,EACA,SAAAC,EACA,UAAAC,CACJ,IAA2B,CACvB,IAAMC,EAAaC,GAAS,CACxB,KAAM,CAACF,CAAS,CACpB,CAAC,EAEKG,EAAkBH,EAAY,KAAK,MAAMC,EAAa,GAAI,EAAI,EAC9DG,EAAkB,KAAK,MAAMD,EAAkB,EAAE,EAAI,KAAOA,EAAkB,IAAI,SAAS,EAAE,SAAS,EAAG,GAAG,EAElH,OAAIL,GAAO,CAACE,EACDK,EAACf,GAAA,CAAa,IAAKQ,EAAK,IAAKA,EAAK,SAAUC,EAAU,EAG7DM,EAAC,OAAI,UAAWC,GAAG,UAAWN,EAAY,oBAAsB,CAAC,CAAC,GAC9DK,EAAC,OAAI,UAAWC,GAAG,mBAAmB,EAAG,EACzCD,EAAC,OAAI,UAAWC,GAAG,cAAc,GAAIF,CAAgB,EACrDC,EAAC,OAAI,UAAWC,GAAG,eAAe,GAAIN,EAAY,YAAc,MAAO,CAC3E,CAER,ICxDA,IAuBaO,GAvBbC,GAAAC,EAAA,kBAAAC,IAkBAC,IAGAC,KAEaL,GAAkC,CAAC,CAAE,aAAAM,EAAc,kBAAAC,CAAkB,IAAM,CACpF,GAAM,CAACC,EAAWC,CAAY,EAAIC,EAAS,EAAK,EAC1C,CAACC,EAAQC,CAAS,EAAIF,EAAS,EAAK,EACpC,CAACG,EAAUC,CAAW,EAAIJ,EAAwB,EAClD,CAACK,EAAQC,CAAS,EAAIN,EAAiB,CAAC,CAAC,EAEzCO,EAAmBT,GAAuB,CAC5CC,EAAaD,CAAS,EACtBD,IAAoBC,CAAS,CACjC,EAEA,SAASU,GAAkB,CACF,CAACV,EAGlB,UAAU,aAAa,aAAa,CAChC,MAAO,CACH,iBAAkBW,GAAS,MAAM,iBACjC,iBAAkBA,GAAS,MAAM,gBACrC,CACJ,CAAC,EAAE,KAAKC,GAAU,CACd,IAAML,EAAS,CAAC,EAChBC,EAAUD,CAAM,EAEhB,IAAMF,EAAW,IAAI,cAAcO,CAAM,EACzCN,EAAYD,CAAQ,EACpBA,EAAS,iBAAiB,gBAAiBQ,GAAK,CAC5CN,EAAO,KAAKM,EAAE,IAAI,CACtB,CAAC,EACDR,EAAS,MAAM,EAEfI,EAAgB,EAAI,CACxB,CAAC,EAEGJ,IACAA,EAAS,iBAAiB,OAAQ,IAAM,CACpCP,EAAa,IAAI,KAAKS,EAAQ,CAAE,KAAM,wBAAyB,CAAC,CAAC,EAEjEE,EAAgB,EAAK,CACzB,CAAC,EACDJ,EAAS,KAAK,EAG1B,CAEA,OACIS,EAAAC,EAAA,KACID,EAACE,EAAA,CAAO,QAASN,GACZV,EAAY,OAAS,QAAQ,YAClC,EAEAc,EAACE,EAAA,CACG,SAAU,CAAChB,EACX,QAAS,IAAM,CACXI,EAAU,CAACD,CAAM,EACbA,EAAQE,GAAU,OAAO,EACxBA,GAAU,MAAM,CACzB,GAECF,EAAS,SAAW,QAAQ,YACjC,CACJ,CAER,ICdA,SAASc,GAAUC,EAAYC,EAAqB,CAChD,IAAMC,EAAYC,GAAqB,aAAa,EAC9CC,EAAQC,GAAkB,gBAAgBH,CAAS,EACrDE,GAAOE,EAAe,SAAS,CAAE,KAAM,uBAAwB,UAAAJ,CAAU,CAAC,EAE9E,IAAMK,EAAS,IAAIC,GAAW,YAAY,CACtC,KAAM,IAAI,KAAK,CAACR,CAAI,EAAG,oBAAqB,CAAE,KAAM,wBAAyB,CAAC,EAC9E,OAAQ,GACR,YAAa,GACb,SAAU,CACd,EAAGE,EAAW,GAAO,CAAC,EAEtBK,EAAO,GAAG,WAAY,IAAM,CACxBE,GAAQ,KAAK,CACT,IAAK,aAAaP,aAClB,KAAM,CACF,MAAO,GAAK,GACZ,WAAYA,EACZ,QAAS,GACT,MAAOQ,GAAe,cAAc,KAAK,IAAI,CAAC,EAC9C,YAAa,CAAC,EACd,KAAM,EACN,YAAa,CAAC,CACV,GAAI,IACJ,SAAUH,EAAO,SACjB,kBAAmBA,EAAO,iBAC1B,SAAUN,EAAK,SACf,cAAeA,EAAK,QACxB,CAAC,EACD,kBAAmBG,EAAQO,GAAe,8BAA8BP,CAAK,GAAG,iBAAmB,IACvG,CACJ,CAAC,CACL,CAAC,EACDG,EAAO,GAAG,QAAS,IAAMK,GAAU,iCAAkCC,GAAO,KAAK,OAAO,CAAC,EAEzFN,EAAO,OAAO,CAClB,CAEA,SAASO,IAAe,CACpB,GAAM,CAACC,EAAKC,CAAM,EAAIC,EAAiB,EAOvC,MAAO,CAACF,EANaf,GAAe,CAC5Be,GACA,IAAI,gBAAgBA,CAAG,EAC3BC,EAAO,IAAI,gBAAgBhB,CAAI,CAAC,CACpC,CAEwB,CAC5B,CAEA,SAASkB,GAAM,CAAE,WAAAC,CAAW,EAAgC,CACxD,GAAM,CAACC,EAAaC,CAAY,EAAIJ,EAAS,EAAK,EAC5C,CAACjB,EAAMsB,CAAO,EAAIL,EAAe,EACjC,CAACM,EAASC,CAAU,EAAIV,GAAa,EAE3CW,GAAU,IAAM,IAAM,CACdF,GACA,IAAI,gBAAgBA,CAAO,CACnC,EAAG,CAACA,CAAO,CAAC,EAEZ,GAAM,CAACtB,CAAI,EAAIyB,GAAW,SAAY,CAClC,GAAI,CAAC1B,EAAM,OAAO2B,GAGlB,IAAMC,EAAc,MADC,IAAI,aAAa,EACC,gBAAgB,MAAM5B,EAAK,YAAY,CAAC,EACzE6B,EAAcD,EAAY,eAAe,CAAC,EAG1CE,EAAO,IAAI,WAAWC,GAAO,MAAM,KAAK,MAAMH,EAAY,SAAW,EAAE,EAAG,KAAK,IAAI,GAAIC,EAAY,MAAM,EAAG,GAAG,CAAC,EAChHG,EAAgB,KAAK,MAAMH,EAAY,OAASC,EAAK,MAAM,EAGjE,QAASG,EAAS,EAAGA,EAASH,EAAK,OAAQG,IAAU,CACjD,IAAIC,EAAU,EACd,QAASC,EAAe,EAAGA,EAAeH,EAAeG,IAAgB,CACrE,IAAMC,EAAYH,EAASD,EAAgBG,EAC3CD,GAAWL,EAAYO,IAAc,CACzC,CACAN,EAAKG,GAAU,CAAC,EAAE,KAAK,KAAKC,EAAUF,CAAa,EAAI,IAC3D,CAGA,IAAMK,EAAS,KAAK,IAAI,GAAGP,CAAI,EACzBQ,EAAQ,GAAK,IAAOD,EAAS,GAAK,KAAK,IAAI,EAAG,KAAOA,EAAS,MAAS,CAAC,EAC9E,QAASE,EAAI,EAAGA,EAAIT,EAAK,OAAQS,IAAKT,EAAKS,GAAK,KAAK,IAAI,IAAM,CAAC,EAAET,EAAKS,GAAKD,EAAM,EAElF,MAAO,CACH,SAAU,OAAO,KAAK,OAAO,aAAa,GAAGR,CAAI,CAAC,EAClD,SAAUF,EAAY,QAC1B,CACJ,EAAG,CACC,KAAM,CAAC5B,CAAI,EACX,cAAe2B,EACnB,CAAC,EAED,OACIa,EAACC,GAAA,CAAW,GAAGtB,GACXqB,EAACE,GAAA,KACGF,EAACG,EAAM,UAAN,KAAgB,sBAAoB,CACzC,EAEAH,EAACI,GAAA,CAAa,UAAWC,GAAG,OAAO,GAC/BL,EAAC,OAAI,UAAWK,GAAG,SAAS,GACxBL,EAACM,GAAA,CACG,aAAc9C,GAAQ,CAClBsB,EAAQtB,CAAI,EACZwB,EAAWxB,CAAI,CACnB,EACA,kBAAmBqB,EACvB,EAEAmB,EAACO,EAAA,CACG,QAAS,SAAY,CACjB,IAAMC,EAAO,MAAMC,GAAW,SAAS,EACnCD,IACA1B,EAAQ0B,CAAI,EACZxB,EAAWwB,CAAI,EAEvB,GACH,aAED,CACJ,EAEAR,EAACG,EAAM,UAAN,KAAgB,SAAO,EACxBH,EAACU,GAAA,CACG,IAAK3B,EACL,SAAUtB,EAAK,SACf,UAAWmB,EACf,CAEJ,EAEAoB,EAACW,GAAA,KACGX,EAACO,EAAA,CACG,SAAU,CAAC/C,EACX,QAAS,IAAM,CACXD,GAAUC,EAAOC,CAAI,EACrBkB,EAAW,QAAQ,EACnBP,GAAU,iDAAkDC,GAAO,KAAK,OAAO,CACnF,GACH,MAED,CACJ,CACJ,CAER,CA1NA,IAqCML,GACAH,GACA+C,GAOAN,GAECO,GAmBD1B,GAyJA2B,GA5NNC,GAAAC,EAAA,kBAAAC,IAkBAC,KAEAC,KACAC,KACAC,IACAC,KACAL,KACAM,IACAC,KACAC,IACAC,IAGAC,KACAC,KACAC,KACAC,KACAC,KAEM/D,GAAagE,EAAgB,aAAa,EAC1CnE,GAAoBoE,GAAc,mBAAmB,EACrDrB,GAAgBoB,EAAgB,aAAc,aAAc,aAAa,EAOzE1B,GAA4D4B,GAE3DrB,GAAQsB,EAAa,CACxB,KAAM,gBACN,YAAa,yHACb,QAAS,CAACC,EAAK,IAAKA,EAAK,IAAKA,EAAK,OAAO,EAC1C,SAAAC,GAEA,OAAQ,CACJC,GAAoB,iBAAkBxB,EAAY,CACtD,EAEA,MAAO,CACHyB,GAAuB,iBAAkBzB,EAAY,CACzD,CACJ,CAAC,EAMK3B,GAA4B,CAC9B,SAAU,eACV,SAAU,CACd,EAsJM2B,GAA4C,CAAC0B,EAAUC,IAAU,IAAM,CACrEA,EAAM,QAAQ,UAAY,EAAEC,GAAgB,IAAIC,GAAgB,oBAAqBF,EAAM,OAAO,GAAKC,GAAgB,IAAIC,GAAgB,cAAeF,EAAM,OAAO,IAE3KD,EAAS,KACLxC,EAAC4C,EAAK,SAAL,CACG,GAAG,eACH,MACI5C,EAAC,OAAI,UAAWY,GAAc,aAC1BZ,EAAC6C,GAAA,CAAW,UAAWjC,GAAc,WAAY,OAAQ,GAAI,MAAO,GAAI,EACxEZ,EAAC,OAAI,UAAWY,GAAc,YAAY,oBAAkB,CAChE,EAEJ,OAAQ,IAAMkC,GAAUnE,GAAcqB,EAACtB,GAAA,CAAM,WAAYC,EAAY,CAAE,EAC3E,CACJ,CACJ,IChNA,eAAeoE,GAAWC,EAAa,CACnC,IAAMC,EAAM,MAAM,MAAMD,CAAG,EAC3B,GAAIC,EAAI,SAAW,IAEnB,OAAO,MAAMA,EAAI,KAAK,CAC1B,CAhCA,IAyBMC,GAUAC,GAaCC,GAhDPC,GAAAC,EAAA,kBAAAC,IAkBAC,IACAC,IACAC,IACAC,KACAC,IACAC,IAEMX,GAAmBY,EAAgB,2BAA2B,EAU9DX,GAAWY,EAAqB,CAGlC,QAAS,CACL,OACA,YAAa,8EAGb,QAAS,GACT,cAAe,EACnB,CACJ,CAAC,EAEMX,GAAQY,EAAa,CACxB,KAAM,kBACN,YAAa,+IACb,QAAS,CAACC,EAAK,GAAG,EAClB,iBAAkB,GAClB,SAAU,GAEV,SAAAd,GAEA,OAAQ,CACAA,GAAS,MAAM,UACf,OAAO,oBAAoB,cAAeD,GAAiB,sBAAsB,EACjF,OAAO,iBAAiB,cAAeA,GAAiB,yBAAyB,EACjF,KAAK,iBAAmB,GAEhC,EAEA,MAAO,CACC,KAAK,mBACL,OAAO,oBAAoB,cAAeA,GAAiB,yBAAyB,EACpF,OAAO,iBAAiB,cAAeA,GAAiB,sBAAsB,EAEtF,EAEA,QAAS,CAEL,CAII,KAAM,mBACN,YAAa,CACT,CAEI,MAAO,wBACP,QAAS,WACb,EAEA,CACI,MAAO,eACP,QAAS,uCACb,CACJ,CACJ,EAGA,CACI,KAAM,kBACN,YAAa,CACT,CAEI,MAAO,0BACP,QAAS,OACb,EACA,CACI,MAAO,uCACP,QAAS,cACb,EACA,CACI,MAAO,oCACP,QAAS,qDACb,EACA,CACI,MAAO,oCACP,QAAS,qDACb,CACJ,CACJ,EAGA,CACI,KAAM,wBACN,IAAK,GACL,UAAW,IAAMC,GAAS,MAAM,QAChC,YAAa,CAET,MAAO,yBACP,QAAS,aACb,CACJ,EAGA,CACI,KAAM,+BACN,UAAW,IAAMA,GAAS,MAAM,QAChC,YAAa,CACT,MAAO,kDACP,QAAS,YACb,CACJ,EAGA,CACI,KAAM,iCACN,UAAW,IAAMA,GAAS,MAAM,QAChC,YAAa,CACT,MAAO,6DACP,QAAS,SACb,CACJ,EACA,CACI,KAAM,uCACN,UAAW,IAAMA,GAAS,MAAM,QAChC,YAAa,CACT,CAEI,MAAO,4BACP,QAAS,EACb,EACA,CAEI,MAAO,8BACP,QAAS,UACb,CACJ,CACJ,EACA,CACI,KAAM,sBACN,UAAW,IAAMA,GAAS,MAAM,QAChC,YAAa,CACT,MAAO,kBACP,QAAS,uBACb,CACJ,EAGA,CACI,KAAM,iCACN,YAAa,CACT,MAAO,mDACP,QAAS,+CACb,CACJ,CACJ,EAEA,MAAM,UAAUH,EAAa,CAGzB,IAAMkB,EAAM,IAAI,MAChBA,EAAI,OAAS,IAAM,CACf,IAAMC,EAAS,SAAS,cAAc,QAAQ,EAC9CA,EAAO,MAAQD,EAAI,aACnBC,EAAO,OAASD,EAAI,cACpBC,EAAO,WAAW,IAAI,EAAG,UAAUD,EAAK,EAAG,CAAC,EAE5CC,EAAO,OAAOC,GAAQ,CAClB,UAAU,UAAU,MAAM,CACtB,IAAI,cAAc,CACd,YAAaA,CACjB,CAAC,CACL,CAAC,CACL,EAAG,WAAW,CAClB,EACAF,EAAI,YAAc,YAClBA,EAAI,IAAMlB,CACd,EAEA,MAAM,UAAUA,EAAa,CACzB,IAAMoB,EAAO,MAAMrB,GAAWC,CAAG,EACjC,GAAI,CAACoB,EAAM,OAEX,IAAMC,EAAO,IAAI,IAAIrB,CAAG,EAAE,SAAS,MAAM,GAAG,EAAE,IAAI,EAC5CsB,EAAO,IAAI,KAAK,CAACF,CAAI,EAAGC,EAAM,CAAE,KAAMD,EAAK,IAAK,CAAC,EAEvDG,GAASD,CAAI,CACjB,EAEA,MAAO,CACH,IAAME,EAAY,SAAS,aAAa,EACpC,CAACA,GAELC,GAAU,KAAKD,EAAU,SAAS,CAAC,CACvC,EAEA,KAAM,CACF,KAAK,KAAK,EACVE,GAAkB,SAAS,cAAe,CAAE,QAAS,EAAG,CAAC,CAC7D,EAEA,MAAM,OAAQ,CACV,IAAMC,GAAQ,MAAM,UAAU,UAAU,KAAK,GAAG,GAChD,GAAI,CAACA,EAAM,OAEX,IAAMP,EAAO,IAAI,aACjB,QAAWQ,KAAQD,EAAK,MACpB,GAAIC,IAAS,YAAa,CACtB,IAAMN,EAAO,IAAI,KAAK,CAAC,MAAMK,EAAK,QAAQC,CAAI,CAAC,EAAG,cAAe,CAAE,KAAAA,CAAK,CAAC,EACzER,EAAK,MAAM,IAAIE,CAAI,CACvB,SAAWM,IAAS,aAAc,CAC9B,IAAMC,EAAO,MAAMF,EAAK,QAAQC,CAAI,EACpCR,EAAK,QAAQQ,EAAM,MAAMC,EAAK,KAAK,CAAC,CACxC,CAGJ,SAAS,cACL,IAAI,eAAe,QAAS,CACxB,cAAeT,CACnB,CAAC,CACL,CACJ,CACJ,CAAC,ICxPD,IAuBMU,GAECC,GAzBPC,GAAAC,EAAA,kBAAAC,IAkBAC,IACAC,IACAC,IACAC,IAEMR,GAAWS,EAAgB,gBAAiB,aAAa,EAExDR,GAAQS,EAAa,CACxB,KAAM,cACN,YAAa,yLACb,QAAS,CAACC,EAAK,GAAG,EAClB,iBAAkB,GAElB,MAAM,EAAkB,CAGpB,GAFgB,EAAE,SAAY,EAAE,SAAW,UAAU,SAAS,SAAS,KAAK,EAE/D,OAAQ,EAAE,IAAK,CACxB,IAAK,IACL,IAAK,IACD,EAAE,eAAe,EACb,EAAE,UACEC,GAAmB,WAAW,GAAGC,GAAiB,kBAAkB,KAAK,EAC7EC,GAAkB,aAAa,kBAAkB,GAEjDC,EAAe,SAAS,CACpB,KAAM,qBACN,MAAO,GACP,UAAW,IACf,CAAC,EAEL,MACJ,IAAK,IACD,EAAE,eAAe,EACjBC,GAAe,KAAK,YAAY,EAChC,MACJ,IAAK,OACe,EAAE,SAAWhB,GAAS,YAAcA,GAAS,aACrD,OAAO,CAAC,EAChB,MACJ,QACQ,EAAE,KAAO,KAAO,EAAE,KAAO,MACzB,EAAE,eAAe,EACjBA,GAAS,cAAc,OAAO,EAAG,OAAO,EAAE,KAAK,GAEnD,KACR,CACJ,EAEA,OAAQ,CACJ,SAAS,iBAAiB,UAAW,KAAK,KAAK,CACnD,EAEA,MAAO,CACH,SAAS,oBAAoB,UAAW,KAAK,KAAK,CACtD,CACJ,CAAC,ICtCD,SAASiB,GAAeC,EAAcC,EAAsBC,EAAc,CACtE,IAAMC,EAAMF,EAAM,MAAQA,EAAM,GAAK,IAAIA,EAAM,KAAO,IACtD,OAAOG,GAAQ,IAAI,CACf,IAAK,aAAaJ,EAAI,uBAAuBA,EAAI,gBAAgBG,IACjE,MAAO,CACH,MAAO,IACP,KAAAD,CACJ,EACA,cAAe,EACnB,CAAC,EACI,KAAKG,GAAOC,EAAe,SAAS,CACjC,KAAM,6BACN,UAAWN,EAAI,WACf,UAAWA,EAAI,GACf,MAAOK,EAAI,KACX,MAAAJ,EACA,aAAcC,CAClB,CAAC,CAAC,EACD,MAAM,QAAQ,KAAK,EACnB,QAAQ,IAAMK,GAAM,GAAG,CAAC,CACjC,CAEA,SAASC,GAAsBR,EAAcS,EAAkBP,EAAc,CACzE,IAAMC,EAAM,GAAGH,EAAI,MAAMS,EAAE,QAAQA,EAAE,IAAM,MAAMP,IAC3CQ,EAAQC,GAAUR,KAAS,CAAE,QAAS,GAAO,MAAO,CAAC,CAAE,EAC7D,OAAKO,EAAM,UACPE,GAAM,QAAQ,IAAMb,GAAeC,EAAKS,EAAGP,CAAI,CAAC,EAChDQ,EAAM,QAAU,IAGbA,EAAM,KACjB,CAEA,SAASG,GAAoBC,EAAe,CACxC,OAAO,SAAyBC,EAAgBC,EAAgB,CAC5D,OACIC,EAACC,GAAA,CAAQ,KAAMJ,EAAM,MAAM,CAAC,EAAE,IAAIK,GAAKA,EAAE,QAAQ,EAAE,KAAK,IAAI,GACvD,CAAC,CAAE,aAAAC,EAAc,aAAAC,CAAa,IAC3BJ,EAAC,OACG,UAAWK,GAAa,UACxB,aAAcF,EACd,aAAcC,GACjB,IACKP,EAAM,OAAS,CACrB,CAER,CAER,CACJ,CAEA,SAASS,GAAkBC,EAAkD,CACzEA,EAAM,gBAAgB,CAC1B,CAxFA,IA6BMC,GACAH,GAEAV,GACFD,GAyDGe,GA1FPC,GAAAC,EAAA,kBAAAC,IAkBAC,KACAC,IACAC,KACAC,KACAJ,KACAK,IACAC,IACAC,IAIMX,GAAkBY,GAAwB,oBAAqB,gCAAgC,EAC/Ff,GAAegB,EAAgB,YAAa,YAAa,kBAAmB,iBAAiB,EAE7F1B,GAAQ,IAAI2B,GA0DXb,GAAQc,EAAa,CACxB,KAAM,aACN,YAAa,wDACb,QAAS,CAACC,EAAK,IAAKA,EAAK,QAAQ,EAEjC,QAAS,CAAC,CACN,KAAM,gBACN,YAAa,CACT,MAAO,wEACP,QAAS,0CACb,CACJ,EAAG,CACC,KAAM,wCACN,YAAa,CACT,MAAO,4CACP,QAAS,uBACb,CACJ,CAAC,EAED,YAAYC,EAAmB,CAC3B,OAAOA,EAAM,QAAQ,UAAU,OAAS,GAAK,KACzCzB,EAAC0B,EAAA,CAAc,KAAI,IACf1B,EAAC,KAAK,aAAL,CAAmB,GAAGyB,EAAO,CAClC,CAER,EAEA,aAAa,CAAE,QAAAE,EAAS,MAAA3C,EAAO,KAAAC,CAAK,EAAe,CAC/C,IAAM2C,EAAcC,GAAgB,EACpCC,EAAM,UAAU,IAAM,CAClB,IAAMC,EAAMvC,GAAW,CACfA,EAAE,YAAcmC,EAAQ,IACxBC,EAAY,CACpB,EACA,OAAAvC,EAAe,UAAU,6BAA8B0C,CAAE,EAElD,IAAM1C,EAAe,YAAY,6BAA8B0C,CAAE,CAC5E,EAAG,CAACJ,EAAQ,EAAE,CAAC,EAEf,IAAMjC,EAAYH,GAAsBoC,EAAS3C,EAAOC,CAAI,EACtDY,EAAQ,OAAO,OAAOH,CAAS,EAAE,OAAO,OAAO,EAErD,QAAWsC,KAAQnC,EACfR,EAAe,SAAS,CACpB,KAAM,cACN,KAAA2C,CACJ,CAAC,EAGL,OACIhC,EAAC,OACG,MAAO,CAAE,WAAY,QAAS,UAAW,YAAa,GAEtDA,EAAC,OAAI,QAASM,IACVN,EAACQ,GAAA,CACG,MAAOX,EACP,QAASoC,EAAa,WAAWN,EAAQ,UAAU,GAAG,SACtD,WAAY,GACZ,IAAK,EACL,+BAA8B,GAC9B,eAAc,GACd,gBAAiB/B,GAAoBC,CAAK,EAC9C,CACJ,CACJ,CAER,EAEA,IAAI,UAAUqC,EAAY,CACtBxC,GAAYwC,CAChB,CACJ,CAAC,ICjKD,IAsBOC,GAtBPC,GAAAC,EAAA,kBAAAC,IAkBAC,KACAC,IACAC,IAEON,GAAQO,EAAa,CACxB,KAAM,aACN,YAAa,6DACb,QAAS,CAACC,EAAK,IAAI,EACnB,aAAc,CAAC,aAAa,EAC5B,SAAU,CACN,CACI,KAAM,aACN,YAAa,uCACb,YACA,QAAS,CACL,CACI,KAAM,SACN,YAAa,qBACb,OACA,SAAU,EACd,CACJ,EACA,QAAS,MAAOC,EAAGC,IAAQ,CACvB,IAAMC,EAAOC,GAAWH,EAAG,SAAU,EAAE,EAEvC,GAAI,CAACE,EACD,OAAOE,GAAeH,EAAI,QAAQ,GAAI,CAClC,QAAS,sBACb,CAAC,EAGL,IAAMI,EAAmB,IAAI,gBAAgB,CACzC,OAAQ,QACR,OAAQ,OACR,KAAM,SACN,cAAe,IACf,OAAQ,IACR,SAAUH,CACd,CAAC,EAEKI,EAAO,MAAM,MAAM,sCAAwCD,CAAgB,EAAE,KAAKE,GAAYA,EAAS,KAAK,CAAC,EAC9G,MAAMC,IACH,QAAQ,IAAIA,CAAG,EACfJ,GAAeH,EAAI,QAAQ,GAAI,CAAE,QAAS,qDAAsD,CAAC,EAC1F,KACV,EAEL,GAAI,CAACK,EAAM,OAEX,GAAI,CAACA,EAAK,OAAO,QAAQ,OACrB,eAAQ,IAAIA,CAAI,EACTF,GAAeH,EAAI,QAAQ,GAAI,CAAE,QAAS,kBAAmB,CAAC,EAGzE,IAAMQ,EAAU,MAAM,MAAM,4JAA4JH,EAAK,MAAM,OAAO,GAAG,iCAAiC,EACzO,KAAKI,GAAOA,EAAI,KAAK,CAAC,EACtB,KAAKJ,GAAQA,EAAK,MAAM,MAAM,EAAE,EAChC,MAAME,IACH,QAAQ,IAAIA,CAAG,EACfJ,GAAeH,EAAI,QAAQ,GAAI,CAAE,QAAS,qDAAsD,CAAC,EAC1F,KACV,EAEL,GAAI,CAACQ,EAAS,OAEd,IAAME,EAAgBF,EAAQ,UAExBG,EAAYD,GAAiB,CAC/B,IAAKA,EAAc,OAAO,QAAQ,YAAa,SAAS,EACxD,OAAQA,EAAc,OAAS,IAC/B,MAAOA,EAAc,MAAQ,GACjC,EAEAP,GAAeH,EAAI,QAAQ,GAAI,CAC3B,OAAQ,CACJ,CACI,KAAM,OACN,MAAOK,EAAK,MAAM,OAAO,GAAG,MAC5B,IAAK,2CAA2CA,EAAK,MAAM,OAAO,GAAG,SACrE,MAAO,WACP,YAAaA,EAAK,MAAM,OAAO,GAAG,QAAQ,QAAQ,uBAAwB,EAAE,EAAE,QAAQ,aAAc,GAAI,EAAI,MAC5G,MAAOM,EACP,OAAQ,CACJ,KAAM,8BACV,CACJ,CACJ,CACJ,CAAC,CACL,CACJ,CACJ,CACJ,CAAC,IC0HD,SAASC,GAAaC,EAAqBC,EAAiBC,EAAkB,CAC1E,MAAM,sCAAsCA,EAAQ,OAAO,MAAMA,EAAQ,OAAO,qBAAqB,EAAE,KAAKC,GAAYA,EAAS,YAAY,CAAC,EAAE,KAAKC,GAAU,CAC3J,IAAMC,EAAU,CACZ,YAAa,EACb,MAAO,EACP,QAASC,GAAS,MAAM,QACxB,OAAQC,GAAgBC,GAAaP,CAAO,CAAC,EAC7C,QAASK,GAAS,MAAM,QACxB,OAAQA,GAAS,MAAM,OACvB,UAAWA,GAAS,MAAM,UAC1B,MAAON,EACP,QAASC,EACT,cAAe,GACf,KAAMG,EACN,UAAW,SACf,EACAK,GAAO,cAAcJ,CAAO,CAChC,CAAC,CACL,CAEA,SAASK,GAAeT,EAAiBD,EAAqB,CAC1D,IAAMK,EAAU,CACZ,YAAa,EACb,MAAO,EACP,QAASC,GAAS,MAAM,QACxB,OAAQC,GAAgBC,GAAaP,CAAO,CAAC,EAC7C,QAASK,GAAS,MAAM,QACxB,OAAQA,GAAS,MAAM,OACvB,UAAWA,GAAS,MAAM,UAC1B,MAAON,EACP,QAASC,EACT,cAAe,GACf,KAAM,KACN,UAAW,SACf,EACAQ,GAAO,cAAcJ,CAAO,CAChC,CAEA,SAASM,GAAaT,EAAkBU,EAAkB,CACtD,IAAMC,EAAcC,EAAU,eAAe,EAE7C,OADIZ,EAAQ,OAAO,KAAOW,EAAY,IAClCX,EAAQ,OAAO,KAAOI,GAAS,MAAM,WAAmB,GACxDS,GAAU,iBAAiBH,CAAO,GAAKV,EAAQ,kBAAoB,CAACa,GAAU,0BAA0Bb,EAAQ,QAAQ,EAAU,GAE/HA,EAAQ,SAAS,KAAKc,GAAKA,EAAE,KAAOH,EAAY,EAAE,CAC7D,CAEA,SAASN,GAAgBN,EAAiB,CACtC,OAAIA,EAAQ,QAAU,IAAY,IAC9BA,EAAQ,QAAU,IAAY,IAC9BA,EAAQ,QAAU,IAAY,IAC3B,GACX,CAEA,SAASO,GAAaP,EAAiB,CACnC,OAAOA,EAAQ,QAAQ,IAAI,OAAO,UAAW,GAAG,EAAG,EAAE,CACzD,CA/RA,IAyEMc,GACAE,GAEAX,GAwCAG,GAECS,GAtHPC,GAAAC,EAAA,kBAAAC,IAMAC,IACAC,KACAC,IACAC,KACAC,IACAC,IACAC,IA6DMb,GAAYc,EAAgB,2BAA2B,EACvDZ,GAAQ,IAAIa,GAAO,WAAW,EAE9BxB,GAAWyB,EAAqB,CAClC,WAAY,CACR,OACA,YAAa,4BACb,QAAS,EACb,EACA,UAAW,CACP,OACA,YAAa,qBACb,QAAS,SACb,EACA,iBAAkB,CACd,OACA,YAAa,wBACb,QAAS,SACb,EACA,UAAW,CACP,OACA,YAAa,6CACb,QAAS,SACb,EACA,QAAS,CACL,OACA,YAAa,wBACb,QAAS,CACb,EACA,QAAS,CACL,OACA,YAAa,gBACb,QAAS,EACT,QAASC,GAAU,EAAG,EAAG,EAAG,CAChC,EACA,OAAQ,CACJ,OACA,YAAa,SACb,QAAS,GACT,QAASA,GAAU,EAAG,EAAG,EAAG,CAChC,CACJ,CAAC,EAEKvB,GAAS,cAAc,cAAc,UAEpCS,GAAQe,EAAa,CACxB,KAAM,YACN,YAAa,sEACb,QAAS,CAACC,EAAK,KAAK,EACpB,KAAM,CAAC,KAAM,QAAQ,EACrB,SAAA5B,GACA,KAAM,CACF,YAAY,CAAE,KAAA6B,CAAK,EAAoB,CACnC,GAAIA,GAAM,SAAS,SAASrB,EAAU,eAAe,EAAE,EAAE,EAAG,CACxD,IAAMF,EAAUwB,EAAa,WAAWD,EAAK,UAAU,EACvDzB,GAAe,gBAAiB,GAAGE,EAAQ,wBAAwB,CACvE,CACJ,EACA,eAAe,CAAE,QAAAV,EAAS,WAAAmC,CAAW,EAA+C,CAEhF,GAAI,CACA,GAAIA,EAAY,OAChB,IAAMzB,EAAUwB,EAAa,WAAWlC,EAAQ,UAAU,EAC1D,GAAI,CAACS,GAAaT,EAASU,CAAO,EAAG,OAErC,IAAM0B,EAAYhC,GAAS,MAAM,UAAU,WAAW,IAAK,EAAE,EAAE,KAAK,EAC9DiC,EAAmBjC,GAAS,MAAM,iBAAiB,WAAW,IAAK,EAAE,EAAE,KAAK,EAC9EkC,EAAWtC,EAAQ,QACnBF,EAAc,GAElB,GAAIY,EAAQ,SAAU,CAClB,IAAM6B,EAAQC,GAAW,SAAS9B,EAAQ,QAAQ,EAClDZ,EAAc,GAAGE,EAAQ,OAAO,aAAauC,EAAM,UAAU7B,EAAQ,OACzE,CAGA,OAAQA,EAAQ,KAAM,CAClB,IAAK,GACDZ,EAAcE,EAAQ,OAAO,SAAS,KAAK,EAC3C,MACJ,IAAK,GACD,IAAMyC,EAAc/B,EAAQ,KAAK,KAAK,GAAKA,EAAQ,cAAc,IAAIgC,GAAKA,EAAE,QAAQ,EAAE,KAAK,IAAI,EAC/F5C,EAAc,GAAGE,EAAQ,OAAO,aAAayC,KAC7C,KACR,CAuCA,GArCIzC,EAAQ,qBACRF,GAAe,YAGfE,EAAQ,OAAO,OAAS,IACxBsC,GAAY,YACRtC,EAAQ,UAAY,KACpBsC,EAAW,0BAIftC,EAAQ,gBACRsC,GAAY,cACRtC,EAAQ,UAAY,KACpBsC,EAAW,mBAIJtC,EAAQ,YAAY,OAAO0C,GACtC,OAAOA,GAAG,cAAiB,UACxBA,GAAG,aAAa,WAAW,OAAO,CACzC,EAGO,QAAQC,GAAO,CAClBL,GAAY,YAAYK,EAAI,YAChC,CAAC,EAED3C,EAAQ,YAAY,OAAO4C,GAAKA,GAAK,CAACA,EAAE,cAAc,WAAW,OAAO,CAAC,EAAE,QAAQA,GAAK,CACpFN,GAAY,iBAAiBM,EAAE,YACnC,CAAC,EAGG5C,EAAQ,SAAS,OAAS,IAC1BsC,EAAWA,EAAS,QAAQ,oBAAqB,CAACO,EAAGC,IAAO,WAAWV,SAAiBxB,EAAU,QAAQkC,CAAE,GAAG,UAAY,4BAA4B,GAGvJ9C,EAAQ,cAAc,OAAS,EAC/B,QAAW+C,KAAU/C,EAAQ,cAAe,CACxC,IAAMgD,EAAOR,GAAW,SAAS9B,EAAQ,QAAQ,EAAE,MAAMqC,GACzD,GAAI,CAACC,EAAM,SACX,IAAMC,EAAYD,EAAK,aAAe,IAAIZ,IAC1CE,EAAWA,EAAS,QAAQ,MAAMS,KAAW,aAAaE,MAAcD,EAAK,kBAAkB,CACnG,CAIJ,IAAME,EAAeZ,EAAS,MAAM,IAAI,OAAO,mBAAoB,GAAG,CAAC,EACjEa,EAAiBb,EAAS,MAAM,IAAI,OAAO,YAAa,GAAG,CAAC,EAElE,GAAIY,EACA,QAAWE,KAAUF,EACjBZ,EAAWA,EAAS,QAAQ,IAAI,OAAO,GAAGc,IAAU,GAAG,EAAG,IAAIA,EAAO,MAAM,GAAG,EAAE,KAAK,EAI7F,GAAID,EACA,QAAWE,KAAUF,EAAgB,CACjC,IAAIG,EAAYD,EAAO,MAAM,IAAI,EAAE,GACnCC,EAAYA,EAAU,UAAU,EAAGA,EAAU,OAAS,CAAC,EACvDhB,EAAWA,EAAS,QAAQ,IAAI,OAAO,GAAGe,IAAU,GAAG,EAAG,cAAchB,MAAqBH,EAAa,WAAWoB,CAAS,EAAE,kBAAkB,CACtJ,CAGJzD,GAAaC,EAAawC,EAAUtC,CAAO,CAC/C,OAASuD,EAAP,CACExC,GAAM,MAAM,mCAAmCwC,GAAK,CACxD,CACJ,CACJ,CACJ,CAAC,ICrOD,IAgJOC,GAhJPC,GAAAC,EAAA,KAAAC,IAAAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACOnJ,GAAQ,CACf,CAACoJ,GAAG,MAAMA,GACV,CAACC,GAAG,MAAMA,GACV,CAACC,GAAG,MAAMA,GACV,CAACC,GAAG,MAAMA,GACV,CAACC,GAAG,MAAMA,GACV,CAACC,GAAG,MAAMA,GACV,CAACC,GAAG,MAAMA,GACV,CAACC,GAAG,MAAMA,GACV,CAACC,GAAG,MAAMA,GACV,CAACC,GAAG,MAAMA,GACV,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAI,MAAMA,GACX,CAACC,GAAK,MAAMA,GACZ,CAACC,GAAK,MAAMA,GACZ,CAACC,GAAK,MAAMA,GACZ,CAACC,GAAK,MAAMA,GACZ,CAACC,GAAK,MAAMA,GACZ,CAACC,GAAK,MAAMA,GACZ,CAACC,GAAK,MAAMA,GACZ,CAACC,GAAK,MAAMA,GACZ,CAACC,GAAK,MAAMA,GACZ,CAACC,GAAK,MAAMA,GACZ,CAACC,GAAK,MAAMA,GACZ,CAACC,GAAK,MAAMA,GACZ,CAACC,GAAK,MAAMA,GACZ,CAACC,GAAK,MAAMA,GACZ,CAACC,GAAK,MAAMA,GACZ,CAACC,GAAK,MAAMA,GACZ,CAACC,GAAK,MAAMA,GACZ,CAACC,GAAK,MAAMA,GACZ,CAACC,GAAK,MAAMA,GACZ,CAACC,GAAK,MAAMA,GACZ,CAACC,GAAK,MAAMA,GACZ,CAACC,GAAK,MAAMA,GACZ,CAACC,GAAK,MAAMA,GACZ,CAACC,GAAK,MAAMA,GACZ,CAACC,GAAK,MAAMA,GACZ,CAACC,GAAK,MAAMA,GACZ,CAACC,GAAK,MAAMA,GACZ,CAACC,GAAK,MAAMA,GACZ,CAACC,GAAK,MAAMA,GACZ,CAACC,GAAK,MAAMA,GACZ,CAACC,GAAK,MAAMA,GACZ,CAACC,GAAK,MAAMA,GACZ,CAACC,GAAK,MAAMA,GACZ,CAACC,GAAK,MAAMA,GACZ,CAACC,GAAK,MAAMA,GACZ,CAACC,GAAK,MAAMA,GACZ,CAACC,GAAK,MAAMA,GACZ,CAACC,GAAK,MAAMA,GACZ,CAACC,GAAK,MAAMA,GACZ,CAACC,GAAK,MAAMA,GACZ,CAACC,GAAK,MAAMA,GACZ,CAACC,GAAK,MAAMA,GACZ,CAACC,GAAK,MAAMA,GACZ,CAACC,GAAK,MAAMA,EACZ,ICjSA,IAAA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",
"names": ["VencordFragment", "VencordCreateElement", "init_react", "__esmMin", "args", "Logger", "init_Logger", "__esmMin", "init_react", "name", "color", "title", "level", "levelColor", "args", "customFmt", "fmt", "styleStr", "Margins", "init_margins", "__esmMin", "init_react", "dir", "size", "cl", "makeLazy", "factory", "attempts", "tries", "cache", "proxyLazy", "isChild", "isSameTick", "proxyDummy", "kCACHE", "kGET", "handler", "target", "p", "receiver", "unconfigurable", "init_lazy", "__esmMin", "init_react", "method", "args", "v", "keys", "key", "descriptor", "LazyComponent", "factory", "attempts", "get", "makeLazy", "props", "Component", "NoopComponent", "VencordCreateElement", "init_lazyReact", "__esmMin", "init_react", "init_lazy", "canonicalizeMatch", "match", "canonSource", "canonicalizeReplace", "replace", "pluginName", "self", "args", "canonicalizeDescriptor", "descriptor", "canonicalize", "original", "canonicalizeReplacement", "replacement", "plugin", "descriptors", "init_patches", "__esmMin", "init_react", "noopTracer", "traceFunction", "init_Tracer", "__esmMin", "init_react", "init_Logger", "name", "f", "mapper", "_initWebpack", "instance", "cache", "r", "wreq", "handleModuleNotFound", "method", "filter", "err", "logger", "findAll", "ret", "key", "mod", "findModuleFactory", "code", "id", "findModuleId", "proxyLazyWebpack", "factory", "attempts", "proxyLazy", "LazyComponentWebpack", "LazyComponent", "findLazy", "find", "findByProps", "props", "res", "filters", "findByPropsLazy", "findByCode", "findByCodeLazy", "findStore", "name", "findStoreLazy", "findComponentByCode", "findComponentLazy", "findComponentByCodeLazy", "findExportedComponentLazy", "extractAndLoadChunks", "matcher", "module", "match", "canonicalizeMatch", "extractAndLoadChunksLazy", "waitFor", "callback", "isIndirect", "existing", "subscriptions", "addListener", "listeners", "removeListener", "search", "results", "factories", "outer", "str", "extract", "_resolveReady", "onceReady", "findBulk", "lazyWebpackSearchHistory", "init_webpack", "__esmMin", "init_react", "init_lazy", "init_lazyReact", "init_Logger", "init_patches", "init_Tracer", "Logger", "m", "p", "s", "c", "traceFunction", "isWaitFor", "found", "filterFns", "length", "j", "ModalImageClasses", "ButtonWrapperClasses", "init_classes", "__esmMin", "init_react", "init_webpack", "findLazy", "m", "findByPropsLazy", "waitForComponent", "name", "filter", "myValue", "lazyComponent", "LazyComponent", "waitFor", "v", "waitForStore", "cb", "filters", "init_internal", "__esmMin", "init_react", "init_webpack", "Forms", "Card", "Button", "Switch", "Tooltip", "TextInput", "TextArea", "Text", "Select", "SearchableSelect", "Slider", "ButtonLooks", "Popout", "Dialog", "TabBar", "Paginator", "ScrollerThin", "Clickable", "Avatar", "useToken", "MaskedLink", "Timestamp", "Flex", "OAuth2AuthorizeModal", "init_components", "__esmMin", "init_react", "init_webpack", "init_internal", "waitForComponent", "m", "filters", "findByPropsLazy", "waitFor", "Menu", "ContextMenuApi", "init_menu", "__esmMin", "init_react", "init_webpack", "waitFor", "m", "findByPropsLazy", "React", "useState", "useEffect", "useMemo", "useRef", "useReducer", "useCallback", "ReactDOM", "init_react", "__esmMin", "init_webpack", "findByPropsLazy", "waitFor", "m", "TextAndImagesSettingsStores", "StatusSettingsStores", "UserSettingsActionCreators", "init_settingsStores", "__esmMin", "init_react", "init_webpack", "findByPropsLazy", "Flux", "DraftType", "MessageStore", "PrivateChannelsStore", "PermissionStore", "GuildChannelStore", "ReadStateStore", "PresenceStore", "PoggerModeSettingsStore", "GuildStore", "UserStore", "UserProfileStore", "SelectedChannelStore", "SelectedGuildStore", "ChannelStore", "GuildMemberStore", "RelationshipStore", "EmojiStore", "WindowStore", "DraftStore", "useStateFromStores", "init_stores", "__esmMin", "init_react", "init_webpack", "init_internal", "findByPropsLazy", "waitForStore", "s", "m", "components_d_exports", "init_components_d", "__esmMin", "init_react", "menu_d_exports", "init_menu_d", "__esmMin", "init_react", "utils_d_exports", "init_utils_d", "__esmMin", "init_react", "showToast", "message", "type", "ToastType", "Toasts", "FluxDispatcher", "ComponentDispatch", "RestAPI", "moment", "hljs", "lodash", "i18n", "SnowflakeUtils", "Parser", "Alerts", "ToastPosition", "UserUtils", "UploadHandler", "ApplicationAssetUtils", "Clipboard", "NavigationRouter", "SettingsRouter", "PermissionsBits", "zustandCreate", "persistFilter", "zustandPersist", "MessageActions", "UserProfileActions", "InviteActions", "init_utils", "__esmMin", "init_react", "init_webpack", "waitFor", "m", "cb", "_resolveReady", "findByPropsLazy", "findLazy", "findByCodeLazy", "filters", "common_exports", "__export", "Alerts", "ApplicationAssetUtils", "Avatar", "Button", "ButtonLooks", "ButtonWrapperClasses", "Card", "ChannelStore", "Clickable", "Clipboard", "ComponentDispatch", "components_d_exports", "ContextMenuApi", "Dialog", "DraftStore", "DraftType", "EmojiStore", "Flex", "Flux", "FluxDispatcher", "Forms", "GuildChannelStore", "GuildMemberStore", "GuildStore", "InviteActions", "MaskedLink", "Menu", "menu_d_exports", "MessageActions", "MessageStore", "ModalImageClasses", "NavigationRouter", "OAuth2AuthorizeModal", "Paginator", "Parser", "PermissionStore", "PermissionsBits", "PoggerModeSettingsStore", "Popout", "PresenceStore", "PrivateChannelsStore", "React", "ReactDOM", "ReadStateStore", "RelationshipStore", "RestAPI", "ScrollerThin", "SearchableSelect", "Select", "SelectedChannelStore", "SelectedGuildStore", "SettingsRouter", "Slider", "SnowflakeUtils", "StatusSettingsStores", "Switch", "TabBar", "Text", "TextAndImagesSettingsStores", "TextArea", "TextInput", "Timestamp", "Toasts", "Tooltip", "UploadHandler", "UserProfileActions", "UserProfileStore", "UserSettingsActionCreators", "UserStore", "UserUtils", "utils_d_exports", "WindowStore", "hljs", "i18n", "lodash", "moment", "showToast", "useCallback", "useEffect", "useMemo", "useReducer", "useRef", "useState", "useStateFromStores", "useToken", "zustandCreate", "zustandPersist", "init_common", "__esmMin", "init_react", "init_classes", "init_components", "init_menu", "init_settingsStores", "init_stores", "init_components_d", "init_menu_d", "init_utils_d", "init_utils", "git_hash_default", "init_git_hash", "__esmMin", "init_react", "git_remote_default", "init_git_remote", "__esmMin", "init_react", "WEBPACK_CHUNK", "REACT_GLOBAL", "VENCORD_USER_AGENT", "SUPPORT_CHANNEL_ID", "Devs", "DevsById", "init_constants", "__esmMin", "init_react", "init_git_hash", "init_git_remote", "git_hash_default", "git_remote_default", "d", "_", "v", "mergeDefaults", "obj", "defaults", "key", "v", "classes", "sleep", "ms", "r", "copyWithToast", "text", "toastMessage", "Clipboard", "Toasts", "isObject", "isObjectEmpty", "k", "parseUrl", "urlString", "identity", "value", "checkIntersecting", "isMobile", "isPluginDev", "init_misc", "__esmMin", "init_react", "init_common", "init_constants", "el", "elementBox", "documentHeight", "id", "DevsById", "useAwaiter", "factory", "providedOpts", "opts", "state", "setState", "useState", "useEffect", "isAlive", "value", "error", "useForceUpdater", "withDep", "r", "useReducer", "x", "useTimer", "interval", "deps", "time", "setTime", "start", "useMemo", "intervalId", "NoopComponent", "useIntersection", "init_react", "__esmMin", "init_common", "init_misc", "init_lazyReact", "intersectOnly", "observerRef", "React", "isIntersecting", "setIntersecting", "element", "checkIntersecting", "entries", "entry", "ErrorCard", "props", "VencordCreateElement", "classes", "init_ErrorCard", "__esmMin", "init_react", "init_", "init_misc", "color", "logger", "NO_ERROR", "ErrorBoundary", "ErrorBoundary_default", "init_ErrorBoundary", "__esmMin", "init_react", "init_Logger", "init_margins", "init_common", "init_ErrorCard", "Logger", "LazyComponent", "React", "error", "stack", "message", "eolIdx", "errorInfo", "VencordCreateElement", "msg", "ErrorCard", "Margins", "Component", "errorBoundaryProps", "props", "Heart", "VencordCreateElement", "init_Heart", "__esmMin", "init_react", "DonateButton", "props", "VencordCreateElement", "Button", "Heart", "init_DonateButton", "__esmMin", "init_react", "init_common", "init_Heart", "Flex", "props", "VencordCreateElement", "init_Flex", "__esmMin", "init_react", "openModalLazy", "render", "options", "ModalAPI", "openModal", "contextKey", "closeModal", "modalKey", "closeAllModals", "ModalSize", "Modals", "ImageModal", "ModalRoot", "ModalHeader", "ModalContent", "ModalFooter", "ModalCloseButton", "init_modal", "__esmMin", "init_react", "init_webpack", "findByPropsLazy", "findExportedComponentLazy", "LazyComponent", "definePlugin", "p", "init_types", "__esmMin", "init_react", "loadBadges", "noCache", "DonorBadges", "init", "r", "CONTRIBUTOR_BADGE", "ContributorBadge", "badges_default", "init_badges", "__esmMin", "init_react", "init_Badges", "init_DonateButton", "init_ErrorBoundary", "init_Flex", "init_Heart", "init_constants", "init_margins", "init_misc", "init_modal", "init_types", "init_common", "user", "isPluginDev", "definePlugin", "Devs", "Toasts", "ErrorBoundary_default", "badge", "Component", "VencordCreateElement", "userId", "modalKey", "openModal", "props", "closeModal", "Modals", "Flex", "Forms", "Heart", "Margins", "DonateButton", "commands_default", "init_commands", "__esmMin", "init_react", "init_constants", "init_types", "definePlugin", "Devs", "_", "cmd", "args", "ctx", "contextMenu_default", "init_contextMenu", "__esmMin", "init_react", "init_constants", "init_types", "definePlugin", "Devs", "memberListDecorators_default", "init_memberListDecorators", "__esmMin", "init_react", "init_constants", "init_types", "definePlugin", "Devs", "messageAccessories_default", "init_messageAccessories", "__esmMin", "init_react", "init_constants", "init_types", "definePlugin", "Devs", "messageDecorations_default", "init_messageDecorations", "__esmMin", "init_react", "init_constants", "init_types", "definePlugin", "Devs", "messageEvents_default", "init_messageEvents", "__esmMin", "init_react", "init_constants", "init_types", "definePlugin", "Devs", "_", "rest1", "rest2", "parsedMessage", "channel", "replyOptions", "extra", "m", "message", "event", "messagePopover_default", "init_messagePopover", "__esmMin", "init_react", "init_constants", "init_types", "definePlugin", "Devs", "m", "makeElement", "msg", "notices_default", "init_notices", "__esmMin", "init_react", "init_constants", "init_types", "definePlugin", "Devs", "serverList_default", "init_serverList", "__esmMin", "init_react", "init_constants", "init_types", "definePlugin", "Devs", "noTrack_default", "init_noTrack", "__esmMin", "init_react", "init_constants", "init_types", "definePlugin", "Devs", "ContextMenu_exports", "__export", "_patchContextMenu", "addContextMenuPatch", "addGlobalContextMenuPatch", "findGroupChildrenByChildId", "globalPatches", "navPatches", "removeContextMenuPatch", "removeGlobalContextMenuPatch", "navId", "patch", "id", "contextMenuPatches", "results", "children", "_itemsArray", "child", "nextChildren", "found", "props", "callback", "patchedMenus", "err", "ContextMenuLogger", "init_ContextMenu", "__esmMin", "init_react", "init_Logger", "Logger", "debounce", "func", "delay", "timeout", "args", "init_debounce", "__esmMin", "init_react", "localStorage", "init_localStorage", "__esmMin", "init_react", "Queue", "init_Queue", "__esmMin", "init_react", "maxSize", "func", "NotificationComponent_default", "init_NotificationComponent", "__esmMin", "init_react", "init_", "init_Settings", "init_ErrorBoundary", "init_misc", "init_common", "ErrorBoundary_default", "title", "body", "richBody", "color", "icon", "onClick", "onClose", "image", "permanent", "className", "dismissOnClick", "timeout", "position", "useSettings", "hasFocus", "useStateFromStores", "WindowStore", "isHover", "setIsHover", "useState", "elapsed", "setElapsed", "start", "useMemo", "useEffect", "intervalId", "timeoutProgress", "VencordCreateElement", "classes", "e", "props", "DataStore_exports", "__export", "clear", "createStore", "del", "delMany", "entries", "get", "getMany", "keys", "promisifyRequest", "set", "setMany", "update", "values", "request", "resolve", "reject", "dbName", "storeName", "dbp", "txMode", "callback", "db", "defaultGetStore", "defaultGetStoreFunc", "key", "customStore", "store", "value", "entry", "updater", "err", "eachCursor", "items", "cursor", "i", "init_DataStore", "__esmMin", "init_react", "Styles_exports", "__export", "classNameFactory", "classNameToSelector", "compileStyle", "disableStyle", "enableStyle", "isStyleEnabled", "requireStyle", "setStyleClassNames", "styleMap", "toggleStyle", "name", "style", "init_Styles", "__esmMin", "init_react", "classNames", "recompile", "match", "className", "prefix", "n", "args", "arg", "value", "nanoid", "init_index_browser", "__esmMin", "init_react", "size", "id", "byte", "persistNotification", "notification", "limit", "Settings", "update", "KEY", "old", "log", "onClick", "onClose", "richBody", "permanent", "noPersist", "dismissOnClick", "pureNotification", "nanoid", "signals", "x", "deleteNotification", "timestamp", "getLog", "index", "set", "useLogs", "signal", "setSignal", "useReducer", "useEffect", "_", "pending", "useAwaiter", "NotificationEntry", "data", "removing", "setRemoving", "useState", "ref", "React", "div", "setHeight", "VencordCreateElement", "cl", "NotificationComponent_default", "Timestamp", "moment", "NotificationLog", "Forms", "n", "LogModal", "modalProps", "close", "ModalRoot", "ModalHeader", "Text", "ModalCloseButton", "ModalContent", "ModalFooter", "Button", "Alerts", "openNotificationLogModal", "key", "openModal", "closeModal", "init_notificationLog", "__esmMin", "init_react", "init_DataStore", "init_Settings", "init_Styles", "init_modal", "init_common", "init_index_browser", "init_NotificationComponent", "get", "classNameFactory", "getRoot", "reactRoot", "container", "ReactDOM", "_showNotification", "notification", "id", "root", "resolve", "VencordCreateElement", "NotificationComponent_default", "shouldBeNative", "useNative", "Settings", "requestPermission", "showNotification", "data", "persistNotification", "title", "body", "icon", "image", "onClick", "onClose", "n", "NotificationQueue", "init_Notifications", "__esmMin", "init_react", "init_Settings", "init_Queue", "init_common", "init_NotificationComponent", "init_notificationLog", "Queue", "Notifications_exports", "__export", "requestPermission", "showNotification", "init_Notifications", "__esmMin", "init_react", "deflateSync", "data", "opts", "dopt", "inflateSync", "out", "inflt", "u8", "u16", "u32", "fleb", "fdeb", "clim", "freb", "_a", "fl", "revfl", "_b", "fd", "revfd", "rev", "x", "i", "hMap", "flt", "fdt", "flm", "flrm", "fdm", "fdrm", "max", "bits", "bits16", "shft", "slc", "ec", "err", "wbits", "wbits16", "hTree", "ln", "lc", "clen", "wfblk", "wblk", "deo", "et", "dflt", "td", "tds", "init_browser", "__esmMin", "init_react", "eb", "start", "b", "r", "j", "cd", "mb", "s", "l", "le", "co", "rvb", "sv", "r_1", "v", "m", "a", "d", "p", "o", "e", "n", "ind", "msg", "nt", "dat", "buf", "st", "sl", "noBuf", "noSt", "cbuf", "bl", "nbuf", "final", "pos", "bt", "lm", "dm", "lbt", "dbt", "tbts", "type", "hLit", "hcLen", "tl", "ldt", "clt", "clb", "clbmsk", "clm", "c", "lt", "dt", "t", "lms", "dms", "lpos", "sym", "add", "dsym", "end", "t2", "i0", "i1", "i2", "maxSym", "tr", "mbt", "lft", "cst", "i2_1", "i2_2", "i2_3", "cl", "cli", "cln", "cls", "w", "cf", "syms", "lf", "df", "li", "bs", "dlt", "mlb", "ddt", "mdb", "_c", "lclt", "nlc", "_d", "lcdt", "ndc", "lcfreq", "_e", "lct", "mlcb", "nlcc", "flen", "ftlen", "dtlen", "ll", "dl", "llm", "lcts", "it", "clct", "len", "dst", "lvl", "plvl", "pre", "post", "lst", "opt", "msk_1", "prev", "head", "bs1_1", "bs2_1", "hsh", "lc_1", "wi", "hv", "imod", "pimod", "rem", "ch_1", "dif", "maxn", "maxd", "ml", "nl", "mmd", "md", "ti", "pti", "lin", "din", "getAuthorization", "secrets", "get", "origin", "cloudUrlOrigin", "update", "getUserId", "setAuthorization", "secret", "deauthorizeCloud", "authorizeCloud", "Settings", "oauthConfiguration", "getCloudUrl", "clientId", "redirectUri", "showNotification", "openModal", "props", "VencordCreateElement", "OAuth2AuthorizeModal", "location", "res", "cloudLogger", "e", "getCloudAuth", "init_cloud", "__esmMin", "init_react", "init_DataStore", "init_Notifications", "init_Settings", "init_common", "init_Logger", "init_modal", "Logger", "id", "UserStore", "relaunch", "showItemInFolder", "path", "init_native", "__esmMin", "init_react", "saveFile", "file", "a", "chooseFile", "mimeTypes", "resolve", "input", "init_web", "__esmMin", "init_react", "importSettings", "data", "parsed", "err", "PlainSettings", "exportSettings", "minify", "settings", "quickCss", "downloadSettingsBackup", "filename", "backup", "saveFile", "uploadSettingsBackup", "showToast", "file", "chooseFile", "reader", "toastSuccess", "Logger", "toastFailure", "putCloudSettings", "manual", "res", "getCloudUrl", "getCloudAuth", "deflateSync", "cloudSettingsLogger", "showNotification", "written", "e", "getCloudSettings", "shouldNotify", "force", "Settings", "localWritten", "inflateSync", "relaunch", "deleteCloudSettings", "toast", "init_settingsSync", "__esmMin", "init_react", "init_Notifications", "init_Settings", "init_common", "init_browser", "init_cloud", "init_Logger", "init_native", "init_web", "type", "message", "Toasts", "Settings_exports", "__export", "PlainSettings", "Settings", "addSettingsListener", "definePluginSettings", "migratePluginSettings", "useSettings", "makeProxy", "settings", "root", "path", "proxyCache", "target", "p", "v", "plugins_default", "plugin", "setting", "def", "o", "setPath", "subscription", "subscriptions", "localStorage", "saveSettingsOnFrequentAction", "paths", "forceUpdate", "React", "onUpdate", "value", "name", "oldNames", "plugins", "oldName", "logger", "checks", "definedSettings", "DefaultSettings", "init_Settings", "__esmMin", "init_react", "init_debounce", "init_localStorage", "init_Logger", "init_misc", "init_settingsSync", "init_types", "init_common", "init_plugins", "Logger", "mergeDefaults", "err", "debounce", "putCloudSettings", "updater_exports", "__export", "UpdateLogger", "changes", "checkForUpdates", "getRepo", "isNewer", "isOutdated", "maybePromptToUpdate", "update", "updateError", "Unwrap", "p", "res", "c", "git_hash_default", "confirmMessage", "checkForDev", "wantsUpdate", "relaunch", "err", "init_updater", "__esmMin", "init_react", "init_git_hash", "init_Logger", "init_native", "Logger", "handleComponentFailed", "maybePromptToUpdate", "init_handleComponentFailed", "__esmMin", "init_react", "init_updater", "onlyOnce", "f", "called", "result", "init_onlyOnce", "__esmMin", "init_react", "SettingsTab", "title", "children", "VencordCreateElement", "Forms", "Text", "Margins", "wrapTab", "component", "tab", "ErrorBoundary_default", "onError", "init_shared", "__esmMin", "init_react", "init_", "init_ErrorBoundary", "init_handleComponentFailed", "init_margins", "init_onlyOnce", "init_common", "onlyOnce", "handleComponentFailed", "VencordTab_exports", "__export", "VencordTab_default", "VencordSettings", "settingsDir", "settingsDirPending", "useAwaiter", "settings", "useSettings", "donateImage", "React", "DEFAULT_DONATE_IMAGE", "SHIGGY_DONATE_IMAGE", "isWindows", "isMac", "needsVibrancySettings", "Switches", "VencordCreateElement", "SettingsTab", "DonateCard", "Forms", "Card", "cl", "Button", "relaunch", "showItemInFolder", "Margins", "s", "Switch", "v", "VencordFragment", "Select", "identity", "NotificationSection", "ErrorCard", "Slider", "openNotificationLogModal", "image", "DonateButton", "init_VencordTab", "__esmMin", "init_react", "init_notificationLog", "init_Settings", "init_Styles", "init_DonateButton", "init_ErrorCard", "init_margins", "init_misc", "init_native", "init_common", "init_shared", "classNameFactory", "wrapTab", "Notices_exports", "__export", "currentNotice", "nextNotice", "noticesQueue", "popNotice", "showNotice", "NoticesModule", "message", "buttonText", "onOkClick", "init_Notices", "__esmMin", "init_react", "init_webpack", "waitFor", "m", "Icon", "height", "width", "className", "children", "viewBox", "svgProps", "VencordCreateElement", "classes", "LinkIcon", "CopyIcon", "props", "OpenExternalIcon", "ImageIcon", "InfoIcon", "OwnerCrownIcon", "i18n", "ScreenshareIcon", "ImageVisible", "ImageInvisible", "Microphone", "CogWheel", "ReplyIcon", "DeleteIcon", "PlusIcon", "NoEntrySignIcon", "init_Icons", "__esmMin", "init_react", "init_", "init_misc", "init_common", "getUnitStr", "unit", "isOne", "short", "formatDuration", "time", "dur", "moment", "unitsAmounts", "units", "amountsToBeRemoved", "outer", "i", "v", "daysAmountIndex", "daysAmount", "daysMod", "res", "amount", "humanFriendlyJoin", "elements", "mapper", "s", "length", "makeCodeblock", "text", "language", "chars", "wordsFromCamel", "wordsFromSnake", "wordsFromKebab", "wordsFromPascal", "wordsFromTitle", "wordsToCamel", "wordsToSnake", "wordsToKebab", "wordsToPascal", "wordsToTitle", "init_text", "__esmMin", "init_react", "init_common", "w", "words", "generateId", "SnowflakeUtils", "sendBotMessage", "channelId", "message", "botMessage", "MessageCreator", "MessageActions", "mergeDefaults", "findOption", "args", "name", "fallbackValue", "a", "init_commandHelpers", "__esmMin", "init_react", "init_misc", "init_webpack", "init_common", "findByPropsLazy", "ApplicationCommandOptionType", "ApplicationCommandInputType", "ApplicationCommandType", "init_types", "__esmMin", "init_react", "Commands_exports", "__export", "ApplicationCommandInputType", "ApplicationCommandOptionType", "ApplicationCommandType", "BUILT_IN", "OptionalMessageOption", "RequiredMessageOption", "_handleCommand", "_init", "commands", "findOption", "generateId", "prepareOption", "registerCommand", "sendBotMessage", "unregisterCommand", "opt", "i", "opts", "OptPlaceholder", "ReqPlaceholder", "x", "registerSubCommands", "cmd", "plugin", "subCmd", "command", "c", "name", "idx", "init_Commands", "__esmMin", "init_react", "init_text", "init_commandHelpers", "init_types", "cmds", "args", "ctx", "handleError", "err", "msg", "reason", "makeCodeblock", "res", "Badge", "text", "color", "VencordCreateElement", "init_Badge", "__esmMin", "init_react", "SettingBooleanComponent", "option", "pluginSettings", "definedSettings", "id", "onChange", "onError", "def", "state", "setState", "React", "error", "setError", "handleChange", "newValue", "isValid", "VencordCreateElement", "Forms", "Switch", "wordsToTitle", "wordsFromCamel", "init_SettingBooleanComponent", "__esmMin", "init_react", "init_text", "init_common", "SettingCustomComponent", "option", "onChange", "onError", "init_SettingCustomComponent", "__esmMin", "init_react", "SettingNumericComponent", "option", "pluginSettings", "definedSettings", "id", "onChange", "onError", "serialize", "value", "state", "setState", "React", "error", "setError", "handleChange", "newValue", "isValid", "MAX_SAFE_NUMBER", "VencordCreateElement", "Forms", "TextInput", "init_SettingNumericComponent", "__esmMin", "init_react", "init_types", "init_common", "SettingSelectComponent", "option", "pluginSettings", "definedSettings", "onChange", "onError", "id", "def", "o", "state", "setState", "React", "error", "setError", "handleChange", "newValue", "isValid", "VencordCreateElement", "Forms", "Select", "init_SettingSelectComponent", "__esmMin", "init_react", "init_common", "makeRange", "start", "end", "step", "ranges", "value", "SettingSliderComponent", "option", "pluginSettings", "definedSettings", "id", "onChange", "onError", "def", "error", "setError", "React", "handleChange", "newValue", "isValid", "VencordCreateElement", "Forms", "Slider", "v", "init_SettingSliderComponent", "__esmMin", "init_react", "init_common", "SettingTextComponent", "option", "pluginSettings", "definedSettings", "id", "onChange", "onError", "state", "setState", "React", "error", "setError", "handleChange", "newValue", "isValid", "VencordCreateElement", "Forms", "TextInput", "init_SettingTextComponent", "__esmMin", "init_react", "init_common", "init_components", "__esmMin", "init_react", "init_Badge", "init_SettingBooleanComponent", "init_SettingCustomComponent", "init_SettingNumericComponent", "init_SettingSelectComponent", "init_SettingSliderComponent", "init_SettingTextComponent", "openInviteModal", "code", "invite", "InviteActions", "FluxDispatcher", "r", "onClose", "onAccept", "inviteAccepted", "getCurrentChannel", "ChannelStore", "SelectedChannelStore", "getCurrentGuild", "GuildStore", "openPrivateChannel", "userId", "PrivateChannelsStore", "getTheme", "UserSettingsActionCreators", "insertTextIntoChatInputBox", "text", "ComponentDispatch", "sendMessage", "channelId", "data", "waitForChannelReady", "extra", "messageData", "MessageActions", "openImageModal", "url", "props", "openModal", "modalProps", "VencordCreateElement", "ModalRoot", "ModalImageClasses", "ImageModal", "MaskedLink", "openUserProfile", "id", "UserUtils", "guildId", "SelectedGuildStore", "UserProfileActions", "fetchUserProfile", "options", "cached", "UserProfileStore", "body", "RestAPI", "getUniqueUsername", "user", "Theme", "init_discord", "__esmMin", "init_react", "init_common", "init_modal", "openContributorModal", "user", "openModal", "modalProps", "VencordCreateElement", "ModalRoot", "ErrorBoundary_default", "ModalContent", "cl", "ContributorModal", "GithubIcon", "src", "getTheme", "GithubIconLight", "GithubIconDark", "WebsiteIcon", "WebsiteIconLight", "WebsiteIconDark", "useSettings", "profile", "useStateFromStores", "UserProfileStore", "useEffect", "fetchUserProfile", "githubName", "a", "website", "plugins", "useMemo", "allPlugins", "plugins_default", "DevsById", "p", "b", "VencordFragment", "Forms", "MaskedLink", "PluginCard", "showToast", "init_ContributorModal", "__esmMin", "init_react", "init_", "init_Settings", "init_Styles", "init_ErrorBoundary", "init_constants", "init_discord", "init_modal", "init_common", "init_plugins", "init_PluginSettings", "classNameFactory", "makeDummyUser", "user", "newUser", "UserRecord", "generateId", "FluxDispatcher", "PluginModal", "plugin", "onRestartNeeded", "onClose", "transitionState", "authors", "setAuthors", "React", "pluginSettings", "useSettings", "tempSettings", "setTempSettings", "errors", "setErrors", "saveError", "setSaveError", "canSubmit", "e", "hasSettings", "isObjectEmpty", "author", "UserUtils", "a", "saveAndClose", "result", "restartNeeded", "key", "value", "option", "renderSettings", "VencordCreateElement", "Forms", "options", "setting", "onChange", "newValue", "s", "onError", "hasError", "Component", "Components", "Flex", "renderMoreUsers", "_label", "count", "sliceCount", "sliceStart", "sliceEnd", "Tooltip", "u", "onMouseEnter", "onMouseLeave", "AvatarStyles", "ModalRoot", "ModalHeader", "Text", "ModalCloseButton", "ModalContent", "UserSummaryItem", "Clickable", "openContributorModal", "classes", "Margins", "ErrorBoundary_default", "ModalFooter", "Button", "init_PluginModal", "__esmMin", "init_react", "init_Commands", "init_Settings", "init_ErrorBoundary", "init_Flex", "init_lazy", "init_margins", "init_misc", "init_modal", "init_types", "init_webpack", "init_common", "init_components", "init_ContributorModal", "findComponentByCodeLazy", "findByPropsLazy", "proxyLazy", "UserStore", "SettingTextComponent", "SettingNumericComponent", "SettingBooleanComponent", "SettingSelectComponent", "SettingSliderComponent", "SettingCustomComponent", "Switch", "checked", "onChange", "disabled", "VencordCreateElement", "classes", "SwitchClasses", "SWITCH_ON", "SWITCH_OFF", "VencordFragment", "e", "init_Switch", "__esmMin", "init_react", "init_", "init_misc", "init_webpack", "findByPropsLazy", "AddonCard", "disabled", "isNew", "name", "infoButton", "footer", "author", "enabled", "setEnabled", "description", "onMouseEnter", "onMouseLeave", "VencordCreateElement", "cl", "Text", "Badge", "Switch", "init_AddonCard", "__esmMin", "init_react", "init_", "init_Styles", "init_Badge", "init_Switch", "init_common", "classNameFactory", "ChangeList", "init_ChangeList", "__esmMin", "init_react", "item", "mapper", "plugins_exports", "__export", "PMLogger", "isPluginEnabled", "patches", "plugins", "startAllPlugins", "startDependenciesRecursive", "startPlugin", "stopPlugin", "p", "plugins_default", "settings", "restartNeeded", "failures", "dep", "Settings", "logger", "pluginsValues", "init_plugins", "__esmMin", "init_react", "init_Commands", "init_Settings", "init_Logger", "init_types", "init_common", "init_Tracer", "Logger", "d", "error", "name", "def", "checks", "patch", "traceFunction", "target", "commands", "flux", "e", "cmd", "registerCommand", "event", "FluxDispatcher", "unregisterCommand", "showErrorToast", "message", "Toasts", "ReloadRequiredCard", "required", "VencordCreateElement", "Card", "cl", "VencordFragment", "Forms", "Button", "PluginCard", "plugin", "disabled", "onRestartNeeded", "onMouseEnter", "onMouseLeave", "isNew", "settings", "Settings", "isEnabled", "openModal", "openModalLazy", "modalProps", "PluginModal", "toggleEnabled", "wasEnabled", "restartNeeded", "failures", "startDependenciesRecursive", "logger", "showNotice", "stopPlugin", "startPlugin", "msg", "AddonCard", "classes", "ButtonClasses", "isObjectEmpty", "CogWheel", "InfoIcon", "PluginSettings", "useSettings", "changes", "React", "ChangeList", "Alerts", "s", "i", "Parser", "depMap", "o", "plugins_default", "deps", "dep", "sortedPlugins", "a", "b", "searchValue", "setSearchValue", "onSearch", "query", "prev", "onStatusChange", "status", "pluginFilter", "enabled", "newPlugins", "v", "t", "useAwaiter", "get", "cachedPlugins", "now", "existingTimestamps", "sortedPluginNames", "p", "set", "lodash", "plugins", "requiredPlugins", "d", "tooltipText", "makeDependencyList", "Tooltip", "name", "Text", "SettingsTab", "Margins", "TextInput", "InputStyles", "Select", "init_PluginSettings", "__esmMin", "init_react", "init_", "init_DataStore", "init_Notices", "init_Settings", "init_Styles", "init_Icons", "init_PluginModal", "init_AddonCard", "init_shared", "init_ChangeList", "init_Logger", "init_margins", "init_misc", "init_modal", "init_webpack", "init_common", "init_plugins", "classNameFactory", "Logger", "findByPropsLazy", "PluginsTab_exports", "__export", "PluginsTab_default", "init_PluginsTab", "__esmMin", "init_react", "init_PluginSettings", "init_shared", "wrapTab", "PluginSettings", "Link", "props", "VencordCreateElement", "init_Link", "__esmMin", "init_react", "ThemesTab_exports", "__export", "ThemesTab_default", "Validator", "link", "res", "err", "pending", "useAwaiter", "contentType", "text", "VencordCreateElement", "Forms", "Validators", "themeLinks", "VencordFragment", "Margins", "Card", "ThemeCard", "theme", "enabled", "onChange", "onDelete", "AddonCard", "Flex", "Link", "e", "openInviteModal", "showToast", "ThemesTab", "settings", "useSettings", "fileInputRef", "useRef", "currentTab", "setCurrentTab", "useState", "themeText", "setThemeText", "userThemes", "setUserThemes", "themeDir", "themeDirPending", "useEffect", "refreshLocalThemes", "themes", "onLocalThemeChange", "fileName", "value", "f", "onFileUpload", "files", "uploads", "file", "name", "resolve", "reject", "reader", "renderLocalThemes", "Button", "showItemInFolder", "cl", "onBlur", "s", "renderOnlineThemes", "TextArea", "classes", "TextAreaProps", "SettingsTab", "TabBar", "InviteActions", "FileInput", "init_ThemesTab", "__esmMin", "init_react", "init_Settings", "init_Styles", "init_Flex", "init_Icons", "init_Link", "init_discord", "init_margins", "init_misc", "init_native", "init_webpack", "init_common", "init_AddonCard", "init_shared", "findByPropsLazy", "findLazy", "m", "classNameFactory", "wrapTab", "UpdaterTab_exports", "__export", "UpdaterTab_default", "withDispatcher", "dispatcher", "action", "e", "UpdateLogger", "code", "path", "cmd", "stderr", "err", "Alerts", "VencordCreateElement", "ErrorCard", "line", "Parser", "HashLink", "repo", "hash", "disabled", "Link", "Changes", "updates", "repoPending", "Card", "author", "message", "Updatable", "props", "setUpdates", "React", "changes", "isChecking", "setIsChecking", "isUpdating", "setIsUpdating", "isOutdated", "VencordFragment", "updateError", "Forms", "Margins", "Flex", "classes", "Button", "update", "r", "relaunch", "checkForUpdates", "Toasts", "Newer", "Updater", "settings", "useSettings", "useAwaiter", "getRepo", "commonProps", "SettingsTab", "Switch", "v", "git_hash_default", "isNewer", "init_UpdaterTab", "__esmMin", "init_react", "init_Settings", "init_ErrorCard", "init_Flex", "init_Link", "init_margins", "init_misc", "init_native", "init_updater", "init_common", "init_git_hash", "init_shared", "wrapTab", "CheckedTextInput", "initialValue", "onChange", "validate", "value", "setValue", "React", "error", "setError", "handleChange", "v", "res", "VencordCreateElement", "VencordFragment", "TextInput", "init_CheckedTextInput", "__esmMin", "init_react", "init_common", "CloudTab_exports", "__export", "CloudTab_default", "validateUrl", "url", "eraseAllData", "res", "getCloudUrl", "getCloudAuth", "cloudLogger", "showNotification", "Settings", "deauthorizeCloud", "SettingsSyncSection", "cloud", "useSettings", "sectionEnabled", "VencordCreateElement", "Forms", "Margins", "Switch", "v", "Button", "putCloudSettings", "Tooltip", "onMouseLeave", "onMouseEnter", "getCloudSettings", "deleteCloudSettings", "CloudTab", "settings", "SettingsTab", "Link", "authorizeCloud", "CheckedTextInput", "Alerts", "init_CloudTab", "__esmMin", "init_react", "init_Notifications", "init_Settings", "init_CheckedTextInput", "init_Link", "init_cloud", "init_margins", "init_settingsSync", "init_common", "init_shared", "wrapTab", "BackupAndRestoreTab_exports", "__export", "BackupAndRestoreTab_default", "BackupRestoreTab", "VencordCreateElement", "SettingsTab", "Card", "classes", "Flex", "Text", "Margins", "Button", "uploadSettingsBackup", "downloadSettingsBackup", "init_BackupAndRestoreTab", "__esmMin", "init_react", "init_Flex", "init_margins", "init_misc", "init_settingsSync", "init_common", "init_shared", "wrapTab", "settings_default", "init_settings", "__esmMin", "init_react", "init_ContextMenu", "init_Settings", "init_constants", "init_types", "init_common", "init_git_hash", "definePlugin", "Devs", "addContextMenuPatch", "children", "c", "it", "id", "SettingsRouter", "m", "component", "props", "Settings", "SectionTypes", "func", "b", "Component", "electronVersion", "chromiumVersion", "additionalInfo", "VencordCreateElement", "VencordFragment", "git_hash_default", "REMEMBER_DISMISS_KEY", "AllowedChannelIds", "supportHelper_default", "init_supportHelper", "__esmMin", "init_react", "init_api", "init_constants", "init_misc", "init_text", "init_types", "init_updater", "init_common", "init_git_hash", "init_plugins", "init_settings", "SUPPORT_CHANNEL_ID", "definePlugin", "Devs", "ctx", "RELEASE_CHANNEL", "client", "isApiPlugin", "plugin", "plugins_default", "enabledPlugins", "p", "enabledApiPlugins", "info", "git_hash_default", "settings_default", "isOutdated", "k", "v", "makeCodeblock", "channelId", "isPluginDev", "UserStore", "DataStore", "rememberDismiss", "Alerts", "VencordCreateElement", "Forms", "alwaysAnimate_default", "init_alwaysAnimate", "__esmMin", "init_react", "init_constants", "init_types", "definePlugin", "Devs", "m", "rest", "alwaysTrust_default", "init_alwaysTrust", "__esmMin", "init_react", "init_constants", "init_types", "definePlugin", "Devs", "tarExtMatcher", "anonymiseFileNames_default", "init_anonymiseFileNames", "__esmMin", "init_react", "init_Settings", "init_constants", "init_types", "definePlugin", "Devs", "Settings", "file", "name", "extIdx", "ext", "chars", "lookupAsset", "applicationId", "key", "ApplicationAssetUtils", "lookupApp", "socket", "RpcUtils", "apps", "ws", "arRPC_default", "init_arRPC", "__esmMin", "init_react", "init_Notices", "init_Link", "init_constants", "init_types", "init_webpack", "init_common", "findByPropsLazy", "definePlugin", "Devs", "VencordCreateElement", "VencordFragment", "Forms", "Link", "data", "activity", "assets", "appId", "app", "FluxDispatcher", "res", "showNotice", "popNotice", "Toasts", "banger_default", "init_banger", "__esmMin", "init_react", "init_constants", "init_types", "definePlugin", "Devs", "ChannelRTCStore", "Animations", "GuildsBar", "FolderSideBar_default", "init_FolderSideBar", "__esmMin", "init_react", "init_ErrorBoundary", "init_webpack", "init_common", "init_betterFolders", "findStoreLazy", "findByPropsLazy", "findComponentByCodeLazy", "ErrorBoundary_default", "guildsBarProps", "expandedFolders", "useStateFromStores", "ExpandedGuildFolderStore", "isFullscreen", "Sidebar", "VencordCreateElement", "visible", "guilds", "barStyle", "settings", "animationStyle", "show", "getGuildFolder", "id", "SortedGuildStore", "folder", "closeFolders", "ExpandedGuildFolderStore", "FolderUtils", "GuildsTree", "lastGuildId", "dispatchingFoldersClose", "settings", "betterFolders_default", "init_betterFolders", "__esmMin", "init_react", "init_Settings", "init_constants", "init_types", "init_webpack", "init_common", "init_FolderSideBar", "findByPropsLazy", "findStoreLazy", "definePluginSettings", "definePlugin", "Devs", "_", "rest", "guildsTree", "isExpandedOrExpandedIds", "folderNote", "isExpanded", "m", "data", "guildFolder", "FluxDispatcher", "expandedFolders", "isBetterFolders", "oldTree", "expandedFolderIds", "newTree", "guildOrFolder", "child", "i18n", "guildsBarProps", "VencordCreateElement", "FolderSideBar_default", "betterGifAltText_default", "init_betterGifAltText", "__esmMin", "init_react", "init_constants", "init_types", "definePlugin", "Devs", "props", "url", "name", "UserPopoutSectionCssClasses", "betterNotes_default", "init_betterNotes", "__esmMin", "init_react", "init_Settings", "init_constants", "init_types", "init_webpack", "findByPropsLazy", "definePlugin", "Devs", "m", "rest", "Settings", "VencordCreateElement", "betterRoleDot_default", "init_betterRoleDot", "__esmMin", "init_react", "init_Settings", "init_constants", "init_types", "init_common", "definePlugin", "Devs", "Settings", "color", "Clipboard", "Toasts", "betterUploadButton_default", "init_betterUploadButton", "__esmMin", "init_react", "init_constants", "init_types", "definePlugin", "Devs", "ApplicationStreamPreviewStore", "ApplicationStreamingStore", "init_stores", "__esmMin", "init_react", "init_webpack", "findStoreLazy", "handleViewPreview", "addViewStreamContext", "streamContextPatch", "userContextPatch", "biggerStreamPreview_default", "init_biggerStreamPreview", "__esmMin", "init_react", "init_ContextMenu", "init_Icons", "init_constants", "init_discord", "init_types", "init_common", "init_stores", "guildId", "channelId", "ownerId", "previewUrl", "ApplicationStreamPreviewStore", "openImageModal", "children", "userId", "stream", "ApplicationStreamingStore", "streamPreviewItem", "VencordCreateElement", "Menu", "ScreenshareIcon", "user", "definePlugin", "Devs", "addContextMenuPatch", "removeContextMenuPatch", "setCss", "style", "Settings", "blurNsfw_default", "init_blurNsfw", "__esmMin", "init_react", "init_Settings", "init_constants", "init_types", "definePlugin", "Devs", "formatDuration", "ms", "human", "Settings", "format", "n", "unit", "s", "delim", "d", "h", "m", "res", "callTimer_default", "init_callTimer", "__esmMin", "init_react", "init_Settings", "init_ErrorBoundary", "init_constants", "init_types", "definePlugin", "Devs", "channelId", "VencordCreateElement", "ErrorBoundary_default", "time", "useTimer", "MessageEvents_exports", "__export", "_handleClick", "_handlePreEdit", "_handlePreSend", "addClickListener", "addPreEditListener", "addPreSendListener", "removeClickListener", "removePreEditListener", "removePreSendListener", "channelId", "messageObj", "extra", "replyOptions", "listener", "sendListeners", "result", "e", "MessageEventsLogger", "messageId", "editListeners", "message", "channel", "event", "MessageStore", "listeners", "init_MessageEvents", "__esmMin", "init_react", "init_Logger", "init_common", "Logger", "defaultRules", "init_defaultRules", "__esmMin", "init_react", "reRegExpChar", "reHasRegExpChar", "clearURLs_default", "init_clearURLs", "__esmMin", "init_react", "init_MessageEvents", "init_constants", "init_types", "init_defaultRules", "definePlugin", "Devs", "str", "rules", "defaultRules", "rule", "splitRule", "paramRule", "hostRule", "hostRuleIndex", "param", "parent", "match", "url", "_value", "regex", "hostRuleName", "msg", "addPreSendListener", "_", "addPreEditListener", "_cid", "_mid", "removePreSendListener", "removePreEditListener", "onPickColor", "color", "hexColor", "settings", "updateColorVars", "ThemeSettings", "lightnessWarning", "hexToLightness", "lightModeWarning", "getTheme", "VencordCreateElement", "Forms", "ColorPicker", "colorPresets", "classes", "Margins", "generateColorOffsets", "styleLinkNodes", "variableLightness", "styleLinkNode", "cssLink", "cssString", "variableMatch", "variableRegex", "variable", "lightness", "lightnessOffsets", "key", "lightnessOffset", "plusOrMinus", "style", "hue", "saturation", "hexToHSL", "hexCode", "r", "g", "b", "cMax", "cMin", "delta", "clientTheme_default", "init_clientTheme", "__esmMin", "init_react", "init_", "init_Settings", "init_constants", "init_discord", "init_margins", "init_misc", "init_types", "init_webpack", "init_common", "findComponentByCodeLazy", "definePluginSettings", "Button", "definePlugin", "Devs", "colorSighted_default", "init_colorSighted", "__esmMin", "init_react", "init_constants", "init_types", "definePlugin", "Devs", "consoleShortcuts_default", "init_consoleShortcuts", "__esmMin", "init_react", "init_constants", "init_native", "init_patches", "init_types", "init_webpack", "init_common", "definePlugin", "Devs", "newFindWrapper", "filterFactory", "cache", "filterProps", "cacheKey", "matches", "findAll", "result", "uniqueMatches", "fakeRenderWin", "find", "f", "findByProps", "filters", "wreq", "search", "extract", "code", "findModuleId", "props", "relaunch", "canonicalizeMatch", "canonicalizeReplace", "canonicalizeReplacement", "component", "prevWin", "win", "doc", "s", "n", "ReactDOM", "React", "shortcuts", "key", "val", "UserContextMenuPatch", "copyUserURLs_default", "init_copyUserURLs", "__esmMin", "init_react", "init_ContextMenu", "init_Icons", "init_constants", "init_types", "init_common", "children", "user", "VencordCreateElement", "Menu", "Clipboard", "LinkIcon", "definePlugin", "Devs", "addContextMenuPatch", "removeContextMenuPatch", "CrashHandlerLogger", "ModalStack", "DraftManager", "DraftType", "closeExpressionPicker", "settings", "crashCount", "lastCrashTimestamp", "shouldAttemptNextHandle", "crashHandler_default", "init_crashHandler", "__esmMin", "init_react", "init_Notifications", "init_Settings", "init_constants", "init_Logger", "init_modal", "init_types", "init_updater", "init_webpack", "init_common", "Logger", "proxyLazyWebpack", "modules", "findBulk", "filters", "definePluginSettings", "definePlugin", "Devs", "_this", "showNotification", "maybePromptToUpdate", "err", "channelId", "SelectedChannelStore", "FluxDispatcher", "closeAllModals", "NavigationRouter", "isTruthy", "item", "isNonNullish", "init_guards", "__esmMin", "init_react", "getApplicationAsset", "key", "ApplicationAssetUtils", "settings", "onChange", "setRpc", "Settings", "isStreamLinkDisabled", "isStreamLinkValid", "value", "isTimestampDisabled", "isImageKeyValid", "createActivity", "appID", "appName", "details", "state", "type", "streamLink", "startTime", "endTime", "imageBig", "imageBigTooltip", "imageSmall", "imageSmallTooltip", "buttonOneText", "buttonOneURL", "buttonTwoText", "buttonTwoURL", "activity", "isTruthy", "v", "disable", "FluxDispatcher", "ActivityComponent", "ActivityClassName", "Colors", "customRPC_default", "init_customRPC", "__esmMin", "init_react", "init_Settings", "init_Link", "init_constants", "init_guards", "init_types", "init_webpack", "init_common", "findComponentByCodeLazy", "findByPropsLazy", "definePluginSettings", "definePlugin", "Devs", "useAwaiter", "VencordCreateElement", "VencordFragment", "Forms", "Link", "SelectedChannelStore", "GuildStore", "SelectedGuildStore", "UserStore", "embedDidMount", "embed", "videoId", "embedUrlRe", "res", "titles", "thumbnails", "hasTitle", "hasThumb", "err", "Logger", "DearrowButton", "component", "VencordCreateElement", "Tooltip", "onMouseEnter", "onMouseLeave", "enabled", "oldThumb", "oldTitle", "dearrow_default", "init_dearrow", "__esmMin", "init_react", "init_", "init_ErrorBoundary", "init_constants", "init_Logger", "init_types", "init_common", "definePlugin", "Devs", "ErrorBoundary_default", "BASE_URL", "API_URL", "AUTHORIZE_URL", "CDN_URL", "CLIENT_ID", "SKU_ID", "RAW_SKU_ID", "GUILD_ID", "INVITE_KEY", "DECORATION_FETCH_COOLDOWN", "init_constants", "__esmMin", "init_react", "indexedDBStorage", "useAuthorizationStore", "init_AuthorizationStore", "__esmMin", "init_react", "init_api", "init_lazy", "init_Logger", "init_modal", "init_common", "init_constants", "name", "DataStore", "v", "value", "proxyLazy", "zustandCreate", "zustandPersist", "set", "get", "UserStore", "token", "id", "tokens", "init", "newTokens", "resolve", "reject", "openModal", "props", "VencordCreateElement", "OAuth2AuthorizeModal", "AUTHORIZE_URL", "CLIENT_ID", "response", "url", "req", "e", "showToast", "Toasts", "Logger", "state", "fetchApi", "url", "options", "res", "useAuthorizationStore", "getUsersDecorations", "getUserDecorations", "getUserDecoration", "setUserDecoration", "deleteDecoration", "getPresets", "init_api", "__esmMin", "init_react", "init_constants", "init_AuthorizationStore", "ids", "API_URL", "c", "id", "decoration", "formData", "hash", "decorationToAsset", "decoration", "decorationToAvatarDecoration", "SKU_ID", "init_decoration", "__esmMin", "init_react", "init_constants", "useUserDecorAvatarDecoration", "user", "decorAvatarDecoration", "setDecorAvatarDecoration", "useState", "useUsersDecorationsStore", "useEffect", "destructor", "state", "newDecorAvatarDecoration", "fetchUserDecorAvatarDecoration", "SKU_ID", "init_UsersDecorationsStore", "__esmMin", "init_react", "init_debounce", "init_lazy", "init_common", "init_api", "init_constants", "proxyLazy", "zustandCreate", "set", "get", "debounce", "fetchQueue", "usersDecorations", "fetchIds", "fetchedUsersDecorations", "getUsersDecorations", "newUsersDecorations", "now", "fetchId", "newDecoration", "userId", "force", "bulkFetch", "fetchedAt", "DECORATION_FETCH_COOLDOWN", "userIds", "newFetchQueue", "decoration", "useCurrentUserDecorationsStore", "init_CurrentUserDecorationsStore", "__esmMin", "init_react", "init_lazy", "init_common", "init_api", "init_decoration", "init_UsersDecorationsStore", "proxyLazy", "zustandCreate", "set", "get", "decorations", "getUserDecorations", "selectedDecoration", "getUserDecoration", "newDecoration", "decoration", "setUserDecoration", "hash", "deleteDecoration", "newState", "d", "useUsersDecorationsStore", "UserStore", "decorationToAsset", "cl", "DecorationModalStyles", "requireAvatarDecorationModal", "requireCreateStickerModal", "init_ui", "__esmMin", "init_react", "init_Styles", "init_webpack", "classNameFactory", "findByPropsLazy", "extractAndLoadChunksLazy", "DecorationGridItem", "setDecorationGridItem", "AvatarDecorationModalPreview", "DecorationGridDecoration", "setDecorationGridDecoration", "init_components", "__esmMin", "init_react", "init_webpack", "init_common", "v", "LazyComponentWebpack", "component", "findComponentByCode", "React", "DecorationGridCreate", "props", "VencordCreateElement", "DecorationGridItem", "PlusIcon", "Text", "i18n", "init_DecorationGridCreate", "__esmMin", "init_react", "init_Icons", "init_common", "init_components", "DecorationGridNone", "props", "VencordCreateElement", "DecorationGridItem", "NoEntrySignIcon", "Text", "i18n", "init_DecorationGridNone", "__esmMin", "init_react", "init_Icons", "init_common", "init_components", "DecorationContextMenu", "decoration", "deleteDecoration", "useCurrentUserDecorationsStore", "VencordCreateElement", "Menu", "cl", "ContextMenuApi", "CopyIcon", "Clipboard", "UserStore", "DeleteIcon", "Alerts", "init_DecorationContextMenu", "__esmMin", "init_react", "init_Icons", "init_common", "init_CurrentUserDecorationsStore", "init_ui", "DecorDecorationGridDecoration", "props", "decoration", "VencordCreateElement", "DecorationGridDecoration", "e", "ContextMenuApi", "DecorationContextMenu", "decorationToAvatarDecoration", "init_DecorDecorationGridDecoration", "__esmMin", "init_react", "init_common", "init_decoration", "init_components", "init_DecorationContextMenu", "Grid", "renderItem", "getItemKey", "ikp", "items", "VencordCreateElement", "cl", "item", "React", "init_Grid", "__esmMin", "init_react", "init_common", "init_ui", "SectionedGridList", "props", "VencordCreateElement", "classes", "cl", "ScrollerClasses", "section", "Grid", "init_SectionedGridList", "__esmMin", "init_react", "init_misc", "init_webpack", "init_ui", "init_Grid", "findByPropsLazy", "useObjectURL", "object", "url", "setUrl", "useState", "useEffect", "objectUrl", "CreateDecorationModal", "props", "name", "setName", "file", "setFile", "submitting", "setSubmitting", "error", "setError", "createDecoration", "useCurrentUserDecorationsStore", "fileUrl", "decoration", "useMemo", "RAW_SKU_ID", "VencordCreateElement", "ModalRoot", "DecorationModalStyles", "ModalHeader", "cl", "Text", "ModalCloseButton", "ModalContent", "ErrorBoundary_default", "HelpMessage", "HelpMessageTypes", "Link", "Forms", "FileUpload", "Margins", "TextInput", "AvatarDecorationModalPreview", "UserStore", "INVITE_KEY", "e", "GuildStore", "GUILD_ID", "closeAllModals", "FluxDispatcher", "NavigationRouter", "openInviteModal", "ModalFooter", "Button", "openCreateDecorationModal", "init_CreateDecorationModal", "__esmMin", "init_react", "init_ErrorBoundary", "init_Link", "init_discord", "init_margins", "init_modal", "init_webpack", "init_common", "init_constants", "init_CurrentUserDecorationsStore", "init_ui", "init_components", "findComponentByCodeLazy", "findByPropsLazy", "requireAvatarDecorationModal", "requireCreateStickerModal", "openModal", "GuidelinesModal", "props", "VencordCreateElement", "ModalRoot", "DecorationModalStyles", "ModalHeader", "cl", "Text", "ModalCloseButton", "ModalContent", "Forms", "Link", "ModalFooter", "Button", "settings", "openCreateDecorationModal", "openGuidelinesModal", "init_GuidelinesModal", "__esmMin", "init_react", "init_Link", "init_modal", "init_common", "init_settings", "init_ui", "init_CreateDecorationModal", "requireAvatarDecorationModal", "openModal", "usePresets", "presets", "setPresets", "useState", "useEffect", "getPresets", "SectionHeader", "section", "hasSubtitle", "hasAuthorIds", "authors", "setAuthors", "authorId", "author", "UserStore", "UserUtils", "VencordCreateElement", "Flex", "Forms", "UserSummaryItem", "Margins", "ChangeDecorationModal", "props", "tryingDecoration", "setTryingDecoration", "isTryingDecoration", "avatarDecorationOverride", "decorationToAvatarDecoration", "decorations", "selectedDecoration", "fetchUserDecorations", "selectDecoration", "useCurrentUserDecorationsStore", "activeSelectedDecoration", "activeDecorationHasAuthor", "hasDecorationPendingReview", "d", "presetDecorations", "preset", "activeDecorationPreset", "isActiveDecorationPreset", "data", "p", "ModalRoot", "DecorationModalStyles", "ModalHeader", "cl", "Text", "ModalCloseButton", "ModalContent", "ErrorBoundary_default", "SectionedGridList", "item", "DecorationGridNone", "Tooltip", "tooltipProps", "DecorationGridCreate", "settings", "openCreateDecorationModal", "openGuidelinesModal", "DecorDecorationGridDecoration", "AvatarDecorationModalPreview", "Parser", "ModalFooter", "classes", "Button", "Alerts", "useAuthorizationStore", "GuildStore", "GUILD_ID", "FluxDispatcher", "NavigationRouter", "openInviteModal", "INVITE_KEY", "closeAllModals", "openChangeDecorationModal", "init_ChangeDecorationModal", "__esmMin", "init_react", "init_ErrorBoundary", "init_Flex", "init_discord", "init_margins", "init_misc", "init_modal", "init_webpack", "init_common", "init_api", "init_constants", "init_AuthorizationStore", "init_CurrentUserDecorationsStore", "init_decoration", "init_settings", "init_ui", "init_components", "init_DecorationGridCreate", "init_DecorationGridNone", "init_DecorDecorationGridDecoration", "init_SectionedGridList", "init_CreateDecorationModal", "init_GuidelinesModal", "findComponentByCodeLazy", "requireAvatarDecorationModal", "openModal", "DecorSection", "hideTitle", "hideDivider", "noMargin", "authorization", "useAuthorizationStore", "selectedDecoration", "selectDecoration", "fetchDecorations", "useCurrentUserDecorationsStore", "useEffect", "VencordCreateElement", "CustomizationSection", "cl", "Flex", "Button", "openChangeDecorationModal", "init_DecorSection", "__esmMin", "init_react", "init_Flex", "init_webpack", "init_common", "init_AuthorizationStore", "init_CurrentUserDecorationsStore", "init_ui", "init_ChangeDecorationModal", "findByCodeLazy", "settings", "init_settings", "__esmMin", "init_react", "init_Settings", "init_Link", "init_margins", "init_misc", "init_modal", "init_types", "init_common", "init_DecorSection", "definePluginSettings", "VencordCreateElement", "DecorSection", "Forms", "classes", "Margins", "Link", "closeAllModals", "FluxDispatcher", "isAnimatedAvatarDecoration", "decor_default", "init_decor", "__esmMin", "init_react", "init_", "init_ErrorBoundary", "init_constants", "init_types", "init_webpack", "init_common", "init_AuthorizationStore", "init_CurrentUserDecorationsStore", "init_UsersDecorationsStore", "init_settings", "init_components", "init_DecorSection", "findByPropsLazy", "definePlugin", "Devs", "settings", "useAuthorizationStore", "useCurrentUserDecorationsStore", "useUsersDecorationsStore", "UserStore", "data", "setDecorationGridItem", "setDecorationGridDecoration", "SKU_ID", "useUserDecorAvatarDecoration", "avatarDecoration", "canAnimate", "url", "CDN_URL", "RAW_SKU_ID", "ErrorBoundary_default", "DecorSection", "disableDMCallIdle_default", "init_disableDMCallIdle", "__esmMin", "init_react", "init_constants", "init_types", "definePlugin", "Devs", "getUrl", "data", "StickerExt", "fetchSticker", "id", "cached", "StickersStore", "body", "RestAPI", "FluxDispatcher", "cloneSticker", "guildId", "sticker", "fetchBlob", "UserStore", "cloneEmoji", "emoji", "dataUrl", "resolve", "reader", "EmojiManager", "getGuildCandidates", "meId", "GuildStore", "g", "PermissionStore", "PermissionsBits", "isAnimated", "emojiSlots", "emojis", "EmojiStore", "count", "a", "b", "url", "res", "doClone", "Toasts", "e", "message", "Logger", "CloneModal", "isCloning", "setIsCloning", "React", "name", "setName", "x", "invalidateMemo", "guilds", "VencordCreateElement", "VencordFragment", "Forms", "Margins", "CheckedTextInput", "v", "nameValidator", "Tooltip", "onMouseLeave", "onMouseEnter", "getFontSize", "buildMenuItem", "type", "fetchData", "Menu", "openModalLazy", "modalProps", "ModalRoot", "ModalHeader", "ModalContent", "isGifUrl", "messageContextMenuPatch", "expressionPickerPatch", "emoteCloner_default", "init_emoteCloner", "__esmMin", "init_react", "init_ContextMenu", "init_CheckedTextInput", "init_constants", "init_Logger", "init_margins", "init_modal", "init_types", "init_webpack", "init_common", "findStoreLazy", "findByPropsLazy", "s", "children", "props", "favoriteableId", "itemHref", "itemSrc", "favoriteableType", "menuItem", "match", "findGroupChildrenByChildId", "firstChild", "definePlugin", "Devs", "addContextMenuPatch", "removeContextMenuPatch", "KbdStyles", "settings", "experiments_default", "init_experiments", "__esmMin", "init_react", "init_Settings", "init_ErrorBoundary", "init_ErrorCard", "init_constants", "init_margins", "init_types", "init_webpack", "init_common", "findByPropsLazy", "definePluginSettings", "definePlugin", "Devs", "_", "user", "flags", "isMacOS", "modKey", "altKey", "VencordCreateElement", "React", "Forms", "ErrorBoundary_default", "ErrorCard", "Margins", "f8break_default", "init_f8break", "__esmMin", "init_react", "init_constants", "init_types", "definePlugin", "Devs", "init_web_metadata", "__esmMin", "init_react", "require_apng_canvas", "__commonJSMin", "exports", "module", "init_react", "self", "i", "o", "a", "s", "u", "n", "t", "e", "__require", "c", "r", "Y", "G", "q", "l", "d", "g", "f", "h", "p", "v", "A", "m", "w", "b", "_", "j", "L", "U", "y", "T", "E", "P", "x", "N", "O", "R", "C", "B", "I", "D", "k", "F", "S", "M", "importApngJs", "rnnoiseDist", "rnnoiseWorkletSrc", "shikiWorkerSrc", "shikiOnigasmSrc", "getStegCloak", "init_dependencies", "__esmMin", "init_react", "init_lazy", "init_web_metadata", "makeLazy", "__markAsModule", "exports", "__export", "GIFEncoder", "applyPalette", "src_default", "nearestColor", "nearestColorIndex", "nearestColorIndexWithDistance", "prequantize", "quantize", "snapColorsToPalette", "constants_default", "createStream", "initialCapacity", "cursor", "contents", "byte", "expand", "data", "offset", "byteLength", "i", "newCapacity", "prevCapacity", "CAPACITY_DOUBLING_MAX", "oldContents", "BITS", "DEFAULT_HSIZE", "MASKS", "lzwEncode", "width", "height", "pixels", "colorDepth", "outStream", "accum", "htab", "codetab", "hsize", "initCodeSize", "cur_accum", "cur_bits", "init_bits", "g_init_bits", "clear_flg", "n_bits", "maxcode", "ClearCode", "EOFCode", "free_ent", "a_count", "ent", "hshift", "fcode", "output", "length", "idx", "next_block", "c", "disp", "code", "lzwEncode_default", "rgb888_to_rgb565", "r", "g", "b", "rgba8888_to_rgba4444", "a", "rgb888_to_rgb444", "clamp", "value", "min", "max", "sqr", "find_nn", "bins", "hasAlpha", "nn", "err", "bin1", "n1", "wa", "wr", "wg", "wb", "bin", "n2", "nerr2", "nerr", "create_bin", "create_bin_list", "format", "bincount", "size", "color", "index", "rgba", "maxColors", "opts", "clearAlpha", "clearAlphaColor", "clearAlphaThreshold", "oneBitAlpha", "useSqrt", "bincountMinusOne", "heap", "maxbins", "d", "h", "l", "l2", "extbins", "tb", "b1", "nb", "palette", "k", "existsInPalette", "p", "matchesRGB", "matchesAlpha", "euclideanDistanceSquared", "sum", "n", "dx", "roundStep", "step", "roundRGB", "roundAlpha", "cache", "key", "nearestColorIndexRGBA", "rgb888_to_key", "nearestColorIndexRGB", "mindist", "px2", "a2", "curdist", "sqr2", "r2", "g2", "b2", "knownColors", "threshold", "paletteRGB", "thresholdSq", "dim", "distanceSq", "colors", "pixel", "distanceFn", "minDist", "minDistIndex", "j", "paletteColor", "dist", "opt", "auto", "stream", "HSIZE", "hasInit", "writeHeader", "transparent", "transparentIndex", "delay", "repeat", "dispose", "first", "encodeLogicalScreenDescriptor", "encodeColorTable", "encodeNetscapeExt", "delayTime", "encodeGraphicControlExt", "useLocalColorTable", "encodeImageDescriptor", "encodePixels", "writeUTFBytes", "transp", "userInput", "writeUInt16", "globalColorTableSize", "colorTableSize", "fields", "backgroundColorIndex", "pixelAspectRatio", "colorTableLength", "localPalette", "palSize", "short", "text", "searchProtoClassField", "localName", "protoClass", "field", "value", "import_gifenc", "DRAFT_TYPE", "StickerStore", "UserSettingsProtoStore", "ProtoUtils", "PreloadedUserSettingsActionCreators", "AppearanceSettingsActionCreators", "ClientThemeSettingsActionsCreators", "USE_EXTERNAL_EMOJIS", "USE_EXTERNAL_STICKERS", "fakeNitroEmojiRegex", "fakeNitroStickerRegex", "fakeNitroGifStickerRegex", "settings", "fakeNitro_default", "init_fakeNitro", "__esmMin", "init_react", "init_MessageEvents", "init_Settings", "init_constants", "init_dependencies", "init_discord", "init_Logger", "init_types", "init_webpack", "init_common", "findStoreLazy", "findByPropsLazy", "proxyLazyWebpack", "UserSettingsActionCreators", "definePluginSettings", "definePlugin", "Devs", "_", "intention", "rest", "canUseExternal", "m", "premiumCheck", "func", "props", "backgroundGradientPresetId", "originalCall", "theme", "content", "rest1", "message", "rest2", "embed", "stickers", "attachments", "renderableSticker", "reactNode", "node", "getCurrentGuild", "UserStore", "proto", "user", "appearanceSettingsDummy", "clientThemeSettingsDummy", "original", "currentAppearanceSettings", "newAppearanceProto", "FluxDispatcher", "firstContent", "lastIndex", "lastContent", "array", "item", "child", "inline", "nextIndex", "transformLinkChild", "fakeNitroMatch", "url", "emojiName", "EmojiStore", "Parser", "gifMatch", "transformChild", "modifyChildren", "modifyChild", "newChild", "listHasAnItem", "index", "children", "lodash", "err", "Logger", "itemsToMaybePush", "contentItems", "attachment", "imgMatch", "stickerName", "match", "link", "type", "fake", "channelId", "channel", "ChannelStore", "PermissionStore", "stickerId", "Settings", "stickerLink", "parseURL", "importApngJs", "frames", "width", "height", "gif", "resolution", "canvas", "ctx", "scale", "previousFrameData", "frame", "left", "top", "img", "delay", "blendOp", "disposeOp", "data", "palette", "file", "UploadHandler", "s", "getWordBoundary", "origStr", "offset", "addPreSendListener", "messageObj", "extra", "guildId", "stickerBypass", "sticker", "canUseStickers", "canUseEmotes", "emoji", "emojiString", "addPreEditListener", "__", "emojiStr", "emojiId", "removePreSendListener", "removePreEditListener", "virtualMerge", "objects", "fallback", "findObjectByProp", "prop", "i", "handler", "acc", "obj", "method", "_", "args", "dist_default", "init_dist", "__esmMin", "init_react", "encode", "primary", "accent", "message", "padding", "encoded", "x", "decode", "bio", "colorString", "parsed", "settings", "fakeProfileThemes_default", "init_fakeProfileThemes", "__esmMin", "init_react", "init_Settings", "init_ErrorBoundary", "init_constants", "init_margins", "init_misc", "init_types", "init_common", "init_dist", "definePluginSettings", "definePlugin", "Devs", "VencordCreateElement", "Forms", "user", "colors", "dist_default", "ErrorBoundary_default", "Button", "copyWithToast", "Margins", "favEmojiFirst_default", "init_favEmojiFirst", "__esmMin", "init_react", "init_constants", "init_types", "init_common", "definePlugin", "Devs", "query", "emojiContext", "EmojiStore", "a", "b", "aIsFavorite", "bIsFavorite", "SearchBar", "instance", "SearchBarComponent", "query", "setQuery", "useState", "ref", "useRef", "onChange", "useCallback", "searchQuery", "props", "result", "gif", "fuzzySearch", "getTargetString", "m", "a", "b", "e", "useEffect", "VencordCreateElement", "containerClasses", "urlStr", "url", "settings", "searchString", "searchIndex", "score", "favGifSearch_default", "init_favGifSearch", "__esmMin", "init_react", "init_Settings", "init_ErrorBoundary", "init_constants", "init_types", "init_webpack", "init_common", "findByPropsLazy", "definePluginSettings", "definePlugin", "Devs", "ErrorBoundary_default", "favorites", "filteredFavorites", "fixSpotifyEmbeds_default", "init_fixSpotifyEmbeds", "__esmMin", "init_react", "init_Settings", "init_components", "init_constants", "init_types", "definePlugin", "Devs", "definePluginSettings", "makeRange", "forceOwnerCrown_default", "init_forceOwnerCrown", "__esmMin", "init_react", "init_constants", "init_types", "init_common", "definePlugin", "Devs", "props", "guildId", "userId", "GuildStore", "FriendInvites", "uuid4", "friendInvites_default", "init_friendInvites", "__esmMin", "init_react", "init_Commands", "init_constants", "init_types", "init_webpack", "init_common", "findByPropsLazy", "definePlugin", "Devs", "args", "ctx", "uses", "findOption", "UserStore", "sendBotMessage", "invite", "random", "invite_suggestions", "RestAPI", "_", "friendInviteList", "style_default", "init_style", "__esmMin", "init_react", "makeIcon", "showCurrentGame", "oldIcon", "settings", "redLinePath", "maskBlackPath", "VencordCreateElement", "VencordFragment", "GameActivityToggleButton", "StatusSettingsStores", "Button", "old", "gameActivityToggle_default", "init_gameActivityToggle", "__esmMin", "init_react", "init_Settings", "init_Styles", "init_ErrorBoundary", "init_constants", "init_types", "init_webpack", "init_common", "init_style", "findComponentByCodeLazy", "definePluginSettings", "definePlugin", "Devs", "ErrorBoundary_default", "enableStyle", "style_default", "disableStyle", "closeExpressionPicker", "gifPaste_default", "init_gifPaste", "__esmMin", "init_react", "init_constants", "init_discord", "init_types", "init_webpack", "findByPropsLazy", "definePlugin", "Devs", "gif", "insertTextIntoChatInputBox", "greet", "channel", "message", "stickers", "options", "MessageActions", "settings", "msg", "GreetMenu", "s", "greetMode", "multiGreetChoices", "VencordCreateElement", "Menu", "FluxDispatcher", "GreetMode", "mode", "WELCOME_STICKERS", "sticker", "VencordFragment", "checked", "greetStickerPicker_default", "init_greetStickerPicker", "__esmMin", "init_react", "init_Settings", "init_constants", "init_types", "init_webpack", "init_common", "definePluginSettings", "findByPropsLazy", "definePlugin", "Devs", "event", "props", "ContextMenuApi", "MessagePopover_exports", "__export", "_buildPopoverElements", "addButton", "buttons", "removeButton", "identifier", "item", "msg", "makeButton", "items", "getItem", "err", "logger", "init_MessagePopover", "__esmMin", "init_react", "init_Logger", "Logger", "style", "KEY", "hiddenMessages", "getHiddenMessages", "saveHiddenMessages", "hideAttachments_default", "init_hideAttachments", "__esmMin", "init_react", "init_DataStore", "init_MessagePopover", "init_Icons", "init_constants", "init_types", "init_common", "get", "set", "ids", "definePlugin", "Devs", "addButton", "msg", "isHidden", "ImageVisible", "ImageInvisible", "ChannelStore", "removeButton", "elements", "id", "iLoveSpam_default", "init_iLoveSpam", "__esmMin", "init_react", "init_constants", "init_types", "definePlugin", "Devs", "ToggleIcon", "activity", "tooltipText", "path", "fill", "VencordCreateElement", "Tooltip", "tooltipProps", "e", "handleActivityToggle", "ToggleActivityComponent", "isPlaying", "s", "settings", "ignoredActivities", "act", "ToggleIconOff", "ToggleIconOn", "ignoredActivityIndex", "getIgnoredActivities", "_", "index", "StatusSettingsStores", "old", "RunningGameStore", "ignoreActivities_default", "init_ignoreActivities", "__esmMin", "init_react", "init_DataStore", "init_Settings", "init_ErrorBoundary", "init_constants", "init_types", "init_webpack", "init_common", "findStoreLazy", "definePluginSettings", "definePlugin", "Devs", "m", "activities", "props", "nowPlaying", "oldIgnoredActivitiesData", "get", "del", "gamesSeen", "ignoredActivity", "game", "exePath", "ErrorBoundary_default", "ELEMENT_ID", "init_constants", "__esmMin", "init_react", "waitFor", "condition", "cb", "init_waitFor", "__esmMin", "init_react", "cl", "Magnifier", "init_Magnifier", "__esmMin", "init_react", "init_Styles", "init_common", "init_constants", "init_imageZoom", "init_waitFor", "classNameFactory", "instance", "initialSize", "initalZoom", "ready", "setReady", "useState", "lensPosition", "setLensPosition", "imagePosition", "setImagePosition", "opacity", "setOpacity", "isShiftDown", "useRef", "zoom", "size", "element", "currentVideoElementRef", "originalVideoElementRef", "imageRef", "React", "onKeyDown", "e", "onKeyUp", "syncVideos", "updateMousePosition", "offset", "pos", "x", "y", "onMouseDown", "settings", "FluxDispatcher", "onMouseUp", "onWheel", "val", "waitFor", "elem", "ELEMENT_ID", "box", "VencordCreateElement", "styles_default", "init_styles", "__esmMin", "init_react", "settings", "imageContextMenuPatch", "imageZoom_default", "init_imageZoom", "__esmMin", "init_react", "init_ContextMenu", "init_Settings", "init_Styles", "init_components", "init_constants", "init_debounce", "init_types", "init_common", "init_Magnifier", "init_styles", "definePluginSettings", "makeRange", "children", "VencordCreateElement", "Menu", "ContextMenuApi", "props", "ref", "debounce", "value", "definePlugin", "Devs", "ELEMENT_ID", "Magnifier", "instance", "e", "ReactDOM", "state", "enableStyle", "styles_default", "addContextMenuPatch", "disableStyle", "removeContextMenuPatch", "DecModal", "props", "encryptedMessage", "password", "setPassword", "React", "VencordCreateElement", "ModalRoot", "ModalHeader", "Forms", "ModalContent", "TextInput", "ModalFooter", "Button", "toSend", "decrypt", "buildDecModal", "msg", "openModal", "init_DecryptionModal", "__esmMin", "init_react", "init_modal", "init_common", "init_invisibleChat", "EncModal", "props", "secret", "setSecret", "React", "cover", "setCover", "password", "setPassword", "noCover", "setNoCover", "isValid", "VencordCreateElement", "ModalRoot", "ModalHeader", "Forms", "ModalContent", "TextInput", "e", "Switch", "ModalFooter", "Button", "encrypted", "encrypt", "toSend", "insertTextIntoChatInputBox", "buildEncModal", "openModal", "init_EncryptionModal", "__esmMin", "init_react", "init_discord", "init_modal", "init_common", "init_invisibleChat", "PopOverIcon", "VencordCreateElement", "Indicator", "Tooltip", "onMouseEnter", "onMouseLeave", "ChatBarIcon", "chatBoxProps", "Button", "ButtonLooks", "ButtonWrapperClasses", "buildEncModal", "encrypt", "secret", "password", "cover", "steggo", "decrypt", "encrypted", "removeIndicator", "decrypted", "isCorrectPassword", "result", "iteratePasswords", "message", "passwords", "settings", "s", "content", "i", "invisibleChat_default", "init_invisibleChat", "__esmMin", "init_react", "init_MessagePopover", "init_Settings", "init_ErrorBoundary", "init_constants", "init_dependencies", "init_types", "init_common", "init_DecryptionModal", "init_EncryptionModal", "definePluginSettings", "definePlugin", "Devs", "StegCloak", "getStegCloak", "addButton", "ChannelStore", "res", "buildDecModal", "removeButton", "url", "body", "RestAPI", "revealed", "urlCheck", "embed", "FluxDispatcher", "ErrorBoundary_default", "attemptToNavigateToChannel", "guildId", "channelId", "ChannelStore", "NavigationRouter", "isSwitchingAccount", "previousCache", "keepCurrentChannel_default", "init_keepCurrentChannel", "__esmMin", "init_react", "init_DataStore", "init_constants", "init_types", "init_common", "definePlugin", "Devs", "set", "get", "SelectedGuildStore", "SelectedChannelStore", "getApplicationAsset", "key", "ApplicationAssetUtils", "applicationId", "setActivity", "activity", "FluxDispatcher", "placeholderId", "logger", "presenceStore", "settings", "lastfm_default", "init_lastfm", "__esmMin", "init_react", "init_Settings", "init_Link", "init_constants", "init_Logger", "init_types", "init_webpack", "init_common", "Logger", "findByPropsLazy", "definePluginSettings", "definePlugin", "Devs", "VencordCreateElement", "VencordFragment", "Forms", "Link", "params", "res", "json", "trackData", "x", "track", "largeImage", "assets", "buttons", "statusName", "v", "quotes", "settings", "loadingQuotes_default", "init_loadingQuotes", "__esmMin", "init_react", "init_Settings", "init_constants", "init_types", "definePluginSettings", "definePlugin", "Devs", "quote", "key", "codes", "s", "MemberCount", "channelId", "guildId", "useStateFromStores", "SelectedChannelStore", "getCurrentChannel", "groups", "ChannelMemberStore", "total", "GuildMemberCountStore", "online", "count", "curr", "VencordCreateElement", "Flex", "Tooltip", "numberFormat", "props", "sharedIntlNumberFormat", "memberCount_default", "init_memberCount", "__esmMin", "init_react", "init_ErrorBoundary", "init_Flex", "init_constants", "init_discord", "init_types", "init_webpack", "init_common", "findStoreLazy", "value", "definePlugin", "Devs", "ErrorBoundary_default", "isDeletePressed", "keydown", "keyup", "settings", "messageClickActions_default", "init_messageClickActions", "__esmMin", "init_react", "init_MessageEvents", "init_Settings", "init_constants", "init_types", "init_webpack", "init_common", "definePluginSettings", "definePlugin", "Devs", "MessageActions", "findByPropsLazy", "EditStore", "addClickListener", "msg", "channel", "event", "isMe", "UserStore", "PermissionStore", "PermissionsBits", "FluxDispatcher", "EPHEMERAL", "Settings", "removeClickListener", "MessageAccessories_exports", "__export", "_modifyAccessories", "accessories", "addAccessory", "removeAccessory", "identifier", "callback", "position", "elements", "props", "accessory", "e", "init_MessageAccessories", "__esmMin", "init_react", "fetchMessage", "channelID", "messageID", "cached", "messageCache", "msg", "RestAPI", "message", "MessageStore", "getImages", "attachments", "content_type", "height", "width", "url", "proxy_url", "type", "image", "thumbnail", "tenorRegex", "noContent", "embeds", "requiresRichEmbed", "a", "e", "computeWidthAndHeight", "adjustedWidth", "adjustedHeight", "withEmbeddedBy", "embeddedBy", "_", "prop", "MessageEmbedAccessory", "accessories", "match", "messageLinkRegex", "guildID", "linkedChannel", "ChannelStore", "PermissionStore", "listMode", "idList", "settings", "isListed", "id", "linkedMessage", "messageFetchQueue", "m", "FluxDispatcher", "messageProps", "VencordCreateElement", "AutomodEmbedAccessory", "ChannelMessageEmbedAccessory", "VencordFragment", "channel", "isDM", "guild", "GuildStore", "dmReceiver", "UserStore", "Embed", "Text", "Parser", "classes", "SearchResultClasses", "ChannelMessage", "props", "compact", "TextAndImagesSettingsStores", "images", "parse", "AutoModEmbed", "messageLinkEmbeds_default", "init_messageLinkEmbeds", "__esmMin", "init_react", "init_MessageAccessories", "init_Settings", "init_ErrorBoundary", "init_constants", "init_misc", "init_Queue", "init_types", "init_webpack", "init_common", "findComponentByCodeLazy", "findByPropsLazy", "Queue", "definePluginSettings", "Button", "definePlugin", "Devs", "addAccessory", "ErrorBoundary_default", "deleteStyleOverlay_default", "init_deleteStyleOverlay", "__esmMin", "init_react", "deleteStyleText_default", "init_deleteStyleText", "__esmMin", "init_react", "addDeleteStyle", "Settings", "enableStyle", "deleteStyleText_default", "disableStyle", "deleteStyleOverlay_default", "styles", "REMOVE_HISTORY_ID", "TOGGLE_DELETE_STYLE_ID", "patchMessageContextMenu", "messageLogger_default", "init_messageLogger", "__esmMin", "init_react", "init_", "init_ContextMenu", "init_Settings", "init_Styles", "init_ErrorBoundary", "init_constants", "init_Logger", "init_types", "init_webpack", "init_common", "init_deleteStyleOverlay", "init_deleteStyleText", "findByPropsLazy", "children", "props", "message", "deleted", "editHistory", "id", "channel_id", "toggle", "domElement", "VencordCreateElement", "Menu", "FluxDispatcher", "definePlugin", "Devs", "addContextMenuPatch", "removeContextMenuPatch", "edit", "ErrorBoundary_default", "Parser", "Timestamp", "i18n", "newMessage", "oldMessage", "moment", "cache", "data", "isBulk", "mutate", "msg", "EPHEMERAL", "m", "a", "e", "Logger", "ignoreBots", "ignoreSelf", "ignoreUsers", "ignoreChannels", "ignoreGuilds", "myId", "UserStore", "ChannelStore", "createTagCommand", "tag", "registerCommand", "_", "ctx", "getTag", "Settings", "sendBotMessage", "EMOTE", "MessageTagsMarker", "DATA_KEY", "getTags", "addTag", "removeTag", "messageTags_default", "init_messageTags", "__esmMin", "init_react", "init_Commands", "init_DataStore", "init_Settings", "init_constants", "init_types", "get", "t", "name", "tt", "tags", "set", "definePlugin", "Devs", "args", "findOption", "message", "unregisterCommand", "mock", "input", "output", "i", "moreCommands_default", "init_moreCommands", "__esmMin", "init_react", "init_Commands", "init_constants", "init_types", "definePlugin", "Devs", "OptionalMessageOption", "opts", "ctx", "content", "findOption", "sendBotMessage", "RequiredMessageOption", "moreKaomoji_default", "init_moreKaomoji", "__esmMin", "init_react", "init_Commands", "init_constants", "init_types", "definePlugin", "Devs", "data", "OptionalMessageOption", "opts", "findOption", "SettingsComponent", "props", "settings", "defaultSettings", "tagSettings", "setTagSettings", "useState", "setValue", "v", "VencordCreateElement", "Flex", "tags", "t", "Card", "Forms", "Tooltip", "onMouseEnter", "onMouseLeave", "Tag", "TextInput", "Margins", "Switch", "PermissionUtil", "isWebhook", "moreUserTags_default", "init_moreUserTags", "__esmMin", "init_react", "init_Settings", "init_Flex", "init_constants", "init_margins", "init_types", "init_webpack", "init_common", "findByPropsLazy", "findLazy", "m", "message", "user", "_", "channel", "GuildStore", "name", "displayName", "definePluginSettings", "definePlugin", "Devs", "origSwitch", "variant", "displayedText", "strings", "newSettings", "value", "setting", "tag", "guild", "permissions", "PermissionsBits", "perm", "permInt", "obj", "i", "passedTagName", "tagName", "tagText", "channelId", "origType", "location", "type", "ChannelStore", "perms", "countOccurrences", "sourceString", "subString", "i", "lastIdx", "countMatches", "pattern", "getMoyaiCount", "message", "count", "MOYAI", "customMoyaiRe", "boom", "settings", "audioElement", "MOYAI_URL_HD", "MOYAI_URL", "moyai_default", "init_moyai", "__esmMin", "init_react", "init_Settings", "init_SettingSliderComponent", "init_constants", "init_misc", "init_types", "init_common", "definePluginSettings", "makeRange", "definePlugin", "Devs", "optimistic", "type", "channelId", "RelationshipStore", "SelectedChannelStore", "moyaiCount", "sleep", "userId", "messageAuthorId", "emoji", "UserStore", "name", "updateGuildNotificationSettings", "settings", "muteNewGuild_default", "init_muteNewGuild", "__esmMin", "init_react", "init_Settings", "init_constants", "init_types", "init_webpack", "findByPropsLazy", "definePluginSettings", "definePlugin", "Devs", "m", "guildId", "lurker", "getGroupDMName", "channel", "UserStore", "isNonNullish", "c", "RelationshipStore", "UserUtils", "SelectedChannelActionCreators", "AvatarUtils", "ProfileListClasses", "GuildLabelClasses", "mutualGroupDMs_default", "init_mutualGroupDMs", "__esmMin", "init_react", "init_constants", "init_guards", "init_types", "init_webpack", "init_common", "findByPropsLazy", "definePlugin", "Devs", "user", "onClose", "entries", "ChannelStore", "VencordCreateElement", "Clickable", "Avatar", "ScrollerThin", "RelationshipStore", "noBlockedMessages_default", "init_noBlockedMessages", "__esmMin", "init_react", "init_Settings", "init_constants", "init_types", "init_webpack", "findByPropsLazy", "definePlugin", "Devs", "find", "Settings", "_", "props", "message", "noDevtoolsWarning_default", "init_noDevtoolsWarning", "__esmMin", "init_react", "init_constants", "init_types", "definePlugin", "Devs", "noF1_default", "init_noF1", "__esmMin", "init_react", "init_constants", "init_types", "definePlugin", "Devs", "styles_default", "init_styles", "__esmMin", "init_react", "settings", "noMosaic_default", "init_noMosaic", "__esmMin", "init_react", "init_Settings", "init_Styles", "init_constants", "init_types", "init_styles", "definePluginSettings", "definePlugin", "Devs", "enableStyle", "styles_default", "disableStyle", "MessageRequestStore", "settings", "noPendingCount_default", "init_noPendingCount", "__esmMin", "init_react", "init_Settings", "init_constants", "init_types", "init_webpack", "findByPropsLazy", "definePluginSettings", "definePlugin", "Devs", "noProfileThemes_default", "init_noProfileThemes", "__esmMin", "init_react", "init_constants", "init_types", "definePlugin", "Devs", "settings", "noReplyMention_default", "init_noReplyMention", "__esmMin", "init_react", "init_Settings", "init_constants", "init_types", "definePluginSettings", "definePlugin", "Devs", "message", "isHoldingShift", "isListed", "isExempt", "noScreensharePreview_default", "init_noScreensharePreview", "__esmMin", "init_react", "init_constants", "init_types", "definePlugin", "Devs", "noTypingAnimation_default", "init_noTypingAnimation", "__esmMin", "init_react", "init_constants", "init_types", "definePlugin", "Devs", "noUnblockToJump_default", "init_noUnblockToJump", "__esmMin", "init_react", "init_constants", "init_types", "definePlugin", "Devs", "normalizeMessageLinks_default", "init_normalizeMessageLinks", "__esmMin", "init_react", "init_constants", "init_types", "definePlugin", "Devs", "host", "settings", "notificationVolume_default", "init_notificationVolume", "__esmMin", "init_react", "init_Settings", "init_constants", "init_types", "definePluginSettings", "definePlugin", "Devs", "nsfwGateBypass_default", "init_nsfwGateBypass", "__esmMin", "init_react", "init_constants", "init_types", "definePlugin", "Devs", "settings", "onePingPerDM_default", "init_onePingPerDM", "__esmMin", "init_react", "init_Settings", "init_constants", "init_types", "init_common", "definePluginSettings", "definePlugin", "Devs", "message", "channelType", "ChannelStore", "m", "UserStore", "ReadStateStore", "oneko_default", "init_oneko", "__esmMin", "init_react", "init_constants", "init_types", "definePlugin", "Devs", "x", "s", "ShortUrlMatcher", "SpotifyMatcher", "SteamMatcher", "EpicMatcher", "settings", "Native", "openInApp_default", "init_openInApp", "__esmMin", "init_react", "init_Settings", "init_constants", "init_types", "init_common", "definePluginSettings", "definePlugin", "Devs", "data", "event", "url", "spotify", "match", "type", "id", "steam", "showToast", "Toasts", "epic", "platformType", "userId", "setPoggerState", "state", "FluxDispatcher", "setSettings", "intensity", "settings", "partyMode_default", "init_partyMode", "__esmMin", "init_react", "init_Settings", "init_constants", "init_types", "init_common", "definePluginSettings", "definePlugin", "Devs", "settings", "permissionFreeWill_default", "init_permissionFreeWill", "__esmMin", "init_react", "init_Settings", "init_constants", "init_types", "definePluginSettings", "definePlugin", "Devs", "formatPermissionWithoutMatchingString", "permission", "wordsToTitle", "getPermissionString", "PermissionKeyMap", "i18n", "getPermissionDescription", "msg", "Parser", "getSortedRoles", "roles", "id", "member", "a", "b", "sortUserRoles", "settings", "sortPermissionOverwrites", "overwrites", "guildId", "guild", "GuildStore", "roleA", "cl", "init_utils", "__esmMin", "init_react", "init_Styles", "init_text", "init_common", "init_permissionsViewer", "init_RolesAndUsersPermissions", "classNameFactory", "PermissionDeniedIcon", "VencordCreateElement", "PermissionAllowedIcon", "PermissionDefaultIcon", "init_icons", "__esmMin", "init_react", "openRolesAndUsersPermissionsModal", "permissions", "guild", "header", "openModal", "modalProps", "VencordCreateElement", "RolesAndUsersPermissions", "RolesAndUsersPermissionsComponent", "a", "b", "useStateFromStores", "GuildMemberStore", "old", "current", "useEffect", "usersToRequest", "p", "id", "FluxDispatcher", "selectedItemIndex", "selectItem", "useState", "selectedItem", "ModalRoot", "ModalHeader", "Text", "cl", "ModalCloseButton", "ModalContent", "permission", "index", "user", "UserStore", "role", "e", "settings", "ContextMenuApi", "RoleContextMenu", "getUniqueUsername", "Flex", "OwnerCrownIcon", "PermissionsBits", "permissionName", "bit", "overwriteAllow", "overwriteDeny", "PermissionAllowedIcon", "PermissionDeniedIcon", "PermissionDefaultIcon", "getPermissionString", "Tooltip", "getPermissionDescription", "props", "InfoIcon", "roleId", "onClose", "Menu", "RolesAndUsersPermissions_default", "init_RolesAndUsersPermissions", "__esmMin", "init_react", "init_ErrorBoundary", "init_Flex", "init_Icons", "init_discord", "init_modal", "init_common", "init_permissionsViewer", "init_utils", "init_icons", "ErrorBoundary_default", "ExpandableHeader", "children", "onMoreClick", "buttons", "moreTooltipText", "defaultState", "onDropDownClick", "headerText", "showContent", "setShowContent", "useState", "VencordCreateElement", "VencordFragment", "Text", "cl", "Tooltip", "tooltipProps", "v", "init_ExpandableHeader", "__esmMin", "init_react", "init_Styles", "init_common", "init_", "classNameFactory", "UserPermissionsComponent", "guild", "guildMember", "showBorder", "stns", "settings", "rolePermissions", "userPermissions", "useMemo", "userRoles", "getSortedRoles", "role", "PermissionsBits", "prev", "curr", "OWNER", "i18n", "sortUserRoles", "permission", "bit", "permissions", "colorString", "position", "getPermissionString", "a", "b", "root", "roleRemoveButton", "roleNameOverflow", "roles", "rolePill", "rolePillBorder", "roleCircle", "roleName", "Classes", "VencordCreateElement", "ExpandableHeader", "RolesAndUsersPermissions_default", "UserStore", "Tooltip", "tooltipProps", "cl", "classes", "roleColor", "Text", "UserPermissions_default", "init_UserPermissions", "__esmMin", "init_react", "init_ErrorBoundary", "init_ExpandableHeader", "init_misc", "init_webpack", "init_common", "init_permissionsViewer", "init_utils", "init_RolesAndUsersPermissions", "proxyLazyWebpack", "findBulk", "filters", "ErrorBoundary_default", "MenuItem", "guildId", "id", "type", "GuildMemberStore", "VencordCreateElement", "Menu", "guild", "GuildStore", "permissions", "header", "member", "getSortedRoles", "role", "PermissionsBits", "prev", "curr", "UserStore", "channel", "ChannelStore", "sortPermissionOverwrites", "allow", "deny", "RolesAndUsersPermissions_default", "makeContextMenuPatch", "childId", "children", "props", "group", "findGroupChildrenByChildId", "item", "settings", "permissionsViewer_default", "init_permissionsViewer", "__esmMin", "init_react", "init_", "init_ContextMenu", "init_Settings", "init_constants", "init_types", "init_common", "init_RolesAndUsersPermissions", "init_UserPermissions", "init_utils", "definePluginSettings", "definePlugin", "Devs", "m", "showBoder", "guildMember", "UserPermissions_default", "addContextMenuPatch", "removeContextMenuPatch", "loadImage", "source", "isFile", "url", "resolve", "reject", "img", "event", "_source", "_lineno", "_colno", "err", "resolveImage", "options", "ctx", "noServerPfp", "opt", "upload", "UploadStore", "DRAFT_TYPE", "UserUtils", "import_gifenc", "DEFAULT_DELAY", "DEFAULT_RESOLUTION", "FRAMES", "getFrames", "petpet_default", "init_petpet", "__esmMin", "init_react", "init_Commands", "init_constants", "init_lazy", "init_types", "init_webpack", "init_common", "makeLazy", "_", "i", "findByPropsLazy", "definePlugin", "Devs", "opts", "cmdCtx", "frames", "findOption", "sendBotMessage", "avatar", "delay", "resolution", "gif", "canvas", "j", "width", "height", "offsetX", "offsetY", "data", "palette", "index", "file", "UploadHandler", "settings", "pictureInPicture_default", "init_pictureInPicture", "__esmMin", "init_react", "init_", "init_Settings", "init_ErrorBoundary", "init_constants", "init_types", "init_common", "definePluginSettings", "definePlugin", "Devs", "ErrorBoundary_default", "VencordCreateElement", "Tooltip", "tooltipProps", "e", "video", "videoClone", "launchPiP", "usePinnedDms", "useSettings", "requireSnapshot", "isPinned", "id", "togglePin", "snapshot", "save", "sortedSnapshot", "settings", "PrivateChannelSortStore", "snapshotArray", "getPinAt", "idx", "movePin", "direction", "pins", "getArray", "a", "b", "takeSnapshot", "init_settings", "__esmMin", "init_react", "init_Settings", "init_types", "init_webpack", "definePluginSettings", "findStoreLazy", "Settings", "PinMenuItem", "channelId", "pinned", "isPinned", "canMove", "settings", "VencordCreateElement", "VencordFragment", "Menu", "togglePin", "snapshotArray", "movePin", "addContextMenus", "addContextMenuPatch", "GroupDMContext", "UserContext", "removeContextMenus", "removeContextMenuPatch", "init_contextMenus", "__esmMin", "init_react", "init_ContextMenu", "init_common", "init_settings", "children", "props", "container", "findGroupChildrenByChildId", "idx", "c", "pinDms_default", "init_pinDms", "__esmMin", "init_react", "init_constants", "init_types", "init_contextMenus", "init_settings", "definePlugin", "Devs", "settings", "addContextMenus", "removeContextMenus", "channelIds", "pinnedDms", "usePinnedDms", "channels", "idx", "getPinAt", "isPinned", "sortedSnapshot", "channelId", "rowHeight", "padding", "preRenderedChildren", "originalOffset", "snapshotArray", "plainFolderIcon_default", "init_plainFolderIcon", "__esmMin", "init_react", "init_constants", "init_types", "definePlugin", "Devs", "MemberListDecorators_exports", "__export", "__getDecorators", "addDecorator", "decorators", "removeDecorator", "identifier", "decorator", "onlyIn", "props", "isInGuild", "decoratorObj", "init_MemberListDecorators", "__esmMin", "init_react", "MessageDecorations_exports", "__export", "__addDecorationsToMessage", "addDecoration", "decorations", "removeDecoration", "identifier", "decoration", "props", "init_MessageDecorations", "__esmMin", "init_react", "Icon", "path", "opts", "color", "tooltip", "small", "VencordCreateElement", "Tooltip", "tooltipProps", "SessionsStore", "Icons", "StatusUtils", "PlatformIcon", "getStatus", "PlatformIndicator", "badge", "indicatorLocations", "platformIndicators_default", "init_platformIndicators", "__esmMin", "init_react", "init_Badges", "init_MemberListDecorators", "init_MessageDecorations", "init_Settings", "init_ErrorBoundary", "init_constants", "init_types", "init_webpack", "init_common", "findStoreLazy", "findByPropsLazy", "platform", "status", "id", "PresenceStore", "user", "wantMargin", "wantTopMargin", "UserStore", "sessions", "sortedSessions", "a", "b", "ownStatus", "acc", "curr", "clientStatuses", "icons", "p", "userInfo", "addDecorator", "props", "ErrorBoundary_default", "removeDecorator", "addBadge", "removeBadge", "addDecoration", "removeDecoration", "definePlugin", "Devs", "settings", "Settings", "displayMode", "key", "value", "_", "userStatus", "isMobile", "PreviewButton", "chatBoxProps", "isEmpty", "attachments", "channelId", "SelectedChannelStore", "draft", "useStateFromStores", "DraftStore", "getDraft", "hasAttachments", "UploadStore", "VencordCreateElement", "Tooltip", "tooltipProps", "Button", "sendBotMessage", "UserStore", "getAttachments", "ButtonLooks", "ButtonWrapperClasses", "getImageBox", "previewMessage_default", "init_previewMessage", "__esmMin", "init_react", "init_Commands", "init_ErrorBoundary", "init_constants", "init_types", "init_webpack", "init_common", "findByPropsLazy", "url", "res", "img", "upload", "isImage", "filename", "spoiler", "file", "attachment", "generateId", "box", "definePlugin", "Devs", "ErrorBoundary_default", "PronounsAboutComponent", "VencordCreateElement", "React", "Forms", "Link", "init_PronounsAboutComponent", "__esmMin", "init_react", "init_Link", "init_common", "settings", "init_settings", "__esmMin", "init_react", "init_Settings", "init_types", "init_pronoundbUtils", "definePluginSettings", "PronounMapping", "init_types", "__esmMin", "init_react", "getDiscordPronouns", "id", "useGlobalProfile", "globalPronouns", "UserProfileStore", "getCurrentChannel", "useFormattedPronouns", "discordPronouns", "NewLineRe", "result", "useAwaiter", "fetchPronouns", "getCachedPronouns", "e", "settings", "formatPronouns", "useProfilePronouns", "pronouns", "UserStore", "EmptyPronouns", "cached", "cache", "res", "requestQueue", "bulkFetch", "bulkFetchPronouns", "ids", "params", "VENCORD_USER_AGENT", "dummyPronouns", "pronounsFormat", "Settings", "PronounMapping", "init_pronoundbUtils", "__esmMin", "init_react", "init_Settings", "init_constants", "init_debounce", "init_discord", "init_common", "init_settings", "init_types", "debounce", "c", "shouldShow", "message", "settings", "AUTO_MODERATION_ACTION", "UserStore", "PronounsChatComponent", "result", "useFormattedPronouns", "VencordCreateElement", "classes", "styles", "PronounsChatComponentWrapper", "CompactPronounsChatComponentWrapper", "CompactPronounsChatComponent", "init_PronounsChatComponent", "__esmMin", "init_react", "init_ErrorBoundary", "init_misc", "init_webpack", "init_common", "init_pronoundbUtils", "init_settings", "findByPropsLazy", "ErrorBoundary_default", "PRONOUN_TOOLTIP_PATCH", "pronoundb_default", "init_pronoundb", "__esmMin", "init_react", "init_", "init_constants", "init_types", "init_PronounsAboutComponent", "init_PronounsChatComponent", "init_pronoundbUtils", "init_settings", "definePlugin", "Devs", "settings", "PronounsAboutComponent", "PronounsChatComponentWrapper", "CompactPronounsChatComponentWrapper", "useProfilePronouns", "quickMention_default", "init_quickMention", "__esmMin", "init_react", "init_MessagePopover", "init_constants", "init_discord", "init_types", "init_common", "definePlugin", "Devs", "addButton", "msg", "channel", "ChannelStore", "PermissionStore", "PermissionsBits", "insertTextIntoChatInputBox", "removeButton", "VencordCreateElement", "calculateIdx", "messages", "id", "idx", "m", "onStartEdit", "channelId", "messageId", "_isQuickEdit", "meId", "UserStore", "MessageStore", "editIdx", "onCreatePendingReply", "message", "_isQuickReply", "replyIdx", "onKeydown", "isUp", "isCtrl", "isAltOrMeta", "nextEdit", "nextReply", "jumpIfOffScreen", "element", "vh", "rect", "Kangaroo", "getNextMessage", "isReply", "SelectedChannelStore", "mutate", "i", "findNextNonDeleted", "shouldMention", "enabled", "userList", "shouldPingListed", "Settings", "shouldPing", "settings", "currChannel", "ChannelStore", "PermissionStore", "PermissionsBits", "FluxDispatcher", "channel", "isMac", "quickReply_default", "onDeletePendingReply", "onEndEdit", "init_quickReply", "__esmMin", "init_react", "init_Settings", "init_constants", "init_types", "init_webpack", "init_common", "findByPropsLazy", "definePluginSettings", "definePlugin", "Devs", "ERROR_CODES", "reactErrorDecoder_default", "init_reactErrorDecoder", "__esmMin", "init_react", "init_constants", "init_types", "init_common", "definePlugin", "Devs", "_", "func", "original", "CODES_URL", "React", "res", "e", "code", "args", "index", "arg", "ServerList_exports", "__export", "ServerListRenderPosition", "addServerListElement", "removeServerListElement", "renderAll", "getRenderFunctions", "position", "renderFunctionsAbove", "renderFunctionsIn", "renderFunction", "logger", "init_ServerList", "__esmMin", "init_react", "init_Logger", "Logger", "ret", "e", "onClick", "channels", "GuildStore", "guild", "GuildChannelStore", "c", "ReadStateStore", "FluxDispatcher", "ReadAllButton", "readAllNotificationsButton_default", "init_readAllNotificationsButton", "__esmMin", "init_react", "init_ServerList", "init_constants", "init_types", "init_common", "VencordCreateElement", "Button", "definePlugin", "Devs", "addServerListElement", "removeServerListElement", "settings_default", "init_settings", "__esmMin", "init_react", "init_Settings", "init_types", "definePluginSettings", "init_types", "__esmMin", "init_react", "runMigrations", "DataStore", "syncAndRunChecks", "oldGuilds", "oldGroups", "oldFriends", "guildsKey", "groupsKey", "friendsKey", "syncGuilds", "syncGroups", "syncFriends", "settings_default", "id", "group", "groups", "notify", "guild", "guilds", "friends", "user", "UserUtils", "getUniqueUsername", "openUserProfile", "RelationshipStore", "text", "icon", "onClick", "Notices", "showNotification", "getGuild", "deleteGuild", "me", "UserStore", "name", "GuildStore", "GuildMemberStore", "getGroup", "deleteGroup", "type", "rawRecipients", "ChannelStore", "r", "relationShips", "init_utils", "__esmMin", "init_react", "init_api", "init_Notifications", "init_discord", "init_common", "init_settings", "init_types", "onRelationshipRemove", "type", "id", "manuallyRemovedFriend", "user", "UserUtils", "settings_default", "notify", "getUniqueUsername", "openUserProfile", "onGuildDelete", "unavailable", "manuallyRemovedGuild", "deleteGuild", "guild", "getGuild", "onChannelDelete", "manuallyRemovedGroup", "deleteGroup", "group", "getGroup", "removeFriend", "removeGuild", "removeGroup", "init_functions", "__esmMin", "init_react", "init_discord", "init_common", "init_settings", "init_types", "init_utils", "relationshipNotifier_default", "init_relationshipNotifier", "__esmMin", "init_react", "init_constants", "init_types", "init_functions", "init_settings", "init_utils", "definePlugin", "Devs", "settings_default", "syncGuilds", "onGuildDelete", "syncGroups", "onChannelDelete", "syncFriends", "onRelationshipRemove", "syncAndRunChecks", "removeFriend", "removeGroup", "removeGuild", "SpoilerClasses", "MessagesClasses", "revealAllSpoilers_default", "init_revealAllSpoilers", "__esmMin", "init_react", "init_constants", "init_types", "init_webpack", "findByPropsLazy", "definePlugin", "Devs", "_", "event", "ctrlKey", "shiftKey", "target", "spoilerContent", "hidden", "messagesWrapper", "parent", "spoiler", "search", "src", "engine", "makeSearchItem", "VencordCreateElement", "Menu", "Engines", "i", "key", "Flex", "OpenExternalIcon", "e", "messageContextMenuPatch", "imageContextMenuPatch", "reverseImageSearch_default", "init_reverseImageSearch", "__esmMin", "init_react", "init_ContextMenu", "init_Flex", "init_Icons", "init_constants", "init_types", "init_common", "children", "props", "findGroupChildrenByChildId", "definePlugin", "Devs", "m", "target", "addContextMenuPatch", "removeContextMenuPatch", "settings", "roleColorEverywhere_default", "init_roleColorEverywhere", "__esmMin", "init_react", "init_Settings", "init_constants", "init_types", "init_common", "definePluginSettings", "definePlugin", "Devs", "userId", "channelId", "guildId", "ChannelStore", "GuildMemberStore", "ids", "colorString", "id", "count", "title", "label", "role", "GuildStore", "VencordCreateElement", "messageUtils", "messageContextMenuPatch", "searchReply_default", "init_searchReply", "__esmMin", "init_react", "init_ContextMenu", "init_Icons", "init_constants", "init_types", "init_webpack", "init_common", "findByPropsLazy", "children", "message", "SelectedChannelStore", "channel", "ChannelStore", "PermissionStore", "PermissionsBits", "dmGroup", "findGroupChildrenByChildId", "child", "pinIndex", "c", "VencordCreateElement", "Menu", "i18n", "ReplyIcon", "e", "serverGroup", "definePlugin", "Devs", "addContextMenuPatch", "removeContextMenuPatch", "secretRingTone_default", "init_secretRingTone", "__esmMin", "init_react", "init_constants", "init_types", "definePlugin", "Devs", "parseTime", "time", "cleanTime", "ms", "PickerModal", "rootProps", "close", "value", "setValue", "useState", "format", "setFormat", "formatTimestamp", "formatted", "rendered", "useMemo", "Parser", "VencordCreateElement", "ModalRoot", "ModalHeader", "cl", "Forms", "ModalCloseButton", "ModalContent", "e", "getTheme", "Select", "Formats", "m", "v", "o", "Margins", "ModalFooter", "Button", "insertTextIntoChatInputBox", "settings", "sendTimestamps_default", "init_sendTimestamps", "__esmMin", "init_react", "init_", "init_MessageEvents", "init_Settings", "init_Styles", "init_constants", "init_discord", "init_margins", "init_modal", "init_types", "init_common", "definePluginSettings", "classNameFactory", "definePlugin", "Devs", "addPreSendListener", "_", "msg", "removePreSendListener", "chatBoxProps", "Tooltip", "onMouseEnter", "onMouseLeave", "ButtonLooks", "ButtonWrapperClasses", "key", "openModal", "props", "closeModal", "samples", "s", "VencordFragment", "FriendsIndicator", "forceUpdateFriendCount", "useForceUpdater", "VencordCreateElement", "onlineFriends", "ServersIndicator", "forceUpdateGuildCount", "guildCount", "handlePresenceUpdate", "relations", "RelationshipStore", "id", "PresenceStore", "handleGuildUpdate", "GuildStore", "serverListIndicators_default", "init_serverListIndicators", "__esmMin", "init_react", "init_ServerList", "init_Settings", "init_ErrorBoundary", "init_constants", "init_types", "init_common", "definePlugin", "Devs", "mode", "Settings", "ErrorBoundary_default", "addServerListElement", "removeServerListElement", "openGuildProfileModal", "guild", "openModal", "props", "VencordCreateElement", "ModalRoot", "GuildProfileModal", "renderTimestamp", "timestamp", "Timestamp", "moment", "friendCount", "setFriendCount", "useState", "blockedCount", "setBlockedCount", "useEffect", "fetched", "currentTab", "setCurrentTab", "bannerUrl", "IconUtils", "iconUrl", "cl", "openImageModal", "classes", "IconClasses", "Forms", "TabBar", "ServerInfoTab", "FriendsTab", "BlockedUsersTab", "Owner", "guildId", "owner", "guildAvatar", "GuildMemberStore", "ownerAvatarUrl", "Parser", "useAwaiter", "UserUtils", "Fields", "SnowflakeUtils", "GuildChannelStore", "name", "node", "setCount", "UserList", "RelationshipStore", "blockedIds", "id", "type", "ids", "missing", "members", "useStateFromStores", "old", "curr", "FluxDispatcher", "ScrollerThin", "FriendRow", "UserStore", "PresenceStore", "openUserProfile", "init_GuildProfileModal", "__esmMin", "init_react", "init_", "init_Styles", "init_discord", "init_misc", "init_modal", "init_webpack", "init_common", "findByPropsLazy", "findExportedComponentLazy", "classNameFactory", "Patch", "serverProfile_default", "init_serverProfile", "__esmMin", "init_react", "init_ContextMenu", "init_constants", "init_types", "init_common", "init_GuildProfileModal", "children", "guild", "findGroupChildrenByChildId", "VencordCreateElement", "Menu", "openGuildProfileModal", "definePlugin", "Devs", "addContextMenuPatch", "removeContextMenuPatch", "previewExample_default", "init_previewExample", "__esmMin", "init_react", "require_eventemitter3", "__commonJSMin", "exports", "module", "init_react", "has", "prefix", "Events", "EE", "fn", "context", "once", "addListener", "emitter", "event", "listener", "evt", "clearEvent", "EventEmitter", "names", "events", "name", "handlers", "l", "ee", "listeners", "a1", "a2", "a3", "a4", "a5", "len", "args", "i", "length", "j", "require_channel", "__commonJSMin", "exports", "init_react", "eventemitter3_1", "ipcPrefix", "kEdgeCreate", "ChannelPort", "sourceName", "event", "data", "pipeName", "listenerMap", "listener", "name", "existingPipe", "pipe", "fn", "Channel", "id", "edge", "message", "logger", "prevEdge", "newEdgeIds", "edgeId", "edgeIds", "callback", "caller", "error", "index", "arr", "destinaton", "destination", "resolve", "checkEdge", "messageData", "opts", "nonce", "promise", "reject", "timeout", "require_rpc", "__commonJSMin", "exports", "init_react", "RemoteHost", "channel", "spec", "name", "fn", "input", "RemoteClient", "hostName", "output", "require_worker", "__commonJSMin", "exports", "init_react", "channel_1", "rpc_1", "createWorkerHost", "name", "spec", "channel", "event", "data", "callback", "WorkerClient", "hostName", "source", "workerOpts", "blob", "worker", "listener", "ev", "evName", "require_ipc", "__commonJSMin", "exports", "init_react", "__createBinding", "o", "m", "k", "k2", "desc", "__exportStar", "p", "dispatchTheme", "state", "currentTheme", "themeSetters", "setTheme", "useTheme", "init_useTheme", "__esmMin", "init_react", "init_common", "React", "resolveLang", "idOrAlias", "languages", "lang", "aliasCache", "VPC_REPO", "VPC_REPO_COMMIT", "vpcRepoAssets", "vpcRepoGrammar", "vpcRepoLanguages", "loadLanguages", "getGrammar", "init_languages", "__esmMin", "init_react", "fileName", "langsJson", "res", "loadedLanguages", "SHIKI_REPO", "SHIKI_REPO_COMMIT", "shikiRepoTheme", "themes", "init_themes", "__esmMin", "init_react", "name", "import_ipc", "themeUrls", "resolveClient", "shiki", "init_shiki", "__esmMin", "init_react", "init_dependencies", "init_useTheme", "init_languages", "init_themes", "themes", "languages", "resolve", "initThemeUrl", "workerBlob", "shikiWorkerSrc", "res", "client", "themeUrl", "loadLanguages", "shikiOnigasmSrc", "themeData", "dispatchTheme", "langId", "lang", "resolveLang", "getGrammar", "code", "devicon_default", "init_devicon", "__esmMin", "init_react", "init_types", "__esmMin", "init_react", "themeNames", "settings", "init_settings", "__esmMin", "init_react", "init_Settings", "init_Styles", "init_misc", "init_text", "init_types", "init_shiki", "init_themes", "init_devicon", "themes", "definePluginSettings", "themeName", "wordsToTitle", "wordsFromPascal", "shiki", "value", "newValue", "disableStyle", "devicon_default", "enableStyle", "url", "parseUrl", "useShikiSettings", "settingKeys", "overrides", "settings", "isLoading", "setLoading", "React", "withOverrides", "themeUrl", "willChangeTheme", "shiki", "noOverrides", "init_useShikiSettings", "__esmMin", "init_react", "init_common", "init_shiki", "init_settings", "hex2Rgb", "hex", "c", "init_color", "__esmMin", "init_react", "cl", "shouldUseHljs", "init_misc", "__esmMin", "init_react", "init_Styles", "init_common", "init_languages", "init_types", "classNameFactory", "lang", "tryHljs", "hljsLang", "hljs", "langName", "resolveLang", "useCopyCooldown", "cooldown", "copyCooldown", "setCopyCooldown", "React", "copy", "text", "Clipboard", "init_useCopyCooldown", "__esmMin", "init_react", "init_common", "CopyButton", "content", "props", "copyCooldown", "copy", "useCopyCooldown", "VencordCreateElement", "init_CopyButton", "__esmMin", "init_react", "init_useCopyCooldown", "ButtonRow", "content", "theme", "buttons", "Clipboard", "VencordCreateElement", "CopyButton", "cl", "init_ButtonRow", "__esmMin", "init_react", "init_common", "init_misc", "init_CopyButton", "Code", "init_Code", "__esmMin", "init_react", "init_common", "init_misc", "theme", "useHljs", "lang", "content", "tokens", "lines", "hljsHtml", "hljs", "line", "i", "VencordCreateElement", "VencordFragment", "color", "fontStyle", "codeTableRows", "cl", "Header", "langName", "useDevIcon", "shikiLang", "VencordCreateElement", "cl", "VencordFragment", "init_Header", "__esmMin", "init_react", "init_types", "init_misc", "createHighlighter", "Highlighter", "init_Highlighter", "__esmMin", "init_react", "init_ErrorBoundary", "init_common", "init_languages", "init_shiki", "init_useShikiSettings", "init_useTheme", "init_color", "init_misc", "init_ButtonRow", "init_Code", "init_Header", "props", "VencordCreateElement", "cl", "ErrorBoundary_default", "lang", "content", "isPreview", "tempSettings", "tryHljs", "useDevIcon", "bgOpacity", "useShikiSettings", "currentThemeId", "currentTheme", "useTheme", "shikiLang", "resolveLang", "useHljs", "shouldUseHljs", "rootRef", "isIntersecting", "useIntersection", "tokens", "useAwaiter", "shiki", "themeBase", "langName", "hljs", "hex2Rgb", "Header", "Code", "ButtonRow", "styles", "clearStyles", "init_createStyle", "__esmMin", "init_react", "style", "shikiCodeblocks_default", "init_shikiCodeblocks", "__esmMin", "init_react", "init_", "init_Styles", "init_constants", "init_types", "init_previewExample", "init_shiki", "init_Highlighter", "init_devicon", "init_settings", "init_createStyle", "definePlugin", "Devs", "settings", "enableStyle", "devicon_default", "shiki", "clearStyles", "tempSettings", "createHighlighter", "previewExample_default", "lang", "content", "showAllMessageButtons_default", "init_showAllMessageButtons", "__esmMin", "init_react", "init_constants", "init_types", "definePlugin", "Devs", "VerifiedIcon", "color", "useToken", "ColorMap", "forcedIconColor", "VencordCreateElement", "VerifiedIconComponent", "i18n", "init_VerifiedIcon", "__esmMin", "init_react", "init_webpack", "init_common", "findLazy", "m", "findComponentByCodeLazy", "ConnectionsComponent", "id", "theme", "profile", "UserProfileStore", "connections", "VencordCreateElement", "Section", "Text", "Flex", "getSpacingPx", "settings", "connection", "CompactConnectionComponent", "platform", "platforms", "platformHooks", "url", "img", "TooltipIcon", "LinkIcon", "CopyIcon", "Tooltip", "VerifiedIcon", "tooltipProps", "e", "copyWithToast", "ThemeStore", "getTheme", "profilePopoutComponent", "profilePanelComponent", "showConnections_default", "init_showConnections", "__esmMin", "init_react", "init_", "init_Settings", "init_ErrorBoundary", "init_Flex", "init_Icons", "init_constants", "init_misc", "init_types", "init_webpack", "init_common", "init_VerifiedIcon", "findComponentByCodeLazy", "findStoreLazy", "findByPropsLazy", "findByCodeLazy", "spacing", "definePluginSettings", "ErrorBoundary_default", "user", "displayProfile", "definePlugin", "Devs", "HiddenChannelLockScreen", "channel", "viewAllowedUsersAndRoles", "setViewAllowedUsersAndRoles", "useState", "settings", "permissions", "setPermissions", "type", "topic", "lastMessageId", "defaultForumLayout", "lastPinTimestamp", "defaultAutoArchiveDuration", "availableTags", "channelId", "rateLimitPerUser", "defaultThreadRateLimitPerUser", "defaultSortOrder", "defaultReactionEmoji", "bitrate", "rtcRegion", "videoQualityMode", "permissionOverwrites", "guild_id", "useEffect", "membersToFetch", "guildOwnerId", "GuildStore", "GuildMemberStore", "userId", "FluxDispatcher", "Settings", "sortPermissionOverwrites", "overwrite", "VencordCreateElement", "ChatScrollClasses", "ChatClasses", "HiddenChannelLogo", "Text", "PermissionStore", "PermissionsBits", "ChannelTypesToChannelNames", "Tooltip", "onMouseLeave", "onMouseEnter", "Parser", "Timestamp", "moment", "SnowflakeUtils", "formatDuration", "VideoQualityModesToNames", "ForumLayoutTypesToNames", "SortOrderTypesToNames", "EmojiParser", "EmojiStore", "EmojiUtils", "tag", "TagComponent", "RolesAndUsersPermissions_default", "v", "ChannelBeginHeader", "HiddenChannelLockScreen_default", "init_HiddenChannelLockScreen", "__esmMin", "init_react", "init_Settings", "init_ErrorBoundary", "init_text", "init_webpack", "init_common", "init_RolesAndUsersPermissions", "init_utils", "init_showHiddenChannels", "findByPropsLazy", "findComponentByCodeLazy", "findComponentLazy", "m", "code", "ErrorBoundary_default", "ChannelListClasses", "settings", "showHiddenChannels_default", "init_showHiddenChannels", "__esmMin", "init_react", "init_", "init_Settings", "init_ErrorBoundary", "init_constants", "init_patches", "init_types", "init_webpack", "init_common", "init_HiddenChannelLockScreen", "findByPropsLazy", "definePluginSettings", "definePlugin", "Devs", "_", "rest", "defaultRenderLevel", "channel", "m", "func", "muted", "otherClasses", "isMuted", "mutedClassExpression", "unread", "pushNotificationButtonExpression", "isLurking", "channelId", "permCheck", "PermissionsBits", "component", "canonicalizeMatch", "props", "amount", "inCall", "channels", "checkConnect", "ChannelStore", "PermissionStore", "shouldIncludeHidden", "res", "key", "maybeObjChannels", "objChannel", "guildId", "prev", "index", "originalArray", "everyoneRole", "role", "VencordCreateElement", "HiddenChannelLockScreen_default", "ErrorBoundary_default", "Tooltip", "onMouseLeave", "onMouseEnter", "settings", "showMeYourName_default", "init_showMeYourName", "__esmMin", "init_react", "init_", "init_Settings", "init_constants", "init_types", "definePluginSettings", "definePlugin", "Devs", "author", "message", "isRepliedMessage", "withMentionPrefix", "userOverride", "user", "username", "nick", "prefix", "VencordCreateElement", "VencordFragment", "showTimeouts_default", "init_showTimeouts", "__esmMin", "init_react", "init_constants", "init_types", "definePlugin", "Devs", "SilentMessageToggle", "chatBoxProps", "enabled", "setEnabled", "React", "lastState", "setEnabledValue", "value", "settings", "listener", "_", "message", "addPreSendListener", "removePreSendListener", "VencordCreateElement", "Tooltip", "tooltipProps", "Button", "ButtonLooks", "ButtonWrapperClasses", "VencordFragment", "silentMessageToggle_default", "init_silentMessageToggle", "__esmMin", "init_react", "init_MessageEvents", "init_Settings", "init_ErrorBoundary", "init_constants", "init_types", "init_common", "definePluginSettings", "newValue", "definePlugin", "Devs", "ErrorBoundary_default", "SilentTypingToggle", "chatBoxProps", "isEnabled", "settings", "toggle", "VencordCreateElement", "Tooltip", "tooltipProps", "Button", "ButtonLooks", "ButtonWrapperClasses", "silentTyping_default", "init_silentTyping", "__esmMin", "init_react", "init_Commands", "init_Settings", "init_ErrorBoundary", "init_constants", "init_types", "init_common", "definePluginSettings", "definePlugin", "Devs", "args", "ctx", "findOption", "sendBotMessage", "channelId", "FluxDispatcher", "ErrorBoundary_default", "settings", "sortFriendRequests_default", "init_sortFriendRequests", "__esmMin", "init_react", "init_Settings", "init_Flex", "init_constants", "init_types", "init_common", "definePluginSettings", "definePlugin", "Devs", "_", "subtext", "user", "row", "RelationshipStore", "text", "since", "VencordCreateElement", "Flex", "hoverOnly_default", "init_hoverOnly", "__esmMin", "init_react", "SpotifyStore", "init_SpotifyStore", "__esmMin", "init_react", "init_Settings", "init_webpack", "init_common", "proxyLazyWebpack", "Store", "Flux", "SpotifySocket", "findByProps", "SpotifyUtils", "API_BASE", "path", "url", "Settings", "_", "idx", "pos", "p", "percent", "playing", "state", "ms", "e", "method", "route", "data", "socket", "store", "FluxDispatcher", "devices", "d", "msToHuman", "ms", "minutes", "m", "s", "Svg", "path", "label", "VencordCreateElement", "classes", "cl", "Button", "props", "CopyContextMenu", "name", "copyId", "openId", "Menu", "FluxDispatcher", "copyWithToast", "LinkIcon", "SpotifyStore", "OpenExternalIcon", "makeContextMenu", "e", "ContextMenuApi", "Controls", "isPlaying", "shuffle", "repeat", "useStateFromStores", "nextRepeat", "repeatClassName", "Flex", "Shuffle", "SkipPrev", "PauseButton", "PlayButton", "SkipNext", "Repeat", "SeekBar", "duration", "storePosition", "isSettingPosition", "position", "setPosition", "useState", "useEffect", "interval", "p", "Forms", "v", "seek", "AlbumContextMenu", "track", "volume", "openImageModal", "ImageIcon", "ref", "debounce", "makeLinkProps", "condition", "Info", "img", "coverExpanded", "setCoverExpanded", "VencordFragment", "a", "i", "React", "Player", "prev", "next", "device", "shouldHide", "setShouldHide", "timeout", "ErrorBoundary_default", "init_PlayerComponent", "__esmMin", "init_react", "init_", "init_ErrorBoundary", "init_Flex", "init_Icons", "init_debounce", "init_discord", "init_misc", "init_common", "init_SpotifyStore", "className", "toggleHoverControls", "value", "enableStyle", "disableStyle", "hoverOnly_default", "spotifyControls_default", "init_spotifyControls", "__esmMin", "init_react", "init_Settings", "init_Styles", "init_constants", "init_types", "init_hoverOnly", "init_PlayerComponent", "definePlugin", "Devs", "v", "Settings", "VencordCreateElement", "Player", "settings", "spotifyCrack_default", "init_spotifyCrack", "__esmMin", "init_react", "init_Settings", "init_constants", "init_types", "definePluginSettings", "definePlugin", "Devs", "m", "req", "sendMessage", "channelId", "message", "reply", "PendingReplyStore", "MessageActions", "FluxDispatcher", "Spotify", "spotifyShareCommands_default", "init_spotifyShareCommands", "__esmMin", "init_react", "init_Commands", "init_constants", "init_types", "init_webpack", "init_common", "findByPropsLazy", "definePlugin", "Devs", "_", "ctx", "track", "sendBotMessage", "StartupTimingPage_exports", "__export", "StartupTimingPage_default", "TimerItem", "emoji", "prefix", "log", "delta", "instance", "VencordCreateElement", "React", "TimingSection", "title", "logs", "traceEnd", "startTime", "lastTimestamp", "timings", "timestamp", "sinceStart", "sinceLast", "Forms", "AppStartPerformance", "i", "ServerTrace", "trace", "lines", "Flex", "line", "StartupTimingPage", "serverTrace", "g", "init_StartupTimingPage", "__esmMin", "init_react", "init_ErrorBoundary", "init_Flex", "init_webpack", "init_common", "findByPropsLazy", "ErrorBoundary_default", "startupTimings_default", "init_startupTimings", "__esmMin", "init_react", "init_constants", "init_types", "definePlugin", "Devs", "LazyComponent", "settings", "superReactionTweaks_default", "init_superReactionTweaks", "__esmMin", "init_react", "init_Settings", "init_constants", "init_types", "definePluginSettings", "definePlugin", "Devs", "_", "rest", "isBurstReactionVariable", "isReactionIntention", "playingCount", "stringToRegex", "str", "match", "char", "pos", "flagArr", "renderFindError", "find", "e", "VencordCreateElement", "Input", "initialValue", "onChange", "placeholder", "value", "setValue", "useState", "TextInput", "TextReplace", "title", "rulesArray", "rulesKey", "update", "isRegexRules", "onClickRemove", "index", "DataStore", "key", "makeEmptyRule", "VencordFragment", "Forms", "Flex", "rule", "React", "Button", "DeleteIcon", "TextReplaceTesting", "applyRules", "content", "stringRules", "regexRules", "regex", "Logger", "STRING_RULES_KEY", "REGEX_RULES_KEY", "makeEmptyRuleArray", "settings", "TEXT_REPLACE_RULES_CHANNEL_ID", "textReplace_default", "init_textReplace", "__esmMin", "init_react", "init_api", "init_MessageEvents", "init_Settings", "init_Flex", "init_Icons", "init_constants", "init_Logger", "init_types", "init_common", "definePluginSettings", "useForceUpdater", "definePlugin", "Devs", "addPreSendListener", "channelId", "msg", "removePreSendListener", "themeAttributes_default", "init_themeAttributes", "__esmMin", "init_react", "init_constants", "init_types", "init_common", "definePlugin", "Devs", "props", "authorId", "UserStore", "timeBarAllActivities_default", "init_timeBarAllActivities", "__esmMin", "init_react", "init_constants", "init_types", "definePlugin", "Devs", "settings", "init_settings", "__esmMin", "init_react", "init_Settings", "init_types", "definePluginSettings", "Languages", "init_languages", "__esmMin", "init_react", "translate", "kind", "text", "sourceLang", "settings", "targetLang", "url", "res", "src", "sentences", "s", "cl", "init_utils", "__esmMin", "init_react", "init_Styles", "init_settings", "classNameFactory", "LanguageSelect", "settingsKey", "includeAuto", "currentValue", "settings", "options", "useMemo", "Languages", "value", "label", "VencordCreateElement", "Margins", "Forms", "SearchableSelect", "o", "v", "AutoTranslateToggle", "Switch", "TranslateModal", "rootProps", "ModalRoot", "ModalHeader", "cl", "ModalCloseButton", "ModalContent", "LanguageSettingKeys", "s", "init_TranslateModal", "__esmMin", "init_react", "init_margins", "init_modal", "init_common", "init_languages", "init_settings", "init_utils", "TranslateIcon", "height", "width", "className", "VencordCreateElement", "classes", "cl", "TranslateChatBarIcon", "slateProps", "autoTranslate", "settings", "toggle", "Tooltip", "onMouseEnter", "onMouseLeave", "Button", "ButtonLooks", "ButtonWrapperClasses", "e", "openModal", "props", "TranslateModal", "init_TranslateIcon", "__esmMin", "init_react", "init_misc", "init_modal", "init_common", "init_settings", "init_TranslateModal", "init_utils", "handleTranslate", "messageId", "data", "TranslationSetters", "Dismiss", "onDismiss", "VencordCreateElement", "cl", "TranslationAccessory", "message", "translation", "setTranslation", "useState", "useEffect", "TranslateIcon", "Parser", "Languages", "init_TranslationAccessory", "__esmMin", "init_react", "init_common", "init_languages", "init_TranslateIcon", "init_utils", "messageCtxPatch", "translate_default", "init_translate", "__esmMin", "init_react", "init_", "init_ContextMenu", "init_MessageAccessories", "init_MessageEvents", "init_MessagePopover", "init_ErrorBoundary", "init_constants", "init_types", "init_common", "init_settings", "init_TranslateIcon", "init_TranslationAccessory", "init_utils", "children", "message", "group", "findGroupChildrenByChildId", "c", "VencordCreateElement", "Menu", "TranslateIcon", "trans", "translate", "handleTranslate", "definePlugin", "Devs", "settings", "addAccessory", "props", "TranslationAccessory", "addContextMenuPatch", "addButton", "ChannelStore", "addPreSendListener", "_", "removePreSendListener", "removeContextMenuPatch", "removeButton", "removeAccessory", "slateProps", "ErrorBoundary_default", "TranslateChatBarIcon", "buildSeveralUsers", "a", "b", "count", "VencordCreateElement", "settings", "TypingUser", "typingTweaks_default", "init_typingTweaks", "__esmMin", "init_react", "init_Settings", "init_ErrorBoundary", "init_constants", "init_discord", "init_types", "init_common", "definePluginSettings", "ErrorBoundary_default", "user", "guildId", "openUserProfile", "GuildMemberStore", "Avatar", "RelationshipStore", "definePlugin", "Devs", "_", "users", "props", "children", "element", "c", "getDisplayName", "guildId", "userId", "user", "UserStore", "GuildMemberStore", "TypingIndicator", "channelId", "typingUsers", "useStateFromStores", "TypingStore", "old", "current", "oldKeys", "currentKeys", "key", "currentChannelId", "SelectedChannelStore", "ChannelStore", "settings", "UserGuildSettingsStore", "myId", "typingUsersArray", "id", "RelationshipStore", "tooltipText", "i18n", "Settings", "buildSeveralUsers", "VencordCreateElement", "Tooltip", "props", "ThreeDots", "typingIndicator_default", "init_typingIndicator", "__esmMin", "init_react", "init_Settings", "init_ErrorBoundary", "init_constants", "init_types", "init_webpack", "init_common", "init_typingTweaks", "findExportedComponentLazy", "findStoreLazy", "definePluginSettings", "definePlugin", "Devs", "ErrorBoundary_default", "unindent_default", "init_unindent", "__esmMin", "init_react", "init_MessageEvents", "init_constants", "init_types", "definePlugin", "Devs", "_", "content", "str", "minIndent", "prev", "curr", "msg", "m", "lines", "suffix", "addPreSendListener", "addPreEditListener", "_cid", "_mid", "removePreSendListener", "removePreEditListener", "EMBED_SUPPRESSED", "messageContextMenuPatch", "unsuppressEmbeds_default", "init_unsuppressEmbeds", "__esmMin", "init_react", "init_ContextMenu", "init_Icons", "init_constants", "init_types", "init_common", "children", "channel", "author", "embeds", "flags", "messageId", "isEmbedSuppressed", "hasEmbedPerms", "PermissionStore", "PermissionsBits", "UserStore", "menuGroup", "findGroupChildrenByChildId", "deleteIndex", "i", "VencordCreateElement", "Menu", "ImageVisible", "ImageInvisible", "RestAPI", "definePlugin", "Devs", "addContextMenuPatch", "removeContextMenuPatch", "settings", "urbanDictionary_default", "init_urbanDictionary", "__esmMin", "init_react", "init_Commands", "init_types", "init_Settings", "init_constants", "definePluginSettings", "definePlugin", "Devs", "args", "ctx", "query", "list", "response", "sendBotMessage", "definition", "prev", "curr", "linkify", "text", "_", "word", "error", "ChannelActions", "UserPopoutSection", "CONNECT", "VoiceChannelSection", "init_VoiceChannelSection", "__esmMin", "init_react", "init_", "init_webpack", "init_common", "findByPropsLazy", "findByCodeLazy", "channel", "label", "showHeader", "VencordCreateElement", "Forms", "Button", "PermissionStore", "Toasts", "VoiceStateStore", "settings", "VoiceChannelField", "userVoiceShow_default", "init_userVoiceShow", "__esmMin", "init_react", "init_Settings", "init_ErrorBoundary", "init_constants", "init_types", "init_webpack", "init_common", "init_VoiceChannelSection", "findStoreLazy", "definePluginSettings", "ErrorBoundary_default", "user", "channelId", "channel", "ChannelStore", "guild", "GuildStore", "result", "VencordCreateElement", "VoiceChannelSection", "definePlugin", "Devs", "isSelfUser", "UserStore", "usrbg_default", "init_usrbg", "__esmMin", "init_react", "BASE_URL", "data", "settings", "usrbg_default", "init_usrbg", "__esmMin", "init_react", "init_Settings", "init_Styles", "init_Link", "init_constants", "init_types", "definePluginSettings", "definePlugin", "Devs", "VencordCreateElement", "Link", "className", "participantUserId", "displayProfile", "user", "userId", "enableStyle", "res", "MentionWrapper", "data", "UserMention", "RoleMention", "parse", "props", "userId", "setUserId", "useState", "VencordCreateElement", "children", "mention", "id", "fetching", "UserStore", "fetch", "queue", "UserUtils", "e", "sleep", "validUser_default", "init_validUser", "__esmMin", "init_react", "init_ErrorBoundary", "init_constants", "init_misc", "init_Queue", "init_types", "init_common", "Queue", "definePlugin", "Devs", "ErrorBoundary_default", "timers", "vcDoubleClick_default", "init_vcDoubleClick", "__esmMin", "init_react", "init_constants", "init_types", "init_common", "definePlugin", "Devs", "find", "_", "onClick", "props", "channelId", "channel", "ChannelStore", "cb", "e", "id", "SelectedChannelStore", "data", "speak", "text", "settings", "Settings", "speech", "voice", "v", "Logger", "clean", "str", "replacer", "formatText", "user", "channel", "displayName", "nickname", "getTypeAndChannelId", "channelId", "oldChannelId", "isMe", "myLastChannelId", "playSample", "tempSettings", "type", "currentUser", "UserStore", "myGuildId", "SelectedGuildStore", "GuildMemberStore", "VoiceStateStore", "vcNarrator_default", "init_vcNarrator", "__esmMin", "init_react", "init_Settings", "init_ErrorCard", "init_constants", "init_Logger", "init_margins", "init_text", "init_types", "init_webpack", "init_common", "findByPropsLazy", "definePlugin", "Devs", "voiceStates", "myChanId", "SelectedChannelStore", "myId", "ChannelStore", "state", "userId", "id", "template", "chanId", "s", "event", "hasVoices", "hasEnglishVoices", "useMemo", "voices", "types", "k", "errorComponent", "VencordCreateElement", "ErrorCard", "error", "Forms", "VencordFragment", "Margins", "t", "Button", "wordsToTitle", "VencordPopout", "onClose", "pluginEntries", "plugin", "VencordCreateElement", "Menu", "text", "action", "key", "openNotificationLogModal", "Settings", "VencordPopoutIcon", "isShown", "VencordPopoutButton", "show", "setShow", "useState", "Popout", "_", "HeaderBarIcon", "v", "ToolboxFragmentWrapper", "children", "ErrorBoundary_default", "VencordFragment", "vencordToolbox_default", "init_vencordToolbox", "__esmMin", "init_react", "init_", "init_notificationLog", "init_Settings", "init_ErrorBoundary", "init_constants", "init_types", "init_webpack", "init_common", "findExportedComponentLazy", "definePlugin", "Devs", "openImage", "url", "format", "settings", "u", "originalUrl", "openImageModal", "BannerStore", "UserContext", "GuildContext", "viewIcons_default", "init_viewIcons", "__esmMin", "init_react", "init_ContextMenu", "init_Settings", "init_Icons", "init_constants", "init_discord", "init_types", "init_webpack", "init_common", "findByPropsLazy", "definePluginSettings", "n", "children", "user", "guildId", "memberAvatar", "GuildMemberStore", "VencordCreateElement", "Menu", "ImageIcon", "guild", "id", "icon", "banner", "definePlugin", "Devs", "addContextMenuPatch", "removeContextMenuPatch", "CodeBlock", "props", "VencordCreateElement", "CodeContainerClasses", "Parser", "init_CodeBlock", "__esmMin", "init_react", "init_webpack", "init_common", "findByPropsLazy", "sortObject", "obj", "k1", "k2", "cleanMessage", "msg", "clone", "key", "cloneAny", "a", "openViewRawModal", "json", "type", "msgContent", "openModal", "props", "VencordCreateElement", "ErrorBoundary_default", "ModalRoot", "ModalHeader", "Text", "ModalCloseButton", "closeModal", "ModalContent", "VencordFragment", "Forms", "CodeBlock", "Margins", "ModalFooter", "Flex", "Button", "copyWithToast", "openViewRawModalMessage", "msgJson", "MakeContextCallback", "name", "children", "lastChild", "p", "Menu", "CopyIcon", "settings", "viewRaw_default", "init_viewRaw", "__esmMin", "init_react", "init_ContextMenu", "init_MessagePopover", "init_Settings", "init_CodeBlock", "init_ErrorBoundary", "init_Flex", "init_constants", "init_margins", "init_misc", "init_modal", "init_types", "init_common", "definePluginSettings", "definePlugin", "Devs", "addButton", "handleClick", "handleContextMenu", "e", "ChannelStore", "addContextMenuPatch", "removeButton", "removeContextMenuPatch", "settings", "init_settings", "__esmMin", "init_react", "init_Settings", "init_types", "definePluginSettings", "Native", "init_DesktopRecorder", "__esmMin", "init_react", "init_common", "init_settings", "cl", "init_utils", "__esmMin", "init_react", "init_Styles", "classNameFactory", "VoiceMessage", "VoicePreview", "init_VoicePreview", "__esmMin", "init_react", "init_webpack", "init_utils", "findComponentByCodeLazy", "src", "waveform", "recording", "durationMs", "useTimer", "durationSeconds", "durationDisplay", "VencordCreateElement", "cl", "VoiceRecorderWeb", "init_WebRecorder", "__esmMin", "init_react", "init_common", "init_settings", "setAudioBlob", "onRecordingChange", "recording", "setRecording", "useState", "paused", "setPaused", "recorder", "setRecorder", "chunks", "setChunks", "changeRecording", "toggleRecording", "settings", "stream", "e", "VencordCreateElement", "VencordFragment", "Button", "sendAudio", "blob", "meta", "channelId", "SelectedChannelStore", "reply", "PendingReplyStore", "FluxDispatcher", "upload", "CloudUtils", "RestAPI", "SnowflakeUtils", "MessageActions", "showToast", "Toasts", "useObjectUrl", "url", "setUrl", "useState", "Modal", "modalProps", "isRecording", "setRecording", "setBlob", "blobUrl", "setBlobUrl", "useEffect", "useAwaiter", "EMPTY_META", "audioBuffer", "channelData", "bins", "lodash", "samplesPerBin", "binIdx", "squares", "sampleOffset", "sampleIdx", "maxBin", "ratio", "i", "VencordCreateElement", "ModalRoot", "ModalHeader", "Forms", "ModalContent", "cl", "VoiceRecorder", "Button", "file", "chooseFile", "VoicePreview", "ModalFooter", "OptionClasses", "voiceMessages_default", "ctxMenuPatch", "init_voiceMessages", "__esmMin", "init_react", "init_", "init_ContextMenu", "init_Icons", "init_constants", "init_modal", "init_types", "init_web", "init_webpack", "init_common", "init_DesktopRecorder", "init_settings", "init_utils", "init_VoicePreview", "init_WebRecorder", "findByPropsLazy", "findStoreLazy", "VoiceRecorderWeb", "definePlugin", "Devs", "settings", "addContextMenuPatch", "removeContextMenuPatch", "children", "props", "PermissionStore", "PermissionsBits", "Menu", "Microphone", "openModal", "fetchImage", "url", "res", "ctxMenuCallbacks", "settings", "webContextMenus_default", "init_webContextMenus", "__esmMin", "init_react", "init_Settings", "init_constants", "init_types", "init_web", "init_webpack", "init_common", "findByPropsLazy", "definePluginSettings", "definePlugin", "Devs", "img", "canvas", "data", "name", "file", "saveFile", "selection", "Clipboard", "ComponentDispatch", "clip", "type", "blob", "KeyBinds", "webKeybinds_default", "init_webKeybinds", "__esmMin", "init_react", "init_constants", "init_types", "init_webpack", "init_common", "findByPropsLazy", "definePlugin", "Devs", "SelectedGuildStore", "NavigationRouter", "ComponentDispatch", "FluxDispatcher", "SettingsRouter", "fetchReactions", "msg", "emoji", "type", "key", "RestAPI", "res", "FluxDispatcher", "sleep", "getReactionsWithQueue", "e", "cache", "reactions", "queue", "makeRenderMoreUsers", "users", "_label", "_count", "VencordCreateElement", "Tooltip", "u", "onMouseEnter", "onMouseLeave", "AvatarStyles", "handleClickAvatar", "event", "UserSummaryItem", "whoReacted_default", "init_whoReacted", "__esmMin", "init_react", "init_ErrorBoundary", "init_constants", "init_misc", "init_Queue", "init_types", "init_webpack", "init_common", "findComponentByCodeLazy", "findByPropsLazy", "Queue", "definePlugin", "Devs", "props", "ErrorBoundary_default", "message", "forceUpdate", "useForceUpdater", "React", "cb", "user", "ChannelStore", "value", "wikisearch_default", "init_wikisearch", "__esmMin", "init_react", "init_Commands", "init_constants", "init_types", "definePlugin", "Devs", "_", "ctx", "word", "findOption", "sendBotMessage", "dataSearchParams", "data", "response", "err", "altData", "res", "thumbnailData", "thumbnail", "sendMsgNotif", "titleString", "content", "message", "response", "result", "msgData", "settings", "calculateHeight", "cleanMessage", "Native", "sendOtherNotif", "shouldNotify", "channel", "currentUser", "UserStore", "MuteStore", "m", "XSLog", "xsOverlay_default", "init_xsOverlay", "__esmMin", "init_react", "init_Settings", "init_components", "init_constants", "init_Logger", "init_types", "init_webpack", "init_common", "findByPropsLazy", "Logger", "definePluginSettings", "makeRange", "definePlugin", "Devs", "call", "ChannelStore", "optimistic", "pingColor", "channelPingColor", "finalMsg", "guild", "GuildStore", "channelName", "e", "img", "a", "_", "id", "roleId", "role", "roleColor", "emoteMatches", "channelMatches", "eMatch", "cMatch", "channelId", "err", "plugins_default", "init_plugins", "__esmMin", "init_react", "init_badges", "init_commands", "init_contextMenu", "init_memberListDecorators", "init_messageAccessories", "init_messageDecorations", "init_messageEvents", "init_messagePopover", "init_notices", "init_serverList", "init_noTrack", "init_settings", "init_supportHelper", "init_alwaysAnimate", "init_alwaysTrust", "init_anonymiseFileNames", "init_arRPC", "init_banger", "init_betterFolders", "init_betterGifAltText", "init_betterNotes", "init_betterRoleDot", "init_betterUploadButton", "init_biggerStreamPreview", "init_blurNsfw", "init_callTimer", "init_clearURLs", "init_clientTheme", "init_colorSighted", "init_consoleShortcuts", "init_copyUserURLs", "init_crashHandler", "init_customRPC", "init_dearrow", "init_decor", "init_disableDMCallIdle", "init_emoteCloner", "init_experiments", "init_f8break", "init_fakeNitro", "init_fakeProfileThemes", "init_favEmojiFirst", "init_favGifSearch", "init_fixSpotifyEmbeds", "init_forceOwnerCrown", "init_friendInvites", "init_gameActivityToggle", "init_gifPaste", "init_greetStickerPicker", "init_hideAttachments", "init_iLoveSpam", "init_ignoreActivities", "init_imageZoom", "init_invisibleChat", "init_keepCurrentChannel", "init_lastfm", "init_loadingQuotes", "init_memberCount", "init_messageClickActions", "init_messageLinkEmbeds", "init_messageLogger", "init_messageTags", "init_moreCommands", "init_moreKaomoji", "init_moreUserTags", "init_moyai", "init_muteNewGuild", "init_mutualGroupDMs", "init_noBlockedMessages", "init_noDevtoolsWarning", "init_noF1", "init_noMosaic", "init_noPendingCount", "init_noProfileThemes", "init_noReplyMention", "init_noScreensharePreview", "init_noTypingAnimation", "init_noUnblockToJump", "init_normalizeMessageLinks", "init_notificationVolume", "init_nsfwGateBypass", "init_onePingPerDM", "init_oneko", "init_openInApp", "init_partyMode", "init_permissionFreeWill", "init_permissionsViewer", "init_petpet", "init_pictureInPicture", "init_pinDms", "init_plainFolderIcon", "init_platformIndicators", "init_previewMessage", "init_pronoundb", "init_quickMention", "init_quickReply", "init_reactErrorDecoder", "init_readAllNotificationsButton", "init_relationshipNotifier", "init_revealAllSpoilers", "init_reverseImageSearch", "init_roleColorEverywhere", "init_searchReply", "init_secretRingTone", "init_sendTimestamps", "init_serverListIndicators", "init_serverProfile", "init_shikiCodeblocks", "init_showAllMessageButtons", "init_showConnections", "init_showHiddenChannels", "init_showMeYourName", "init_showTimeouts", "init_silentMessageToggle", "init_silentTyping", "init_sortFriendRequests", "init_spotifyControls", "init_spotifyCrack", "init_spotifyShareCommands", "init_startupTimings", "init_superReactionTweaks", "init_textReplace", "init_themeAttributes", "init_timeBarAllActivities", "init_translate", "init_typingIndicator", "init_typingTweaks", "init_unindent", "init_unsuppressEmbeds", "init_urbanDictionary", "init_userVoiceShow", "init_usrbg", "init_validUser", "init_vcDoubleClick", "init_vcNarrator", "init_vencordToolbox", "init_viewIcons", "init_viewRaw", "init_voiceMessages", "init_webContextMenus", "init_webKeybinds", "init_whoReacted", "init_wikisearch", "init_xsOverlay", "badges_default", "commands_default", "contextMenu_default", "memberListDecorators_default", "messageAccessories_default", "messageDecorations_default", "messageEvents_default", "messagePopover_default", "notices_default", "serverList_default", "noTrack_default", "settings_default", "supportHelper_default", "alwaysAnimate_default", "alwaysTrust_default", "anonymiseFileNames_default", "arRPC_default", "banger_default", "betterFolders_default", "betterGifAltText_default", "betterNotes_default", "betterRoleDot_default", "betterUploadButton_default", "biggerStreamPreview_default", "blurNsfw_default", "callTimer_default", "clearURLs_default", "clientTheme_default", "colorSighted_default", "consoleShortcuts_default", "copyUserURLs_default", "crashHandler_default", "customRPC_default", "dearrow_default", "decor_default", "disableDMCallIdle_default", "emoteCloner_default", "experiments_default", "f8break_default", "fakeNitro_default", "fakeProfileThemes_default", "favEmojiFirst_default", "favGifSearch_default", "fixSpotifyEmbeds_default", "forceOwnerCrown_default", "friendInvites_default", "gameActivityToggle_default", "gifPaste_default", "greetStickerPicker_default", "hideAttachments_default", "iLoveSpam_default", "ignoreActivities_default", "imageZoom_default", "invisibleChat_default", "keepCurrentChannel_default", "lastfm_default", "loadingQuotes_default", "memberCount_default", "messageClickActions_default", "messageLinkEmbeds_default", "messageLogger_default", "messageTags_default", "moreCommands_default", "moreKaomoji_default", "moreUserTags_default", "moyai_default", "muteNewGuild_default", "mutualGroupDMs_default", "noBlockedMessages_default", "noDevtoolsWarning_default", "noF1_default", "noMosaic_default", "noPendingCount_default", "noProfileThemes_default", "noReplyMention_default", "noScreensharePreview_default", "noTypingAnimation_default", "noUnblockToJump_default", "normalizeMessageLinks_default", "notificationVolume_default", "nsfwGateBypass_default", "onePingPerDM_default", "oneko_default", "openInApp_default", "partyMode_default", "permissionFreeWill_default", "permissionsViewer_default", "petpet_default", "pictureInPicture_default", "pinDms_default", "plainFolderIcon_default", "platformIndicators_default", "previewMessage_default", "pronoundb_default", "quickMention_default", "quickReply_default", "reactErrorDecoder_default", "readAllNotificationsButton_default", "relationshipNotifier_default", "revealAllSpoilers_default", "reverseImageSearch_default", "roleColorEverywhere_default", "searchReply_default", "secretRingTone_default", "sendTimestamps_default", "serverListIndicators_default", "serverProfile_default", "shikiCodeblocks_default", "showAllMessageButtons_default", "showConnections_default", "showHiddenChannels_default", "showMeYourName_default", "showTimeouts_default", "silentMessageToggle_default", "silentTyping_default", "sortFriendRequests_default", "spotifyControls_default", "spotifyCrack_default", "spotifyShareCommands_default", "startupTimings_default", "superReactionTweaks_default", "textReplace_default", "themeAttributes_default", "timeBarAllActivities_default", "translate_default", "typingIndicator_default", "typingTweaks_default", "unindent_default", "unsuppressEmbeds_default", "urbanDictionary_default", "userVoiceShow_default", "usrbg_default", "validUser_default", "vcDoubleClick_default", "vcNarrator_default", "vencordToolbox_default", "viewIcons_default", "viewRaw_default", "voiceMessages_default", "webContextMenus_default", "webKeybinds_default", "whoReacted_default", "wikisearch_default", "xsOverlay_default", "Badges_exports", "__export", "BadgePosition", "_getBadges", "addBadge", "removeBadge", "badge", "ErrorBoundary_default", "Badges", "args", "badges", "donorBadges", "plugins_default", "init_Badges", "__esmMin", "init_react", "init_ErrorBoundary", "init_plugins", "api_exports", "__export", "Badges", "Commands", "ContextMenu", "DataStore", "MemberListDecorators", "MessageAccessories", "MessageDecorations", "MessageEvents", "MessagePopover", "Notices", "Notifications", "ServerList", "Settings", "Styles", "init_api", "__esmMin", "init_react", "init_Badges", "init_Commands", "init_ContextMenu", "init_DataStore", "init_MemberListDecorators", "init_MessageAccessories", "init_MessageDecorations", "init_MessageEvents", "init_MessagePopover", "init_Notices", "init_Notifications", "init_ServerList", "init_Settings", "init_Styles", "MessageEvents_exports", "Notices_exports", "Commands_exports", "DataStore_exports", "MessageAccessories_exports", "MessagePopover_exports", "Badges_exports", "ServerList_exports", "MessageDecorations_exports", "MemberListDecorators_exports", "Settings_exports", "Styles_exports", "Notifications_exports", "ContextMenu_exports", "Vencord_exports", "__export", "api_exports", "PlainSettings", "plugins_exports", "quickCss_exports", "Settings", "updater_exports", "utils_exports", "webpack_exports", "init_react", "init_api", "init_plugins", "utils_exports", "__export", "ChangeList", "Devs", "DevsById", "ImageModal", "LazyComponent", "Logger", "Margins", "ModalCloseButton", "ModalContent", "ModalFooter", "ModalHeader", "ModalRoot", "ModalSize", "Modals", "NoopComponent", "Queue", "REACT_GLOBAL", "SUPPORT_CHANNEL_ID", "Theme", "VENCORD_USER_AGENT", "WEBPACK_CHUNK", "canonicalizeDescriptor", "canonicalizeMatch", "canonicalizeReplace", "canonicalizeReplacement", "checkIntersecting", "classes", "closeAllModals", "closeModal", "copyWithToast", "debounce", "fetchUserProfile", "formatDuration", "getCurrentChannel", "getCurrentGuild", "getTheme", "getUniqueUsername", "git_hash_default", "git_remote_default", "humanFriendlyJoin", "identity", "insertTextIntoChatInputBox", "isMobile", "isNonNullish", "isObject", "isObjectEmpty", "isPluginDev", "isTruthy", "localStorage", "makeCodeblock", "makeLazy", "mergeDefaults", "onceDefined", "onlyOnce", "openImageModal", "openInviteModal", "openModal", "openModalLazy", "openPrivateChannel", "openUserProfile", "parseUrl", "proxyLazy", "sendMessage", "sleep", "useAwaiter", "useForceUpdater", "useIntersection", "useTimer", "wordsFromCamel", "wordsFromKebab", "wordsFromPascal", "wordsFromSnake", "wordsFromTitle", "wordsToCamel", "wordsToKebab", "wordsToPascal", "wordsToSnake", "wordsToTitle", "init_react", "init_ChangeList", "init_constants", "init_debounce", "init_discord", "init_guards", "init_lazy", "init_localStorage", "init_Logger", "init_margins", "init_misc", "init_modal", "init_react", "onceDefined", "target", "property", "callback", "propertyAsAny", "v", "init_onlyOnce", "init_patches", "init_Queue", "init_react", "init_text", "quickCss_exports", "__export", "toggle", "init_react", "init_Settings", "style", "themesStyle", "createStyle", "id", "initSystemValues", "values", "variables", "v", "k", "isEnabled", "css", "Settings", "initThemes", "themeLinks", "enabledThemes", "links", "localThemes", "theme", "link", "addSettingsListener", "init_updater", "webpack_exports", "__export", "common_exports", "LazyComponentWebpack", "_initWebpack", "_resolveReady", "addListener", "cache", "extract", "extractAndLoadChunks", "extractAndLoadChunksLazy", "filters", "find", "findAll", "findBulk", "findByCode", "findByCodeLazy", "findByProps", "findByPropsLazy", "findComponentByCode", "findComponentByCodeLazy", "findComponentLazy", "findExportedComponentLazy", "findLazy", "findModuleFactory", "findModuleId", "findStore", "findStoreLazy", "lazyWebpackSearchHistory", "listeners", "onceReady", "proxyLazyWebpack", "removeListener", "search", "subscriptions", "waitFor", "wreq", "init_react", "init_common", "init_webpack", "init_react", "init_constants", "init_Logger", "init_patches", "init_Tracer", "webpackChunk", "logger", "Logger", "WEBPACK_CHUNK", "_initWebpack", "patchPush", "v", "patchFactories", "webpackGlobal", "handlePush", "chunk", "err", "args", "factories", "subscriptions", "listeners", "patches", "id", "mod", "code", "originalMod", "patchedBy", "factory", "module", "exports", "require", "callback", "filter", "i", "patch", "executePatch", "traceFunction", "match", "replace", "previousMod", "previousCode", "replacement", "lastMod", "lastCode", "canonicalizeReplacement", "newCode", "init_types", "init_DataStore", "init_Notifications", "init_Settings", "init_plugins", "init_localStorage", "init_native", "init_settingsSync", "init_updater", "init_common", "syncSettings", "Settings", "get", "showNotification", "SettingsRouter", "localStorage", "putCloudSettings", "getCloudSettings", "relaunch", "init", "onceReady", "startAllPlugins", "checkForUpdates", "update", "err", "UpdateLogger"]
}