discord-message-transcript 1.3.0 → 1.3.1-dev.1.37

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "discord-message-transcript",
3
- "version": "1.3.0",
3
+ "version": "1.3.1-dev.1.37",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -44,11 +44,8 @@
44
44
  "url": "https://github.com/HenriqueMairesse/discord-message-transcript/issues"
45
45
  },
46
46
  "homepage": "https://github.com/HenriqueMairesse/discord-message-transcript#readme",
47
- "devDependencies": {
48
- "typescript": "^5.9.3"
49
- },
50
47
  "dependencies": {
51
- "discord-message-transcript-base": "1.3.0"
48
+ "discord-message-transcript-base": "1.3.1-dev.1.37"
52
49
  },
53
50
  "peerDependencies": {
54
51
  "discord.js": ">=14.19.0 <15"
@@ -57,7 +54,7 @@
57
54
  "access": "public"
58
55
  },
59
56
  "scripts": {
60
- "test": "echo \"Error: no test specified\" && exit 1",
61
- "build": "tsc"
57
+ "clean": "pnpm exec rimraf dist",
58
+ "build": "pnpm run clean && tsc"
62
59
  }
63
60
  }
@@ -1,3 +0,0 @@
1
- import { Client } from "discord.js";
2
- export declare function getClient(): Client | null;
3
- export declare function setClient(c: Client): void;
@@ -1,9 +0,0 @@
1
- let client = null;
2
- export function getClient() {
3
- return client;
4
- }
5
- export function setClient(c) {
6
- if (!client) {
7
- client = c;
8
- }
9
- }
@@ -1,3 +0,0 @@
1
- import { TopLevelComponent } from "discord.js";
2
- import { TranscriptOptions, JsonTopLevelComponent } from "../types/types";
3
- export declare function componentsToJson(components: TopLevelComponent[], options: TranscriptOptions): JsonTopLevelComponent[];
@@ -1,175 +0,0 @@
1
- import { ComponentType, ButtonStyle, SeparatorSpacingSize } from "discord.js";
2
- import { JsonComponentType, JsonButtonStyle, JsonSeparatorSpacingSize } from "../types/types";
3
- import { CustomError } from "./error";
4
- export function componentsToJson(components, options) {
5
- return components.filter(component => {
6
- return !(!options.includeV2Components && component.type != ComponentType.ActionRow);
7
- }).map(component => {
8
- switch (component.type) {
9
- case ComponentType.ActionRow: {
10
- const actionRowComponents = component.components.filter(c => {
11
- if (c.type == ComponentType.Button && !options.includeButtons) {
12
- return false;
13
- }
14
- if (c.type != ComponentType.Button && !options.includeComponents) {
15
- return false;
16
- }
17
- return true;
18
- }).map(c => {
19
- if (c.type === ComponentType.Button) {
20
- return {
21
- type: JsonComponentType.Button,
22
- style: mapButtonStyle(c.style),
23
- label: c.label,
24
- emoji: c.emoji ? {
25
- id: c.emoji.id ?? null,
26
- name: c.emoji.name ?? null,
27
- animated: c.emoji.animated ?? false,
28
- } : null,
29
- url: c.url,
30
- disabled: c.disabled,
31
- };
32
- }
33
- else if (c.type === ComponentType.StringSelect) {
34
- return {
35
- type: JsonComponentType.StringSelect,
36
- placeholder: c.placeholder,
37
- disabled: c.disabled,
38
- options: c.options.map(option => ({
39
- label: option.label,
40
- description: option.description ?? null,
41
- emoji: option.emoji ? {
42
- id: option.emoji.id ?? null,
43
- name: option.emoji.name ?? null,
44
- animated: option.emoji.animated ?? false,
45
- } : null,
46
- }))
47
- };
48
- }
49
- else {
50
- return {
51
- type: JsonComponentType.RoleSelect,
52
- placeholder: c.placeholder,
53
- disabled: c.disabled,
54
- };
55
- }
56
- });
57
- if (actionRowComponents.length > 0) {
58
- return {
59
- type: JsonComponentType.ActionRow,
60
- components: actionRowComponents,
61
- };
62
- }
63
- else {
64
- return null;
65
- }
66
- }
67
- case ComponentType.Container: {
68
- const newOptions = { ...options, includeComponents: true, includeButtons: true };
69
- return {
70
- type: JsonComponentType.Container,
71
- components: componentsToJson(component.components, newOptions).filter(isJsonComponentInContainer), // Impossible to send an component that can be used inside and return an component that can't be used inside
72
- hexAccentColor: component.hexAccentColor,
73
- spoiler: component.spoiler,
74
- };
75
- }
76
- case ComponentType.File: {
77
- return {
78
- type: JsonComponentType.File,
79
- fileName: component.data.name ?? null,
80
- size: component.data.size ?? 0,
81
- url: component.file.url,
82
- spoiler: component.spoiler,
83
- };
84
- }
85
- case ComponentType.MediaGallery: {
86
- return {
87
- type: JsonComponentType.MediaGallery,
88
- items: component.items.map(item => ({
89
- media: { url: item.media.url },
90
- spoiler: item.spoiler,
91
- })),
92
- };
93
- }
94
- case ComponentType.Section: {
95
- return {
96
- type: JsonComponentType.Section,
97
- accessory: (component.accessory.type === ComponentType.Button ? {
98
- type: JsonComponentType.Button,
99
- style: mapButtonStyle(component.accessory.style),
100
- label: component.accessory.label,
101
- emoji: component.accessory.emoji ? {
102
- id: component.accessory.emoji.id ?? null,
103
- name: component.accessory.emoji.name ?? null,
104
- animated: component.accessory.emoji.animated ?? false,
105
- } : null,
106
- url: component.accessory.url,
107
- disabled: component.accessory.disabled,
108
- } : {
109
- type: JsonComponentType.Thumbnail,
110
- media: {
111
- url: component.accessory.media.url,
112
- },
113
- spoiler: component.accessory.spoiler,
114
- }),
115
- components: component.components.map(c => ({
116
- type: JsonComponentType.TextDisplay,
117
- content: c.content,
118
- })),
119
- };
120
- }
121
- case ComponentType.Separator: {
122
- return {
123
- type: JsonComponentType.Separator,
124
- spacing: mapSeparatorSpacing(component.spacing),
125
- divider: component.divider,
126
- };
127
- }
128
- case ComponentType.TextDisplay: {
129
- return {
130
- type: JsonComponentType.TextDisplay,
131
- content: component.content,
132
- };
133
- }
134
- default:
135
- return null;
136
- }
137
- })
138
- .filter(c => c != null);
139
- }
140
- function mapButtonStyle(style) {
141
- switch (style) {
142
- case ButtonStyle.Primary:
143
- return JsonButtonStyle.Primary;
144
- case ButtonStyle.Secondary:
145
- return JsonButtonStyle.Secondary;
146
- case ButtonStyle.Success:
147
- return JsonButtonStyle.Success;
148
- case ButtonStyle.Danger:
149
- return JsonButtonStyle.Danger;
150
- case ButtonStyle.Link:
151
- return JsonButtonStyle.Link;
152
- case ButtonStyle.Premium:
153
- return JsonButtonStyle.Premium;
154
- default:
155
- throw new CustomError(`Unknow ButtonStyle: ${style}`);
156
- }
157
- }
158
- function mapSeparatorSpacing(spacing) {
159
- switch (spacing) {
160
- case SeparatorSpacingSize.Small:
161
- return JsonSeparatorSpacingSize.Small;
162
- case SeparatorSpacingSize.Large:
163
- return JsonSeparatorSpacingSize.Large;
164
- default:
165
- throw new CustomError(`Unknow SeparatorSpacingSize: ${spacing}`);
166
- }
167
- }
168
- function isJsonComponentInContainer(component) {
169
- return (component.type == JsonComponentType.ActionRow ||
170
- component.type == JsonComponentType.File ||
171
- component.type == JsonComponentType.MediaGallery ||
172
- component.type == JsonComponentType.Section ||
173
- component.type == JsonComponentType.Separator ||
174
- component.type == JsonComponentType.TextDisplay);
175
- }
@@ -1,3 +0,0 @@
1
- export declare class CustomError extends Error {
2
- constructor(message: string);
3
- }
@@ -1,7 +0,0 @@
1
- export class CustomError extends Error {
2
- constructor(message) {
3
- super(`[discord-message-transcript] ${message}`);
4
- this.name = 'DiscordMessageTranscriptError';
5
- Object.setPrototypeOf(this, CustomError.prototype);
6
- }
7
- }
@@ -1,2 +0,0 @@
1
- import { JsonMessageMentions } from "../types/types";
2
- export declare function markdownToHTML(text: string, mentions: JsonMessageMentions, dateFormat: Intl.DateTimeFormat): string;
@@ -1,175 +0,0 @@
1
- export function markdownToHTML(text, mentions, dateFormat) {
2
- const codeBlock = [];
3
- const codeLine = [];
4
- // Code Block (```)
5
- text = text.replace(/```(?:(\S+)\n)?([\s\S]+?)```/g, (_m, lang, code) => {
6
- const rawLang = lang?.toLowerCase();
7
- const normalizedLang = rawLang ? (LANGUAGE_ALIAS[rawLang] ?? rawLang) : null;
8
- const language = normalizedLang && SUPPORTED_LANGUAGES.has(rawLang) ? normalizedLang : 'plaintext';
9
- codeBlock.push(`<pre><code class="language-${language}">${code.trimEnd()}</code></pre>`);
10
- return `%$%CODE!BLOCK!${codeBlock.length - 1}%$%`;
11
- });
12
- // Code line (`)
13
- text = text.replace(/`([^`]+)`/g, (_m, code) => {
14
- codeLine.push(`<code>${code}</code>`);
15
- return `%$%CODE!LINE!${codeLine.length - 1}%$%`;
16
- });
17
- // Citation (> | >>>)
18
- text = text.replace(/(^> ?.*(?:(?:\n^> ?.*)+)?)/gm, (match) => {
19
- const cleanContent = match.split('\n').map(line => {
20
- return line.replace(/^>+ ?/, '');
21
- }).join('\n');
22
- return `<blockquote class="quote-multi">${cleanContent}</blockquote>`;
23
- });
24
- // Headers (#)
25
- text = text.replace(/^### (.*)(?=\n|$)/gm, `<h3>$1</h3>`);
26
- text = text.replace(/^## (.*)(?=\n|$)/gm, `<h2>$1</h2>`);
27
- text = text.replace(/^# (.*)(?=\n|$)/gm, `<h1>$1</h1>`);
28
- // Subtext(-#)
29
- text = text.replace(/^-# (.*)(?=\n|$)/gm, `<p class="subtext">$1</p>`);
30
- // List (- | *)
31
- text = text.replace(/^(\s*)[-*] (.*)(?=\n|$)/gm, (_m, indentation, text) => {
32
- const isSubItem = indentation.length > 0;
33
- const bullet = isSubItem ? '◦' : '•';
34
- return `<p class="pList">${indentation}${bullet} ${text}</p>`;
35
- });
36
- // Spoiler (||)
37
- text = text.replace(/\|\|(.*?)\|\|/gs, `<span class="spoilerMsg">$1</span>`);
38
- // Bold & Italic (***)
39
- text = text.replace(/\*\*\*(.*?)\*\*\*/gs, `<strong><em>$1</em></strong>`);
40
- // Bold (**)
41
- text = text.replace(/\*\*(.*?)\*\*/gs, `<strong>$1</strong>`);
42
- // Underline(__)
43
- text = text.replace(/__(.*?)__/gs, `<u>$1</u>`);
44
- // Italic (*)
45
- text = text.replace(/\*(.*?)\*/gs, `<em>$1</em>`);
46
- text = text.replace(/\_(.*?)\_/gs, `<em>$1</em>`);
47
- // Strikethrough (~~)
48
- text = text.replace(/~~(.*?)~~/gs, `<s>$1</s>`);
49
- // Links ([]() && https)
50
- text = text.replace(/\[([^\]]+)\]\((https?:\/\/[^\s]+)\)/g, (_m, text, link) => `<a href="${link}" target="_blank">${text}</a>`);
51
- text = text.replace(/(?<!href=")(https?:\/\/[^\s]+)/g, (_m, link) => `<a href="${link}" target="_blank">${link}</a>`);
52
- // Mentions (@)
53
- if (mentions.users.length != 0) {
54
- const users = new Map(mentions.users.map(user => [user.id, user]));
55
- text = text.replace(/<@!?(\d+)>/g, (_m, id) => {
56
- let user = users.get(id);
57
- return user ? `<span class="mention" style="color: ${user.color ?? "#dbdee1"}">@${user.name}</span> ` : `<span class="mention"><@${id}></span> `;
58
- });
59
- }
60
- if (mentions.roles.length != 0) {
61
- const roles = new Map(mentions.roles.map(role => [role.id, role]));
62
- text = text.replace(/<@&(\d+)>/g, (_m, id) => {
63
- const role = roles.get(id);
64
- return role ? `<span class="mention" style="color: ${role.color}">@${role.name}</span> ` : `<span class="mention"><@&${id}></span> `;
65
- });
66
- }
67
- if (mentions.channels.length != 0) {
68
- const channels = new Map(mentions.channels.map(channel => [channel.id, channel]));
69
- text = text.replace(/<#(\d+)>/g, (_m, id) => {
70
- const channel = channels.get(id);
71
- return channel && channel.name ? `<span class="mention">#${channel.name}</span> ` : `<span class="mention"><#${id}></span> `;
72
- });
73
- }
74
- if (mentions.everyone) {
75
- text = text.replace("@everyone", `<span class="mention">@everyone</span> `);
76
- text = text.replace("@here", `<span class="mention">@here</span> `);
77
- }
78
- // Timestamp
79
- const { locale, timeZone } = dateFormat.resolvedOptions();
80
- text = text.replace(/<t:(\d+)(?::([tTdDfFR]))?>/g, (_m, timestamp, format) => {
81
- const date = new Date(parseInt(timestamp, 10) * 1000);
82
- const style = format || 'f';
83
- const isoString = date.toISOString();
84
- const titleFormatter = new Intl.DateTimeFormat(locale, {
85
- dateStyle: 'full',
86
- timeStyle: 'full',
87
- timeZone: timeZone,
88
- });
89
- const fullDateForTitle = titleFormatter.format(date);
90
- if (style === 'R') {
91
- const rtf = new Intl.RelativeTimeFormat(locale, { numeric: 'auto' });
92
- const seconds = Math.floor((date.getTime() - Date.now()) / 1000);
93
- const minutes = Math.floor(seconds / 60);
94
- const hours = Math.floor(minutes / 60);
95
- const days = Math.floor(hours / 24);
96
- let relativeString;
97
- if (Math.abs(days) > 30)
98
- relativeString = rtf.format(Math.floor(days / 30.44), 'month');
99
- else if (Math.abs(days) > 0)
100
- relativeString = rtf.format(days, 'day');
101
- else if (Math.abs(hours) > 0)
102
- relativeString = rtf.format(hours, 'hour');
103
- else if (Math.abs(minutes) > 0)
104
- relativeString = rtf.format(minutes, 'minute');
105
- else
106
- relativeString = rtf.format(seconds, 'second');
107
- return `<time datetime="${isoString}" title="${fullDateForTitle}">${relativeString}</time>`;
108
- }
109
- else if (isStyleKey(style)) {
110
- const formatter = new Intl.DateTimeFormat(locale, {
111
- ...styleOptions[style],
112
- timeZone: timeZone,
113
- });
114
- const formattedDate = formatter.format(date);
115
- return `<time datetime="${isoString}" title="${fullDateForTitle}">${formattedDate}</time>`;
116
- }
117
- return _m;
118
- });
119
- // Break Line
120
- text = text.replace(/\n/g, '<br>');
121
- // Clear Unecessary Break Line
122
- text = text.replace(/(<\/(?:p|h[1-3]|blockquote)>)\s*<br>/g, '$1');
123
- // Remove Placeholders
124
- text = text.replace(/%\$%CODE!BLOCK!(\d+)%\$%/g, (_m, number) => {
125
- return codeBlock[number];
126
- });
127
- text = text.replace(/%\$%CODE!LINE!(\d+)%\$%/g, (_m, number) => {
128
- return codeLine[number];
129
- });
130
- return text;
131
- }
132
- // Check if styleKey is valid
133
- const styleOptions = {
134
- 't': { timeStyle: 'short' },
135
- 'T': { timeStyle: 'medium' },
136
- 'd': { dateStyle: 'short' },
137
- 'D': { dateStyle: 'long' },
138
- 'f': { dateStyle: 'long', timeStyle: 'short' },
139
- 'F': { dateStyle: 'full', timeStyle: 'short' },
140
- };
141
- function isStyleKey(key) {
142
- return key in styleOptions;
143
- }
144
- // At least I hope
145
- const SUPPORTED_LANGUAGES = new Set([
146
- 'bash', 'sh', 'shell',
147
- 'c',
148
- 'cpp',
149
- 'css',
150
- 'javascript', 'js',
151
- 'typescript', 'ts',
152
- 'json',
153
- 'xml',
154
- 'yaml', 'yml',
155
- 'java',
156
- 'kotlin',
157
- 'php',
158
- 'python', 'py',
159
- 'ruby', 'rb',
160
- 'sql',
161
- 'lua',
162
- 'markdown', 'md',
163
- 'plaintext', 'txt'
164
- ]);
165
- const LANGUAGE_ALIAS = {
166
- sh: 'bash',
167
- shell: 'bash',
168
- js: 'javascript',
169
- ts: 'typescript',
170
- py: 'python',
171
- rb: 'ruby',
172
- md: 'markdown',
173
- yml: 'yaml',
174
- txt: 'plaintext'
175
- };
File without changes
@@ -1,73 +0,0 @@
1
- "use strict";
2
- document.addEventListener('DOMContentLoaded', () => {
3
- const transcriptDataElement = document.getElementById('transcript-data');
4
- if (!transcriptDataElement) {
5
- console.error('Missing transcript data element.');
6
- return;
7
- }
8
- const data = JSON.parse(transcriptDataElement.textContent);
9
- const authorMap = new Map(data.authors.map(author => [author.id, author]));
10
- document.querySelectorAll('.messageDiv[data-author-id]').forEach(messageDiv => {
11
- const authorId = messageDiv.dataset.authorId;
12
- const author = authorMap.get(authorId);
13
- if (!author) {
14
- console.warn(`Author not found for message with ID: ${messageDiv.id} and author ID: ${authorId}`);
15
- return;
16
- }
17
- const avatarImg = messageDiv.querySelector('.messageImg');
18
- if (avatarImg)
19
- avatarImg.src = author.avatarURL;
20
- const usernameH3 = messageDiv.querySelector('.messageUsername');
21
- if (usernameH3) {
22
- usernameH3.textContent = author.member?.displayName ?? author.displayName;
23
- usernameH3.style.color = author.member?.displayHexColor ?? '#dbdee1';
24
- }
25
- const badgesDiv = messageDiv.querySelector('.badges');
26
- if (badgesDiv) {
27
- badgesDiv.innerHTML = ''; // Clear existing placeholders
28
- if (author.bot) {
29
- const badge = document.createElement('p');
30
- badge.className = 'badge';
31
- badge.textContent = 'APP';
32
- badgesDiv.appendChild(badge);
33
- }
34
- if (author.system) {
35
- const badge = document.createElement('p');
36
- badge.className = 'badge';
37
- badge.textContent = 'SYSTEM';
38
- badgesDiv.appendChild(badge);
39
- }
40
- if (author.guildTag) {
41
- const badge = document.createElement('p');
42
- badge.className = 'badgeTag';
43
- badge.textContent = author.guildTag;
44
- badgesDiv.appendChild(badge);
45
- }
46
- }
47
- });
48
- // Handle existing client-side event listeners
49
- document.addEventListener('click', function (event) {
50
- const spoiler = event.target.closest('.spoilerMsg, .spoilerAttachment');
51
- if (spoiler && !spoiler.classList.contains('revealed')) {
52
- event.preventDefault();
53
- event.stopPropagation();
54
- spoiler.classList.add('revealed');
55
- }
56
- const selectorInput = event.target.closest('.selectorInput');
57
- document.querySelectorAll('.selector').forEach(selector => {
58
- if (!selector.contains(event.target)) {
59
- selector.classList.remove('active');
60
- }
61
- });
62
- if (selectorInput) {
63
- const selector = selectorInput.closest('.selector');
64
- if (selector) {
65
- selector.classList.toggle('active');
66
- }
67
- }
68
- });
69
- // Initial highlighting
70
- if (window.hljs) {
71
- hljs.highlightAll();
72
- }
73
- });
@@ -1,11 +0,0 @@
1
- export declare const DEFAULT_CSS = "\nbody {\n background-color: #313338;\n color: #dbdee1;\n font-family: \"Whitney\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n margin: 0;\n padding: 0;\n width: 100%;\n}\nheader {\n height: fit-content;\n border-bottom: 2px solid black;\n margin-top: 2rem;\n padding-left: 2rem;\n padding-bottom: 1rem;\n display: flex;\n flex-direction: column;\n display: flex;\n flex-direction: row;\n}\na {\n text-decoration: none;\n color: #1E90FF;\n}\np {\n margin: 0;\n}\nh4 {\n margin: 0;\n}\ncode {\n border: 1px solid #202225;\n border-radius: 0.25rem;\n}\nblockquote {\n margin: 0.5rem 0;\n border-left: 0.25rem solid #4f545c;\n padding: 0.4rem 0.6rem;\n border-radius: 0.25rem;\n color: #9f9fa6;\n}\n.line {\n display: flex;\n align-items: baseline;\n gap: 0.5rem\n}\n.badge {\n background-color: #5865f2;\n color: white;\n font-weight: 600;\n font-size: 80%;\n padding: 0.1rem 0.35rem;\n border-radius: 0.25rem;\n letter-spacing: 0.03rem;\n height: fit-content;\n width: fit-content;\n align-self: flex-start;\n}\n.badgeTag {\n background-color: #747F8D50;\n color: white;\n font-weight: 600;\n font-size: 70%;\n padding: 0.1rem 0.35rem;\n border-radius: 0.25rem;\n letter-spacing: 0.03rem;\n height: fit-content;\n width: fit-content;\n align-self: center;\n}\n.mention {\n background-color: #5664fa41;\n padding: 0.2rem;\n border-radius: 0.25rem;\n transition: background-color 0.2s ease;\n}\n.mention:hover {\n background-color: #5664fa7e;\n}\n";
2
- export declare const MESSAGE_CSS = "\n.messageDiv {\n display: flex;\n flex-direction: column;\n gap: 0.2rem;\n padding: 0.5rem;\n border-radius: 1rem;\n}\n.messageDiv.highlight, .messageDiv:hover {\n background-color: #40434b;\n transition: background-color 0.3s ease-in-out;\n}\n.messageBotton {\n display: flex;\n flex-direction: row;\n gap: 1rem;\n padding: 0.5rem;\n border-radius: 0.25rem;\n}\n.messageImg {\n width: 3.5rem; \n height: 3.5rem; \n border-radius: 50%;\n}\n.messageDivRight {\n display: flex;\n flex-direction: column;\n gap: 0.25rem\n}\n.messageUser {\n display: flex;\n flex-direction: row;\n gap: 0.75rem;\n}\n.messageUsername {\n margin: 0;\n}\n.messageTimeStamp {\n color: #999999;\n font-size: 77.5%;\n align-self: center;\n}\n.messageContent {\n line-height: 1.5;\n}\n.pList {\n white-space: pre-wrap;\n}\n.subtext {\n font-size: 85%;\n color: #808080;\n}\n.spoilerMsg {\n display: inline-block;\n background-color: #202225;\n color: #202225;\n padding: 0 0.2rem;\n border-radius: 0.2rem;\n cursor: pointer;\n transition: background-color 0.1s ease-in-out, color 0.1s ease-in-out;\n}\n.spoilerMsg.revealed {\n background-color: transparent;\n color: inherit;\n}\n.messageReply {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 0.8rem;\n color: #b5bac1;\n cursor: pointer;\n margin-left: 2rem;\n}\n.messageReplySvg {\n flex-shrink: 0;\n width: 2.25rem;\n height: 2.25rem;\n color: #b5bac1;\n}\n.messageReplyImg {\n width: 1.75rem;\n height: 1.75rem;\n border-radius: 50%;\n flex-shrink: 0;\n}\n.messageReplyAuthor {\n font-weight: 600;\n color: #dbdee1;\n margin-right: 0.3rem;\n}\n.badgeReply {\n background-color: #5865f2;\n color: white;\n font-weight: 600;\n font-size: 70%;\n padding: 0.1rem 0.3rem;\n border-radius: 0.25rem;\n letter-spacing: 0.03rem;\n height: fit-content;\n align-self: center;\n flex-shrink: 0;\n}\n.messageReplyText {\n flex-grow: 1;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n color: #b5bac1;\n font-size: 0.75rem;\n}\n";
3
- export declare const EMBED_CSS = "\n.embed {\n background-color: #2b2d31;\n border: 0.15rem solid #2b2d31;\n border-left: 0.25rem solid;\n border-radius: 0.25rem;\n padding: 0.5rem 0.75rem;\n margin-top: 0.5rem;\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n max-width: 520px;\n}\n.embed a {\n color: #00aff4;\n text-decoration: none;\n}\n.embed a:hover {\n text-decoration: underline;\n}\n.embedHeader {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 0.5rem;\n}\n.embedHeaderRight {\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n}\n.embedHeaderRightAuthor {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 0.875rem;\n font-weight: 500;\n color: #ffffff;\n}\n.embedHeaderRightAuthorImg {\n width: 1.5rem;\n height: 1.5rem;\n border-radius: 50%;\n}\n.embedHeaderRightAuthorName {\n color: #ffffff;\n font-weight: 500;\n}\n.embedHeaderRightTitle {\n font-size: 1rem;\n font-weight: bold;\n color: #ffffff;\n}\n.embedHeaderThumbnail {\n max-width: 80px;\n max-height: 80px;\n object-fit: contain;\n border-radius: 0.25rem;\n flex-shrink: 0;\n}\n.embedDescription {\n font-size: 0.875rem;\n color: #dcddde;\n}\n.embedFields {\n display: flex;\n flex-wrap: wrap;\n gap: 0.5rem;\n}\n.embedFieldsField {\n flex: 1;\n min-width: 150px;\n}\n.embedFieldsFieldTitle {\n font-size: 0.75rem;\n font-weight: bold;\n color: #ffffff;\n margin-bottom: 0.25rem;\n}\n.embedFieldsFieldValue {\n font-size: 0.875rem;\n color: #dcddde;\n}\n.embedImage {\n margin-top: 0.5rem;\n max-width: 100%;\n height: auto;\n}\n.embedImage img {\n max-width: 100%;\n max-height: 300px;\n object-fit: contain;\n border-radius: 0.25rem;\n}\n.embedFooter {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 0.75rem;\n color: #999999;\n margin-top: 0.5rem;\n}\n.embedFooterImg {\n width: 1.25rem;\n height: 1.25rem;\n border-radius: 50%;\n}\n.embedFooterText {\n color: #999999;\n}\n";
4
- export declare const ATTACHMENT_CSS = "\n.attachmentImage, .attachmentVideo {\n max-width: 400px;\n height: auto;\n border-radius: 0.25rem;\n margin-top: 0.5rem;\n}\n.attachmentAudio {\n width: 300px;\n margin-top: 0.5rem;\n}\n.attachmentFile {\n background-color: #2b2d31;\n border: 1px solid #202225;\n border-radius: 0.75rem;\n padding: 0.75rem;\n display: flex;\n align-items: center;\n gap: 0.75rem;\n max-width: 400px;\n margin-top: 0.5rem;\n width: fit-content;\n}\n.attachmentFileIcon {\n width: 2.5rem;\n height: 2.5rem;\n fill: #b9bbbe;\n flex-shrink: 0;\n}\n.attachmentFileInfo {\n display: flex;\n flex-direction: column;\n gap: 0.1rem;\n overflow: hidden;\n flex-grow: 1;\n}\n.attachmentFileName {\n color: #ffffff;\n text-decoration: none;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.attachmentFileSize {\n font-size: 0.75rem;\n color: #72767d;\n}\n.attachmentDownload {\n display: block;\n flex-shrink: 0;\n}\n.attachmentDownloadIcon {\n width: 1.5rem;\n height: 1.5rem;\n fill: #b9bbbe;\n transition: fill 0.2s ease;\n}\n.attachmentDownload:hover .attachmentDownloadIcon {\n fill: #ffffff;\n}\n.spoilerAttachment {\n position: relative;\n display: inline-block;\n border-radius: 0.5rem;\n overflow: hidden;\n cursor: pointer;\n}\n.spoilerAttachment .spoilerAttachmentContent {\n filter: blur(64px);\n pointer-events: none;\n transition: filter 0.2s ease;\n}\n.spoilerAttachment .spoilerAttachmentOverlay {\n position: absolute;\n inset: 0;\n background: rgba(32, 34, 37, 0.85);\n color: #fff;\n font-weight: 600;\n letter-spacing: 0.05em;\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 2;\n user-select: none;\n}\n.spoilerAttachment.revealed .spoilerAttachmentContent {\n filter: none;\n pointer-events: auto;\n}\n.spoilerAttachment.revealed .spoilerAttachmentOverlay {\n display: none;\n}\n";
5
- export declare const ACTIONROW_CSS = "\n.actionRow {\n display: flex;\n gap: 0.5rem;\n margin-top: 0.5rem;\n}\n";
6
- export declare const BUTTON_CSS = "\n.button {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0rem 0.8rem;\n height: 2.5rem;\n border-radius: 0.6rem;\n color: white;\n font-weight: 600;\n cursor: pointer;\n transition: filter 0.2s ease;\n}\n.button:hover {\n filter: brightness(1.1);\n}\n.buttonEmoji {\n font-size: 1.25rem;\n}\n.buttonLabel {\n font-size: 0.875rem;\n}\n.buttonLink {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n color: white;\n font-weight: 600;\n}\n.buttonLinkIcon {\n width: 1.25rem;\n height: 1.25rem;\n}\n";
7
- export declare const COMPONENTS_CSS = "\n.selector {\n width: 100%;\n position: relative;\n}\n.selectorInput {\n background-color: #2b2d31;\n border: 1px solid #202225;\n border-radius: 0.75rem;\n padding: 0.75rem;\n min-width: 17.5rem;\n cursor: pointer;\n user-select: none;\n}\n.selectorInputText {\n color: #808080;\n}\n.selectorOptionMenu {\n display: none; \n position: absolute;\n top: 100%;\n left: 0;\n width: 100%;\n background-color: #2b2d31;\n border: 1px solid #202225;\n border-radius: 1rem;\n margin-top: 0.25rem;\n padding: 0.5rem;\n z-index: 10;\n box-sizing: border-box;\n}\n.selector.active .selectorOptionMenu {\n display: block;\n}\n.selectorOption {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.75rem;\n border-radius: 0.75rem;\n cursor: pointer;\n transition: background-color 0.2s ease;\n}\n.selectorOption:hover {\n background-color: #4f545c;\n}\n.selectorOptionEmoji {\n font-size: 1.25rem;\n}\n.selectorOptionRight {\n display: flex;\n flex-direction: column;\n}\n.selectorOptionTitle {\n font-weight: 500;\n}\n.selectorOptionDesc {\n font-size: 0.75rem;\n color: #808080;\n}\n";
8
- export declare const COMPONENTSV2_CSS = "\n.mediaGallery {\n display: flex;\n flex-wrap: wrap;\n gap: 0.35rem;\n width: 20rem;\n height: 20rem;\n border: 1px solid #202225\n padding: 0.35rem;\n overflow: hidden;\n}\n.mediaGalleryItem {\n flex-grow: 1;\n flex-basis: 6rem;\n min-width: 0;\n display: flex;\n}\n.mediaGalleryImg {\n width: 100%;\n height: 100%;\n object-fit: cover;\n display: block;\n}\n";
9
- export declare const POLL_CSS = "\n.pollDiv {\n background-color: #2b2d31;\n border-radius: 0.5rem;\n padding: 1rem;\n margin-top: 0.5rem;\n max-width: 420px;\n}\n.pollQuestion {\n font-size: 1.1rem;\n font-weight: bold;\n margin-bottom: 1rem;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n.pollAnswers {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n.pollAnswer {\n background-color: #3a3c42;\n border-radius: 0.3rem;\n padding: 0.75rem;\n cursor: pointer;\n border: 1px solid transparent;\n transition: border-color 0.2s ease;\n position: relative;\n overflow: hidden;\n}\n.pollAnswer:hover {\n border-color: #4d515a;\n}\n.pollAnswerBar {\n position: absolute;\n top: 0;\n left: 0;\n height: 100%;\n background-color: #5664fa7a;\n border-radius: 0.2rem;\n z-index: 1;\n}\n.pollAnswerContent {\n position: relative;\n z-index: 2;\n display: flex;\n align-items: center;\n justify-content: space-between;\n}\n.pollAnswerDetails {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n.pollAnswerEmoji {\n font-size: 1.25rem;\n}\n.pollAnswerText {\n font-weight: 500;\n}\n.pollAnswerVotes {\n font-size: 0.8rem;\n color: #b5bac1;\n font-weight: bold;\n}\n.pollFooter {\n margin-top: 1rem;\n font-size: 0.75rem;\n color: #949ba4;\n}\n";
10
- export declare const POLL_RESULT_EMBED_CSS = "\n.pollResultEmbed {\n background-color: #2b2d31;\n border-radius: 0.5rem;\n padding: 1rem;\n margin-top: 0.5rem;\n border: 1px solid #3a3c42;\n min-width: 25rem;\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n}\n.pollResultEmbedWinner {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 1rem;\n font-weight: 600;\n margin-bottom: 0.4rem;\n}\n.pollResultEmbedCheckmark {\n color: #57f287;\n font-size: 1.1em;\n}\n.pollResultEmbedSubtitle {\n font-size: 0.9rem;\n color: #b5bac1;\n}\n.pollResultEmbedButtonDiv {\n margin-right: 0.5rem;\n margin-left: 1rem;\n align-self: center;\n}\n.pollResultEmbedButton {\n background-color: black;\n color: white;\n padding: 0.5rem 1rem;\n border-radius: 0.3rem;\n text-decoration: none;\n font-weight: 500;\n transition: background-color 0.2s ease;\n cursor: pointer;\n}\n.pollResultEmbedButton:hover {\n filter: brightness(1.1);\n}\n";
11
- export declare const REACTIONS_CSS = "\n.reactionsDiv {\n display: flex;\n flex-wrap: wrap;\n gap: 0.5rem;\n margin-top: 0.5rem;\n}\n.reaction {\n align-items: center;\n background-color: #2b2d31;\n border: 1px solid #3a3c42;\n border-radius: 1rem;\n padding: 0.25rem 0.6rem;\n font-size: 1rem;\n color: #dcddde;\n font-weight: bold;\n cursor: pointer;\n}\n.reaction:hover {\n filter: brightness(1.1);\n}\n";